I need to somehow implement this in Delphi 2009:
The user clicks on button 2. If the user's ver开发者_开发问答y last action was clicking on button 1, then I want to do one thing, but if the user's very last action was anything else, I want to do another thing.
Obviously, I set up a boolean variable: UserClickedOnButton1 and set it to true when button 1 is clicked on, and I test that variable in the OnButtonClick event for Button 2.
My question is how do I set that to false whenever anything else is done by the user before clicking on button 2. (e.g. Mouse press, key press, arrow keys, switch to another program, or anything else).
... or is there a simpler way to do this that I am overlooking.
The code below seems to work (D7), but please check this for your specific situation.
type
TButton = class(StdCtrls.TButton)
private
FClickedLast: Boolean;
FNextButton: TButton;
protected
procedure WndProc(var Message: TMessage); override;
public
procedure Click; override;
property ClickedLast: Boolean read FClickedLast write FClickedLast;
property NextButton: TButton write FNextButton;
end;
TForm1 = class(TForm)
...
procedure TForm1.FormCreate(Sender: TObject);
begin
Button1.NextButton := Button2;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
if Button1.ClickedLast then
Caption := Caption + ' +'
else
Caption := Caption + ' -';
Button1.ClickedLast := False;
end;
{ TButton }
procedure TButton.Click;
begin
inherited Click;
if (FNextButton <> nil) and Focused then
FClickedLast := True;
end;
procedure TButton.WndProc(var Message: TMessage);
begin
if (FNextButton <> nil) and not (csDestroying in ComponentState) then
case Message.Msg of
CM_CANCELMODE,
WM_KEYFIRST..WM_KEYLAST:
FClickedLast := False;
WM_KILLFOCUS:
if TWMKillFocus(Message).FocusedWnd <> FNextButton.Handle then
FClickedLast := False;
end;
inherited WndProc(Message);
end;
Explanation:
- CM_CANCELMODE handles mouse clicks anywhere not resulting in changing focus,
- WM_KEY* handles all key events, but also switching to another application (there is a WM_SYSKEYDOWN, otherwise WM_KILLFOCUS takes care),
- WM_KILLFOCUS handles everything else.
From what I think; It's not really possible unless you're willing to go and track all (or at least all possibly unwanted) of events with logic.
A key-press (Tab?) can still be valid to move on to the next button and click it; a mouse-down event, obviously is good if it's on the second button, otherwise it's not. You'd probably want to check if the 'first button is clicked' before executing a whole bunch of logic to slow down every keypress/mousedown/lostfocus event in your application.
An idea could be to use a timer, but this doesn't prevent the user from 'quickly' doing something else.
Edt1: If all other actions that are 'illegal' are actually doing something, perhaps a lostfocus event on the first button could be a start?
精彩评论