Blokada kliknięcia przycisku

Blokada kliknięcia przycisku
TO
  • Rejestracja:prawie 20 lat
  • Ostatnio:ponad 4 lata
0

Tytuł dość kontrowersyjny, ale jakoś tak wyszło.

Chodzi o taką sytuacją:

Jest pole typu Edit i jest przycisk. User wpisuje jakąś wartość w pole edit. Przy zdazeniu onEditValueChanged (czyli po zmianie wartości względem poprzedniej w polu Edit - tak na prawde po wyjściu z pola) wykonywane jest sprawdzenie - czy wartość aktualnie znajdujaca się w polu edit odpowiada dokladnie jednemu rekordowi w tabeli - jezeli tak - wykonywane są pewne operacje, które nas tutaj nie interesują.

Jeżeli wprowadzono taką wartość, która nie odpowiada wprost ani jednej pozycji lub wielu pozycjom - zdarzenie onEditValueChaged wywoluje zdarzenie onClick na Buttonie, ktore wywoluje okienko z lista wyboru - przefiltrowana względem wartości z pola Edit.

Wszystko jest fajnie, do czasu gdy próbujemy wykonac operację taką:

wprowadzam jakąś "ogólna" wartość odpowiadającą wielu rekordom i klikam przycisk. W tej sytuacji onEditValueChanged odpala raz onClick, a potem wykonuje się onClick z przysku - czyli okienko z lista wyboru pojawia się dwa razy.

Znów - gdy po wykonaniu onClick w onEditValueChanged dodam semafor (np. ExitFromEdit : Boolean = TRUE), że onClick na samym początku sprawdza czy semafor jest opuszczony: ExitFromEdit = FALSE - wtedy wykonuje operację i dodatkowo na końcu onClicka niezależnie od wyniku sprawdzenia na początku dam ExitFromEdit:=FALSE; to efekt jrst taki, że jak wprowadze wartość w Edit i wykona się onEditValueChanged (po którym jest ExitFromEdit:=TRUE) to owszem okno pojawi się raz, ale pierwsze kliknięcie na Button - powoduje brak reakcji (bo jest sprawdzenie stanu semafora i na koncu ustawienie na sztywno ExitFromEdit:=FALSE) i dopiero drugie kliknięcie pozwala wykonać operacje typowe dla onClick Buttona.

Ufff ... ja wiem, że opis mi się zagmatwał, ale może ktoś coś zrozumie z tego miszungu. Generalnie jest "prawie dobrze" - gdyby udalo sie jeszcze zlikwidować ten nieszczęsny brak reakcji po pierwszym kliknięciu.

Miał ktoś kiedyś podobną zagwozdke logiczną ?

edytowany 3x, ostatnio: toyman
0

Może po prostu:

Kopiuj
if not forma.visible then forma.Show;

Bo to rozwiązanie chyba nie może zfailować?

cimak
  • Rejestracja:ponad 22 lata
  • Ostatnio:ponad 9 lat
  • Postów:1668
0
toyman napisał(a)

W tej sytuacji onEditValueChanged odpala raz onClick, a potem wykonuje się onClick z przysku - czyli okienko z lista wyboru pojawia się dwa razy.

tego nie lapie...?
masz edit i przycisk. w onEditValueChanged masz button.Click;
a w onClick buttona form.show;

i forma pojawia sie dwa razy?

edytowany 1x, ostatnio: cimak
TO
  • Rejestracja:prawie 20 lat
  • Ostatnio:ponad 4 lata
0

Przepraszam. Zagmatwałem. Jest tak:

Edit -> onEditValueChange

Button -> onClick

kiedy user wpisuje jakąś wartość i opuszcza pole (np. Tabulatorem) odpalane jest zdarzenie onEditValueChange. Sprawdzam wtedy czy wprowadzona wartość odpowiada jakiejś jednej konkretne wartości z konkretnej tabeli (odpalam zapytanie SQL). Jeżeli tak - w drugim polu Edit pojawia się opis do tej wprowadzonej wartości - np. po wprowadzeniu konkretnego nr PESEL - w drugim Editcie pojawia się Imię i nazwisko.

