2011-07-27 3 views
4

私は何とかデルファイ2009年にこれを実装する必要があります。その後、私は一つのことをやりたい、ユーザーの非常に最後のアクションは、ボタン1をクリックした場合、ユーザーがボタン2をクリックするアクションが完了したら変数を設定するには(Delphiで)?

が、ユーザーの非常に最後のアクションであれば私は別のことをしたい。

もちろん、私は、ブール変数の設定:UserClickedOnButton1を、ボタン1がクリックされたときにtrueに設定すると、私はボタンのOnButtonClickイベントでその変数をテスト2.

私の質問は、私が設定しない方法ですボタン2をクリックする前にユーザーが何か他の操作を行ったときは、それを偽にします(マウスを押す、キーを押す、矢印キー、別のプログラムに切り替えるなど)。

...これを行う簡単な方法は、私が見落としているところです。

+0

"anything else"はかなり曖昧です。たとえば、メインウィンドウを最小化するなど、別のプログラムに切り替えると、これは達成しようとしているかなり不明瞭な(定義されていない)もののようです。できるだけ正確に質問を編集してください。後で来る貧しい人々を考えて、何か他のものが何を意味しているのか疑問に思います。... –

+0

@Warren:基本的には、ボタン2をクリックする以外は、ボタン1をクリックした特別なアクションをキャンセルする必要があります。 – lkessler

+0

このコントロールを含むメインウィンドウのフォーカスが失われたり、他のコントロール上のウィンドウ内の任意の場所にマウスが移動したりすると... –

答えて

10

以下のコードは動作しているようですが(D7)、具体的な状況を確認してください。

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; 

説明:

  • CM_CANCELMODEがどこにフォーカスを変更する際に得られていないマウスクリックを処理し、
  • WM_KEY *は、すべてのキーイベントを処理するだけでなく、他のアプリケーション(WM_SYSKEYDOWNがあり、そうでなければWM_KILLFOCUSに切り替えます処理します)、
  • WM_KILLFOCUSは他のすべてを処理します。
+0

ダーン、あなたは私にそれを打ち明けました:) –

+0

@NGLN:あなたの答えは潜在的なもので、私が探していたものです(つまり、変数をすべて1つのルーチンにリセットしています)。私は今夜​​家に帰るときにそれが私のために働くかどうか確認するつもりです。 – lkessler

+1

これは、WndProcのための良い使い方のように思えます。なぜなら、1つの場所でたくさんの異なるメッセージを扱うことが考えられるからです。 –

2

私は思っています。ロジックを使用してすべてのイベント(または少なくともすべての可能性のある不要イベント)を追跡して追跡しない限り、実際には可能ではありません。

キー押し(Tab?)は、次のボタンに移動してクリックすることができます。マウスダウンのイベントは、それが2番目のボタンにある場合は明らかに良好です。それ以外の場合はそうではありません。アプリケーションのすべてのkeypress/mousedown/lostfocusイベントを遅くするためにロジック全体を実行する前に、「最初のボタンがクリックされた」かどうかをチェックしたいと思うでしょう。

アイデアはタイマーを使用することですが、ユーザーが他のことを「すばやく」するのを妨げるものではありません。

Edt1:「違法」であるアクションが実際に何かをしている場合は、最初のボタンのlostfocusイベントが開始される可能性がありますか?

+0

これは、button2のonclickがAFAIKを引き起こす前に変数の値を最初にfalseに設定するので、無用です。 – LeleDumbo

+0

はい、論理を設定せずにfalse onMouseDown /に設定した場合、そうなります。 – PtPazuzu

+0

@PtPazuzu:試してくれてありがとう。単純な解決策があれば、私が抱えていた問題と私の不思議を完全に表現できました。 – lkessler

関連する問題