私のTComponent
には、キーイベントを聞き取り、ESC
の鍵を傍受し、それを私のコンポーネントで処理し、キーストロークを消費/「食べる」ようにして、所有者のフォームがそれを処理しないようにしますその段階でちょうど開始するときTDragObject
のようにドラッグし、ESC
を押して、それをキャンセルします。私のTComponentはどのようにしてESC鍵を傍受し、それを処理できますか?
問題はTDragObject
にはAllocateHWnd
があり、オーナーフォームでCN_KEYDOWN
と通知されています。しかし、誰も私のコンポーネントに通知しません。
フォームのWindowProc
を自分で置き換える必要がありますか?はいの場合は、どのように正しく "本で"それを行うには話す?
ただ、100%明確にするために:
TMyComponent = class(TComponent)
私は小さなテストを作り、動作しているようです:
TMyComponent = class(TComponent)
private
FOldWindowProc: TWndMethod;
FParentForm: TCustomForm;
procedure FormWindowProc(var Message: TMessage);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
end;
...
constructor TMyComponent.Create(AOwner: TComponent);
begin
if not (AOwner is TWinControl) then
raise Exception.Create('TMyComponent.Create: Owner must be a TWinControl');
inherited Create(AOwner);
// hook parent form
FParentForm := GetParentForm(TWinControl(Owner));
if Assigned(FParentForm) then
begin
FOldWindowProc := FParentForm.WindowProc;
FParentForm.WindowProc := FormWindowProc;
end;
end;
destructor TMyComponent.Destroy;
begin
// unhook parent form
if Assigned(FParentForm) then
FParentForm.WindowProc := FOldWindowProc;
inherited;
end;
procedure TMyComponent.FormWindowProc(var Message: TMessage);
begin
FOldWindowProc(Message);
if Message.Msg = CM_CHILDKEY then // CM_CHILDKEY -> CM_DIALOGKEY -> CM_DIALOGCHAR
begin
OutputDebugString('CM_CHILDKEY');
if Message.WParam = VK_ESCAPE then
begin
Beep;
// do my stuff...
Message.Result := 1; // consume keystroke
end;
end;
end;
これがある場合、私は思ったんだけど右/唯一のアプローチ。
ドラッグすると、新しいモーダルループが発生します。それはあなたのための選択肢ではありません。あなたがホストからの協力なしにこれをきれいに行う方法を理解することは難しいです。 –
@DavidHeffernan、OPは「TDragObjectのように」と言っていますが、これは単なる例であり、私はOPがESCキーを望んでいると思います。 ESCはダイアログキーです。私はちょうどコード/ API /ウィンドウのメッセージを今すぐルックアップするために必要な1分を持っていない。 –
@Cosminドラッグ操作のモーダルループは、キューを所有し、ポンピングします。キープレスを手に入れることができます。しかし、フォーム上のコンポーネントにはその贅沢はありません。あなたはどのようにアプリケーションのメッセージループの中に入ることを提案しますか? –