Wizualnie jest tak: | EDIT1 - wartość | Button (...) | EDIT2 - opisowy |

Teraz - jeżeli wprowadzimy część wartości i i ta wartość nie odpowiada wprost jednemu rekordowi (jest wiele odpowiedników lub brak odpowiedników) - wywoływane jest zdarzenie Button->onClick, które pokazuje okienko z listą dostępnych wartości - z tym, że lista jest już przefiltrowana już wstępnie. np. jeżeli wprowadzimy pierwsze trzy cyfry nr PESEL - pojawia się okienko z listą osób, których PESELe zaczynają się tak jak wprowadzona wartość. User wybiera interesującą wartość z listy i ta przepisuje się do Edita (potem jest jeszcze raz wykonywane sprawdzenie czy wprowadzona wartość odpowiada dokładnie jednej wartośc - wiem glupota, ale na razie nie chce rozbijać aplikacji, która robi swoją robotę)

Kłopot pojawia się w momencie, kiedy User wprowadzi część wartości (np. pierwsze trzy cyfry nr PESEL) i od razu kliknie przycisk (Button) - wtedy odpala się w pierwszej kolejności zdarzenie Edit -> onEditValueChanged, a później Button -> onClick.

teraz jeżeli utworzę sobie jakąś zmienną globalną np. ExitFromEdit i w zdarzeniu onEditValueChange po wywolaniu zdarzeni onClick ustawię ją na TRUE, a w zdarzeniu onClick sprawdzę czy ExitFromEdit = TRUE - nie wykonuję treści onClick. Jednakże na końcu - poza if-em daję ExitFromEdit:=FALSE.

Taki układ generalnie działa - ale. Jeżeli wyjdę z edita Tabem (nie klikam Buttona) - pozostaje wartość TRUE w ExitFromEdit - pochodzę trochę po aplikacji, poklikam w inne pola, powprowadzam inne dane, a następnie stwierdzam, że jednak chciałbym wywolać okienko spod Buttona -> onClick - za pierwszym kliknięciem nadal mam ExitFromEdit = TRUE. Na końcu przestawiam zawsze na FALSE więc drugie kliknięcie pozwala na wykonanie treści onClick.

No dobra to teraz bardziej konkretnie:

Zdarzenie onEditValueChanged - pesel = Edit

