如何拦截WM_SETFOCUS,WM_KILLFOUC消息(100分)

  • 主题发起人 主题发起人 小妖刀
  • 开始时间 开始时间

小妖刀

Unregistered / Unconfirmed
GUEST, unregistred user!
我要做一个控件,放到Form上以后就可以拦截到Form上发生的输入焦点改变的事件.
我用替换窗口过程,和Application.OnMessage事件的方法,都拦截不到上述的两个
消息,请问各位大大,我的程序有什么问题,谁能给个示范程序.
我的程序如下:

unit test;

interface

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

type
TForm1 = class(TForm)
Edit1: TEdit;
ListBox1: TListBox;
ComboBox1: TComboBox;
Memo1: TMemo;
Label1: TLabel;
Button1: TButton;
Button2: TButton;
Button3: TButton;
ListBox2: TListBox;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
OldWndProc,WndProcPtr: Pointer;
procedure WndMethod(var Msg: TMessage);
Procedure HandleAppMessage(var Msg: TMsg;var Handled: Boolean);
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation
uses ColorFoucs;
{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
fff: TFoucsColor;
begin
fff:=TFoucsColor.Create(self);
fff.Parent:=Form1;
end;

procedure TForm1.HandleAppMessage(var Msg: TMsg; var Handled: Boolean);
begin
if ListBox1.Items.Count > 20 then ListBox1.Items.Clear;
if (Msg.message <> 512) and (Msg.message <> 15) and (Msg.message <> 208)
and (Msg.message <> 280)and (Msg.message <> 160) then
ListBox1.Items.Add(IntToStr(Msg.message));
if Msg.message = WM_SETFOCUS then showmessage('true');
end;

procedure TForm1.WndMethod(var Msg: TMessage);
begin
ListBox2.Items.Add(IntToStr(Msg.Msg));
if Msg.Msg = WM_SETFOCUSthen showmessage('true too');
With Msg do
Result:=CallWindowProc(OldWndProc,Application.Handle,Msg,wParam,lParam);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnMessage:=HandleAppMessage;
WndProcptr:=MakeObjectInstance(WndMethod);
OldWndProc:=Pointer(SetWindowLong(Application.Handle,GWL_WNDPROC,integer(WndProcPtr)));
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
SetWindowLong(Application.Handle,GWL_WNDPROC,Longint(OldWndProc));
FreeObjectInstance(WndProcPtr);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
SendMessage(Application.Handle,WM_SETFOCUS,0,0);
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
PostMessage(Application.Handle,WM_SETFOCUS,0,0);
end;

end.

//程序中用SendMessage和postMessage发送的WM_SETFOCUS消息可以拦截到,但是在form上
//随意点击EDIT,LISTBOX等都监测不到,难道输入焦点改变的时候,没有WM_SETFOCUS消息
//发出???
//
 
我觉得你理解错误。
比如焦点切换到Edit1时,是Edit1获得WM_SETFOCUS。
而不是TApplication。
 
我修改Edit1的窗口过程,可收到WM_SETFOCUS和WM_KILLFOCUS
 
可能我没讲清楚,我想知道怎么不通过Edit1,ListBox1...等等,而直接得到
发生在他们上面的WM_SETFOCUS消息,因为我想做的是一个不可视控件,它监视
发生在Form上的WM_SETFOCUS,等事件,做出处理.
上面的例子是我测试用的.
 
子窗体(Edit,Button...)焦点切换时,
是子窗体自己受到WM_SETFOCUS或WM_KILLFOCUS。
TApplication窗口根本收不到这两个消息。
 
那也就是说没有办法了???
 
你是不是用form的Active事件来处理一下。我看你的意思,不是想知道form的
setfocus,而是form被激活了。
如果你想知道到底是哪个控件被setfocus了。你还是应该对每个控件做事件处理。
 
办法当然有,所有可拥有焦点的控件的OnEnter
和OnExit指向同一个过程。
 
我的意思是在我自己的控件中知道Form上的焦点变换事件(具体来说就是那个控件得到焦点,那个控件失去焦点)
 
问题解决了,我发现Form上每个控件接受到消息时,父窗体都会接受到WM_COMMAND消息.
 
因为Reboot的回答对我的问题有一定的提示作用,所以给分多一点.
 
后退
顶部