Ekran dotykowy win8 i BUTTON w Delphi

0

Ekran dotykowy dziwnie reaguje z aplikacjami napisanymi
w Delphi, zjawisko dotyczy tylko kontrolek BUTTON pod Windows8.

Naciskamy przycisk BUTTON na ekranie i dochodzi do jego wywołania
ale bardzo często wielokrotnego.Kolejka komunikatow otrzymuje
prawdopododnie wielokrotnie ten sam komunikat czemu?
Nie jest to wina monitora sprawdzałem kilka modeli.

Zabezpieczenie takie jak w przykładowym kodzie nie działa!!!!

 
procedure TForm1.Button1Click(Sender: TObject);
begin
     (Sender as TButton).Enabled:=False;

     //... tu kod przycisku

     (Sender as TButton).Enabled:=True;
end;

Oznacza to ze dane o wielu naciśnięciach są już w kolejce
zanim wywołana zostaje funkcja Button.Click przycisku.

Moje pytanie jak wyczyścić kolejkę komunikatów dla danego
przycisku z jego funkcji Button.Click?

0

Po co ci sprawdzanie sendera w NIE-DYNAMICZNYM przycisku? Nic ci to nie da.

0

Win 8 nie mam więc nie sprawdzę. Ale miałem podobny problem z buttonem i zdarzeniem mouse wheel. Kiedy button leżał na formie to pomimo, że rolka przewijana była tylko raz, to zdarzenie mouse wheel wywoływało się 2-3 razy. Doszedłem do tego, że problem sprawiał button "przechwytujący" focusa (focus mrugał przy przewijaniu rolką). Zastosowanie tspeedbuttona pomogło, bo nie posiada on focusa.
Natomiast możesz to też prawdopodobnie rozwiązać stosując timer, i przyjmując tylko jedno kliknięcia np. w czasie 1-2 sekund.

0

Zminusowaliście mnie, tak więc rozumiem, iż plotę głupotę.
Jednakże uświadomcie mnie ._.
Nawet jeśli do tego zdarzenia jest podpasowanych 5 przycisków, to jednak to są TButtony tak czy inaczej.

0

Zapytam inaczej...... jak w chwili wykonywania kodu Button.Click wykasować komunikaty o kolejnym kliknięciu tego przycisku?

0

Tak jak pisałem wyżej:
Tworzysz TTimer z interval np. 1000;
W execute timera wpisujesz: Timer1.Enabled := false;

A w kodzie:

 
procedure TForm1.Button1Click(Sender: TObject);
begin
     if (Timer1.Enabled) then exit;
 
     //... tu kod przycisku
 
     Timer1.Enabled:=True;
end;
0

Brak efektu z pierwszym razem i tak akcja buttona jest wywoływana dwa razy a potem Button juz wcale nie działa.....
Ten problem wymaga czegoś bardziej skutecznego

0

Powinno działać a zdarzeniu OnTimer Timera dałeś?

Timer1.Enabled:= False;

EDIT//

Timer1.Enabled:=True;

Powinno być na początku zaraz po if (Timer1.Enabled) then exit; a nie po wykonaniu reszty kodu.

0

@ergo nic nie rozumiesz wykonaj sobie kod (klikaj szybko na button do pierwszego komunikatu):

procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
begin
  if Timer1.Enabled then exit;
 //Timer1.Enabled:= True; //później zmień na to to zobaczysz
  for i:=1 to 10000000 do
    Application.ProcessMessages;
  ShowMessage('to ja!'); //ile razy sie wykona
  Timer1.Enabled:= True;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Timer1.Interval:= 5000; //dla zobrazowania dlugi czas
  Timer1.Enabled:= False;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Timer1.Enabled:= False;
end;
0

Problemu nie rozwiązuje Timer1 bo zanim go kod przycisku aktywuje na True to i tak w tym czasie system ponownie wywoła( Button.Click) mam wiele kontrolek na formie może..... ten fakt ma jakieś znaczenie podczas realizacji komunikatów okna.
Wniosek jest taki ,ze sterownik ekranu dotykowego czasami robi double-click ale w takim tempie jakiego nie wykona się poprzez myszkę.
Wypociłem dziś ten kod ale poprawa jest niewielka
Więc dalej proszę o pomoc z wykasowaniem oczekujących komunikatów dla buttona.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

const
     OczekiwanieLicznikaBlokady = 1000;

var
  Form1: TForm1;
  LicznikBlokadyPrzycisku:    int64;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
Kursor:   integer;
begin
     try
          //Zapobieganie wielokrotnemu kliknieciu przycisku
          if LicznikBlokadyPrzycisku > (GetTickCount()-OczekiwanieLicznikaBlokady) then
          begin
               LicznikBlokadyPrzycisku:=GetTickCount();
               exit;
          end;
          LicznikBlokadyPrzycisku:=GetTickCount();

          Kursor:=Screen.Cursor;
          Screen.Cursor:=crHourGlass;
          (Sender as TButton).Enabled:=False;

          Application.ProcessMessages;
          Sleep(1000);

          (Sender as TButton).Enabled:=True;;
          Screen.Cursor:=Kursor;
     except
     end;
end;

end.

 
0

A więc jednak ProcessMessages, który uruchamia kolejne przyciśnięcia. Pytanie czy próbowałeś zmienić zdarzenie na OnMouseUp, albo OnMouseDown, albo timer1.enabled dać przed ProcessMessages?

0

Umieść na formie Memo

procedure TForm1.Button1Click(Sender: TObject);
begin
     (Sender as TButton).Enabled:=False;
 
     Memo1.Lines.Add('Test');
     Sleep(100);
 
     (Sender as TButton).Enabled:=True;
end;

Sprawdź czy to powoduje błąd jeśli nie to problem generuje twój kod. Wstawiany pod przycisk.

0

Panowie, po mojemu to kombinujecie strasznie. Czemu zabezpieczenie autora nie działa? Dlatego, że zabezpieczenia nie ma! Gdzie jakiś if? To powinno być tak:

if not (sender as TButton).Enabled then exit;
(sender as TButton).Enabled:=false;

//operacje

(sender as TButton).Enabled:=true;

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