Kopiuj
procedure Tfrm_Glowne.peselPropertiesEditValueChanged(Sender: TObject);
begin
    if pesel.Text<>'' then begin
        Pacjent.SQL.Clear;
        Pacjent.SQL.Add('SELECT  p.nazwisko ,p.imiona ,p.data_ur ,p.pesel ,p.plec ,p.miasto ,p.ulica ');
        Pacjent.SQL.Add('       ,p.nr_domu ,p.nr_lokalu ,p.id_pac ,p.id_dodatkowy ,p.status_nr_pesel ');
        Pacjent.SQL.Add('       ,p.uprawnienie ,p.uprawnienia_po ,p.status_potw_ub ,p.kod_kasa_ch  ');
        Pacjent.SQL.Add('       ,COALESCE(CAST(p.nr_karty_ubezp AS VARCHAR(12)),'''') || COALESCE(CAST(p.nr_dupl_karty_ub AS VARCHAR(12)), '''')   AS nr_karty ');
        Pacjent.SQL.Add('       ,CAST(p.nazwisko || '', '' || p.imiona AS VARCHAR(52)) AS pacjent ');
        Pacjent.SQL.Add('FROM pacjent p ');
        Pacjent.SQL.Add('WHERE (czy_archiwalny=0) ');
        Pacjent.SQL.Add('  AND UPPER(p.pesel)=UPPER('''+pesel.Text+''') ');
        Pacjent.Active:=TRUE;
        LogDebug(Pacjent.SQL.Text);
        if not Pacjent.Eof then begin
                pesel.Text:=Pacjent.FieldByName('pesel').AsString;
                cxTextEdit1.Text:=Pacjent.FieldByName('pacjent').AsString;
        end else begin
            JvXPButton1Click(Self);
            ReturnFromPacjent:=TRUE;
        end;
    end else begin
        ClearPacjent;
    end;
end; 

Button - onClick

Kopiuj
procedure Tfrm_Glowne.JvXPButton1Click(Sender: TObject);
begin
    if not ReturnFromPacjent then begin
        if Tabelka=nil then
            Tabelka:=TTabelka.Create(Self);
        if Tabelka<>nil then begin
            Tabelka.Czysc;
            Tabelka.tytul:='Pacjenci';
            Tabelka.dopasuj:=TRUE;
            Tabelka.Query.SQL.Clear;
            Tabelka.Query.SQL.Add('SELECT  p.nazwisko, p.imiona, p.data_ur, p.pesel, p.plec, p.miasto, p.ulica ');
            Tabelka.Query.SQL.Add('       ,p.nr_domu, p.nr_lokalu, p.id_pac, p.id_dodatkowy ');
            Tabelka.Query.SQL.Add('       ,COALESCE(CAST(p.nr_karty_ubezp AS VARCHAR(12)),'''') || COALESCE(CAST(p.nr_dupl_karty_ub AS VARCHAR(12)), '''')   AS nr_karty ');
            Tabelka.Query.SQL.Add('FROM pacjent p ');
            Tabelka.Query.SQL.Add('WHERE (czy_archiwalny=0) ');
            if pesel.Text<>'' then begin
                Tabelka.Query.SQL.Add('  AND ( ');
                Tabelka.Query.SQL.Add('          (p.nazwisko || p.imiona LIKE '''+pesel.Text+'%'') ');
                Tabelka.Query.SQL.Add('       OR (p.pesel LIKE '''+pesel.Text+'%'') ');
                Tabelka.Query.SQL.Add('      ) ');
            end;
            Tabelka.Query.SQL.Add('ORDER BY UPPER(nazwisko), UPPER(imiona) ');
            Tabelka.Query.Active:=TRUE;
            LogDebug(Tabelka.Query.SQL.Text);
            if Tabelka.Query.Active then begin
                //--------------------------------------------
                Tabelka.IDField.Clear;
                Tabelka.IDField.Add('pesel');
                //--------------------------------------------
                Tabelka.ToggleVisible('id_pac',FALSE);
                Tabelka.ToggleVisible('id_dodatkowy',FALSE);
                //--------------------------------------------
                Tabelka.SetColumnCaption('nazwisko','Nazwisko');
                Tabelka.SetColumnCaption('imiona','Imię');
                Tabelka.SetColumnCaption('data_ur','Urodzony');
                Tabelka.SetColumnCaption('pesel','PESEL');
                Tabelka.SetColumnCaption('plec','Płeć');
                Tabelka.SetColumnCaption('miasto','Miejscowość');
                Tabelka.SetColumnCaption('ulica','Ulica');
                Tabelka.SetColumnCaption('nr_domu','Nr domu');
                Tabelka.SetColumnCaption('nr_lokalu','Nr lokalu');
                Tabelka.SetColumnCaption('id_pac','id_pac');
                Tabelka.SetColumnCaption('id_dodatkowy','id_dodatkowy');
                //--------------------------------------------
            end;
            if Tabelka.ShowModal=mrOK then begin
                if Tabelka.num_wynik>=0 then begin
                    pesel.Text:=Tabelka.wynik[0][0];
                end;
            end;
        end else begin
            Application.MessageBox('Błąd podczas wywoływania okna dialogowego','Błąd wywołania okna',MB_ICONERROR+MB_OK);
        end;
    end;
    ReturnFromPacjent:=FALSE;
end;
 
0
Kopiuj
JvXPButton1Click(Self);

Źle, powinno być JvXPButton1.Click;.

Co do problemu to masz pare wyjść:
1.Ustawiać flagę która wywołuje okienko, a która jest sprawdzana (i wywoływane jest okienko) np. w timerze.
2.Ustawiać flagę która powstrzymuje wyskakiwanie okienka i która jest resetowana np. w timerze.

