Blokada kliknięcia przycisku

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ą ?

0

Może po prostu:

if not forma.visible then forma.Show;

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

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?

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

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

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
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 .

0
Lulhax napisał(a)
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.

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.

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:

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

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

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 ...

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.

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ż.

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:

if not (button.Focused) then
    ButtonClick();
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.

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)

1 użytkowników online, w tym zalogowanych: 0, gości: 1