Prawie to samo, ale polecam drugie rozwiązanie :P .

TO
  • Rejestracja:prawie 20 lat
  • Ostatnio:ponad 4 lata
0
Lulhax napisał(a)
Kopiuj
JvXPButton1Click(Self);

Źle, powinno być JvXPButton1.Click;.

  1. Komponent którego używam TJvXPButton z biblioteki JEDI nie ma metody Click;
  2. Czym różni się symulacja naciśnięcia LPM od wywołania zdarzenia uruchamianego po kliknięciu LPM ? To znaczy pytam dlatego, że od zawsze, wszystkie programy jakie pisałem - pisałem waśnie w ten sposób - oprogramowywałem zdarzenia, a później w miarę potrzeb wywoływałem je traktując jak procedury. To co mi przedstawiłeś po pierwsze wywraca mój sposób pojmowania aplikacji Delphi, a po drugie odnosi się tylko do tych komponentów, które mają medoty symulujące uruchomienie jakiegoś zdarzenia. Pojaśnij dlaczego bładzę (bez uszczypliwości).
Lulhax napisał(a)

Co do problemu to masz pare wyjść:
1.Ustawiać flagę która wywołuje okienko, a która jest sprawdzana (i wywoływane jest okienko) np. w timerze.
2.Ustawiać flagę która powstrzymuje wyskakiwanie okienka i która jest resetowana np. w timerze.

Prawie to samo, ale polecam drugie rozwiązanie :P .

A jak zachowa się timer, kiedy aplikacja jest uruchamiana np. poprzez TeamViewera lub LogMeIna na bardzo słabym łączu - gdzie okna odświeżają się kilka-kilkanaście sekund ? Oczywiście - jest to jakieś rozwiązanie, ale jakoś mnie nie przekonuje.

0

Pojaśnij dlaczego bładzę (bez uszczypliwości).

Widać po coś jest metoda Click skoro ją zrobili. Jest to łatwiejsze do zrozumienia a może wywoływać inne procedury które coś robią i w ten sposób je obchodzisz. A jeśli takowych procedur nie ma to zapis po optymilizacji jest taki sam, ale bardziej czytelny dla programisty. Nie żebyś robił jakiś straszny błąd, po prostu tak się powinno generalnie robić. Coś jak używanie tabulatorów - nie trzeba, ale warto.

A jak zachowa się timer, kiedy aplikacja jest uruchamiana np. poprzez TeamViewera lub LogMeIna na bardzo słabym łączu - gdzie okna odświeżają się kilka-kilkanaście sekund ? Oczywiście - jest to jakieś rozwiązanie, ale jakoś mnie nie przekonuje.
Co ma timer do TeamViewera czy innego Hamachi? Kolego, może najpierw dowiedz się o czym piszesz, bo albo się mylę, albo pierniczysz głupoty.
Wyjaśniam: Timer to zdarzenie które jest wywoływane co dany okres czasu, który wykonuje pewne operacje (niekoniecznie graficzne, tutaj akurat niegraficzne). TeamViewer czy Hamachi wysyła obraz, timer jest wykonywany na lokalnej maszynie, i jeśli obraz nie ulega aktualizacji to działanie timera jest zupełnie niewidoczne dla takich programów. Tego typu programy nie kopiują bloków danych programu etc., tylko odczytują obraz i wysyłają ruchy myszki i naciśnięcia klawiatury. Więc timer nic nie zmienia.

poza tym, timery stosuje się często, i nie wiem skąd ta twoja niepewność co do nich.

TO
  • Rejestracja:prawie 20 lat
  • Ostatnio:ponad 4 lata
0
Lulhax napisał(a)

Pojaśnij dlaczego bładzę (bez uszczypliwości).

Widać po coś jest metoda Click skoro ją zrobili. Jest to łatwiejsze do zrozumienia a może wywoływać inne procedury które coś robią i w ten sposób je obchodzisz. A jeśli takowych procedur nie ma to zapis po optymilizacji jest taki sam, ale bardziej czytelny dla programisty. Nie żebyś robił jakiś straszny błąd, po prostu tak się powinno generalnie robić. Coś jak używanie tabulatorów - nie trzeba, ale warto.

No może i po coś on jest w TButton. W TJvXPButton go nie ma. Idąc twoim tokiem myślenia i argumentacją - widać niepotrzebne.

Lulhax napisał(a)

A jak zachowa się timer, kiedy aplikacja jest uruchamiana np. poprzez TeamViewera lub LogMeIna na bardzo słabym łączu - gdzie okna odświeżają się kilka-kilkanaście sekund ? Oczywiście - jest to jakieś rozwiązanie, ale jakoś mnie nie przekonuje.
Co ma timer do TeamViewera czy innego Hamachi? Kolego, może najpierw dowiedz się o czym piszesz, bo albo się mylę, albo pierniczysz głupoty.
Wyjaśniam: Timer to zdarzenie które jest wywoływane co dany okres czasu, który wykonuje pewne operacje (niekoniecznie graficzne, tutaj akurat niegraficzne). TeamViewer czy Hamachi wysyła obraz, timer jest wykonywany na lokalnej maszynie, i jeśli obraz nie ulega aktualizacji to działanie timera jest zupełnie niewidoczne dla takich programów. Tego typu programy nie kopiują bloków danych programu etc., tylko odczytują obraz i wysyłają ruchy myszki i naciśnięcia klawiatury. Więc timer nic nie zmienia.

poza tym, timery stosuje się często, i nie wiem skąd ta twoja niepewność co do nich.

No. Akurat o zachowaniu i TeamViewera i LogMeIna (nie LogMeIn Hamachi przyjacielu, bo ten tworzy całkiem sprytne tunele VPNowe, któe nijak nie służą do przesyłania senso-stricte obrazu) mogę z tobą podyskutować. Od kilku lat zajmuję się zdalnym serwisowaniem klientów właśnie za pomocą takich narzedzi. I wyobraź sobie, że to co mnie wydawało się niemożliwe (np. kliknięcie czegokolwiek zanim odświeży się do końca okno = Update/Refresh/Repaint) poprzez te programy staje się realne. Nie raz byłem w stanie wykonać operację, która na desktopie, lokalnie była nie do odtworzenia, bo ekran nawet nie mignął - na TV i LogMeIn odświeża się (szczególnie po łączach typu Blueconnect, Play Mobile czy iPlus) tak wolno, że pojawiają sie błędy, o których ani Tobie, ani mnie się nie śniło.

EDIT: Chodziło mi o coś takiego: pojawia się okienko. Na nim przycisk który jest Enabled = TRUE. Za chwile przycisk jest Enabled = FALSE (to samo na desktopie jest niezauważalne). Na łączu typu Blueconnect czy PlayMobile czy iPlus przejście z jednego do drugiego stanu trwa tyle, że jestem w stanie kliknąć ten przycisk zanim on stanie się Enabled = FALSE. Tak samo z polami Edit czy Memo. Odpala się okno, pojawia się Edit/Memo.Readonly = FALSE, po czym przestawia się na ReadOnly = TRUE. Na desktopie jest pstryk. Tutaj jesteś w stanie wkleić tekst w to pole.

Uwierz (a na prawdę widziałem już kilka dziwnych zachowań różnych aplikacji), że mój sceptycyzm nie jest bezzasadny.

edytowany 3x, ostatnio: toyman
cimak
  • Rejestracja:ponad 22 lata
  • Ostatnio:ponad 9 lat
  • Postów:1668
0

@toyman - duuzo piszesz i w efekcie znow sie gubie.
jesli dobrze rozumiem, to problem wyglada w skrocie tak:

wklepujesz cos to edita.
po "opuszczeniu" edita, ten wywoluje onEditValueChanged.
wewnatrz tej procedury pokazujesz okienko.
to okienko zmienia wartosc w edicie.
zmiana wartosci w edicie znow wywoluje onEditValueChanged (a nie powinno bo tego nie chcesz).

czy tak?

jesli tak to moze po prostu na czas zmieniania wartosci w edit, odlacz od niego event:

Kopiuj
   pesel.OnEditValueChanged:=nil;
   pesel.Text:=Tabelka.wynik[0][0];
   pesel.OnEditValueChanged:=peselPropertiesEditValueChanged;

w ten sposob, zmieniajac zawartosc edita, nie zareaguje on na ta zmiane.

edytowany 7x, ostatnio: cimak
0

No może i po coś on jest w TButton. W TJvXPButton go nie ma. Idąc twoim tokiem myślenia i argumentacją - widać niepotrzebne.

Skoro go nie ma to trudno :P .

No. Akurat o zachowaniu i TeamViewera i LogMeIna (nie LogMeIn Hamachi przyjacielu, bo ten tworzy całkiem sprytne tunele VPNowe, któe nijak nie służą do przesyłania senso-stricte obrazu) mogę z tobą podyskutować. Od kilku lat zajmuję się zdalnym serwisowaniem klientów właśnie za pomocą takich narzedzi. I wyobraź sobie, że to co mnie wydawało się niemożliwe (np. kliknięcie czegokolwiek zanim odświeży się do końca okno = Update/Refresh/Repaint) poprzez te programy staje się realne. Nie raz byłem w stanie wykonać operację, która na desktopie, lokalnie była nie do odtworzenia, bo ekran nawet nie mignął - na TV i LogMeIn odświeża się (szczególnie po łączach typu Blueconnect, Play Mobile czy iPlus) tak wolno, że pojawiają sie błędy, o których ani Tobie, ani mnie się nie śniło. [...]

Racja, Hamachi to co innego, mój błąd.
Nadal wydaje mi się niemożliwe żeby aplikacja kombinowała z timerami, a zwłaszcza że sam używałem TeamViewera do połączeń z moimi aplikacjami które stosują timery - nic złego się nie działo. Słyszałem o tym że niektóre aplikacji symulują komponenty na formie, ale to i tak nie ingeruje w timery. Skoro 'coś' ingeruje w Twoje timery i doprowadza do ich błędów to widać to 'coś' jest złe, bo timery są stosowane praktycznie wszędzie. I Twój sceptycyzm wydaje mi się dziwny. Możesz kombinować w użycie wątków zamiast timerów, ale timery to PODSTAWA. Nie przekonasz mnie że aplikacje pokroju TeamViewer ingerują w to, gdyż to: 1. Jest bez sensu. 2.Jest bez sensu. 3.Powoduje same problemy, nic nie rozwiązuje.

Skoro nie timer, to baw się w jakiś często używany event ...

TO
  • Rejestracja:prawie 20 lat
  • Ostatnio:ponad 4 lata
0

Wiem. Przepraszam. Wpadam w słowotok. Pracuje nad sobą ;)

Nie. Przeanalizuj kod, który wkleiłem bez "ściemniania".

Edytuję Edita (pesel). W zależności co zostanie tam wprowadzone masz dwie główne ścieżki (ścieżka, że Edit (pesel) jest pusty nie ma sensu rozwijać):

  1. znaleziono od razu poprawne dopasowanie wartości wpisanej w Edit (pesel) do konkretnego rekordu w BD (wynik z DataSeta Pacjent) - wtedy pole pesel ustawiane jest na to samo (to samo, więc onEditValueChanged nie zareaguje - zbytk łaski, ale zastosowałem jeden schemat działania dla uproszczenia logiki - bo w innych polach ma to o tyle znaczenie, że czasem pokazuje wartość dokłądnie tak jak została zapisana w bazie) - uzupełnia się pole cxTextEdit1 nazwiskiem i imieniem. Sprawa zamknięta - nic więcej się nie dzieje.

  2. nie znaleziono dopasowania - wywolywana jest procedura JvXPButton1Click(Self) - która udaje, że został kliknięty przycisk JvXPButton1.


Teraz. Przycisk JvXPButton1 służy do tego, że user ma możliwość - albo wpisze wartość z łapki (pole Edit - pesel) albo wybierze z listy, która pojawia się po kliknięciu przycisku. Jeżeli wybierze jakąś wartość z listy (ModalResult = OK) - wtedy wartość wybranego pola (definiuję tam Tabelka.IDField.Add('pesel');) przepisywana jest do pola Edit (pesel) i wykonywane jest sprawdzenie pola Edit, czy ma match 1:1 - owszem. Moze się to wydawać, że robi się pętla, ale tak nie jest. Dane z Tabelki można tylko pobrać/wybrać. Nie mozna ich tam edytować. Więc to co tam jest wybrane jest na pewno tym co jest w bazie. Oczywiście - puszczane sa dwa, niemal identyczne zapytania SQLowe - wiem, ale serwer uniesie takie obciążenie bez mrugnięcia - tym bardziej, że po pierwsze taka sytuacja występuje w szczególnych momentach, po drugie mam dodatkowe sprawdzenie, po trzecie upraszcza się trochę kod (bo używam tej samej metody weryfikacji końcowej otrzymując dane z różnych źródeł - po prostu wrzucam dane w pole, a ono ma zaszyte mechanizmy sprawdzania czy wartośc jest poprawna.

No. I teraz problem pojawia się w momencie, kiedy po wprowadzeniu jakiejś wartości Edita (pesel) np. liczby 345 nie nacisnę tabulatora, tylko kliknę przycisk. wartość Edita zmienia się z '' na '345' więc reaguje zdarzenie onEditValueChanged. To sprawdza czy mamy match 1:1 - nie, więc wywoluje procedure JvXPButton1Click, któa wywoluje okienko. User wybiera poprawną wartość z przefiltrowanej listy i zatwierdza OK. pojawia się wartość w Edit. Zmienia się z '345' na np. '34534534534'- jest match 1:1 więc już więcej nic nie zrobi. Ale. Potem pojawia się zdarzenie onClick wywołane bezpośrednio przez usera i wtedy okienko pojawia się drugi raz.

TO
  • Rejestracja:prawie 20 lat
  • Ostatnio:ponad 4 lata
0
Lulhax napisał(a)

Racja, Hamachi to co innego, mój błąd.
Nadal wydaje mi się niemożliwe żeby aplikacja kombinowała z timerami, a zwłaszcza że sam używałem TeamViewera do połączeń z moimi aplikacjami które stosują timery - nic złego się nie działo. Słyszałem o tym że niektóre aplikacji symulują komponenty na formie, ale to i tak nie ingeruje w timery. Skoro 'coś' ingeruje w Twoje timery i doprowadza do ich błędów to widać to 'coś' jest złe, bo timery są stosowane praktycznie wszędzie. I Twój sceptycyzm wydaje mi się dziwny. Możesz kombinować w użycie wątków zamiast timerów, ale timery to PODSTAWA. Nie przekonasz mnie że aplikacje pokroju TeamViewer ingerują w to, gdyż to: 1. Jest bez sensu. 2.Jest bez sensu. 3.Powoduje same problemy, nic nie rozwiązuje.

Skoro nie timer, to baw się w jakiś często używany event ...
Jejku. Nie zrozumiałeś o co mi chodziło. Ja NIE twierdzę, że Timery to zło wcielone. NIe twierdzę, że TV czy LMI ingeruje w działanie aplikacji bo tak nie jest. Nie napisałem też, że chodzi o moje wypociny. Nie wiem gdzie Timery to podstawa (być może masz taką specyfikę swoich aplikacji - ok. Może tak musi być) - ja nie używam Timerów (o dziwo wiem co to jest i z czym to jest i po co to i kiedy zastosować) - bo nie mam takich potrzeb. Przykro mi.

Pisałem o aplikacjach takich firm jak ASSECO, czy COMARCH - tak się dzieje i już. Nie zamierzam wyprówać sobie flaków, bo nie spotkałeś się z takim przypadkiem - ja się spotkałem. Tak się czasem dzieje na wolnych łączach i już.

Co nie zmienia faktu, że mam cokolwiek na przeciwko Timerom - po prostu zapytałem czy masz doświadczenia z Timerami na wolnych łączach i w obciążonych systemach. Nie chce cię w żaden sposób urazić - nie mam bladego pojęcia ile pracujesz "w branży", ale jeżeli pracujesz z "żywym klientem" to na pewno zobaczysz jeszcze niejedno i opowiesz przy dużej wyborowej kolegom po fachu jakie cudo widziałeś.

Co do mojego sceptycyzmu. Możesz uznać, że pierniczę, ale nauczyłem się ufać przeczuciom (wiem. głupie, staroświeckie, "Jest bez sensu". Ale tak mam) i jezeli coś mi trzeszczy piaskiem między zębami - wolę dopytać 100 razy czy na pewno to to o co mnie chodziło, bo po pierwsze - jak widzisz - staram się pojaśnić problem (który wydaje mi się, że jest gdzies na wyciągnięcie ręki) i i ani ja nie potrafię tego przekazać na sucho, ani Wy nie jesteście w stanie tego wprost załapać (nie, nie mam pretensji) a po drugie na aplikacji pracują żywi, często sfrustrowani userzy (panie recepcjonistki/pielęgniarki po 50, któe traktują komputer i tych, którzy informatyzują jak zamach na ich godność osobistą) - więc zanim zrobię rewolucję w aplikacji - chę sięupewnić czy nie pojawią się nowe "kwiatki". Tak mam i już.

edytowany 1x, ostatnio: toyman
cimak
  • Rejestracja:ponad 22 lata
  • Ostatnio:ponad 9 lat
  • Postów:1668
0

ok, tym razem chyba dobrze zrozumialem (chociaz glowy nie daje :D )
chcesz uniknac przypadku gdy edit probuje kliknac przycisk, ktory wlasnie kliknal user.
sprawdz to: w zdarzeniu edita:

Kopiuj
if not (button.Focused) then
    ButtonClick();
TO
  • Rejestracja:prawie 20 lat
  • Ostatnio:ponad 4 lata
0

Dokładnie tak.

I wygląda, że działa - wiedziałem, że rozwiązanie jest gdzies na wyciągnięcie ręki.

Pewnie po jakimś czasie doszedłbym do takiego lub podobnego rozwiązania, ale nie ukrywam, że ostatnie kilka dni dało mi zdrowo w kość - musiałem odtworzyć bazę danych klienta z niczego (dokładnie kilkunastu plików CSV z kilku źródeł - Baaaaaardo luźno ze sobą powiązanych). Udało się, że mózg się zlasował - a tutaj klient zażyczył sobie ciekawej funkcjonalności i utknąłem.

Dzięki - wiedziełam, że moge na Was liczyć.

Temat wydaje sie być zamknięty - Pozdrawiam i dobranoc.

TO
  • Rejestracja:prawie 20 lat
  • Ostatnio:ponad 4 lata
0

Dodam w tej kwestii jedną ciekawostkę. Przy niektórych zdarzeniach i kontrolkach - jeżeli przycisk który programowo chcemy kliknąć i pole z któego wychodzimy są obok siebie w sensie properta: TabOrder - patent cimaka nie zadziała. Wystarczy oczywiście (o ile jest taka możliwość) pokombinować z TabOrderami i wszystko gitesowo na powrót zaczyna działać.

Aha. Problem jest tylko, jak się naciśnie Tab (czyli teoretycznie wychodzimy z pola, ale od strony programowej nie chcemy, bo np wprowadzona wartość nie znajduje się w słowniku, do którego się odwołujemy (w polu tekstowym wpisujemy wartość. Jeżeli jest w słowniku - super. Jeżeli nie - wywołujemy to co jest pod przyciskiem, żeby pozwoliło wybrać najbardziej zbliżone)

edytowany 1x, ostatnio: toyman
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)