我想做到以下效果:捕获 窗体上所有的edit文本控件,当它们发生change或keypress事件时,调用某一子程序.除了在每个edit控件的onchange或onkeypress事件中加入 call 子程序,如果我程序中有几十个edit控件,我不想这样做,还有其它方法吗

解决方案 »

  1.   

    用HOOK应该可以实现,下面是代码供参考unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      StdCtrls;
    const
      WM_TestMessage = WM_USER + 2000;
    type
      TForm1 = class(TForm)
        Button1: TButton;
        procedure FormCreate(Sender: TObject);
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.DFM}
    var
      HookHandle: HHOOK;function TestHookProc(Code: Integer; WParam: Longint;Msg:Longint): Longint;stdcall;
    begin
        if (Code = HC_ACTION) then
        if PMsg(Msg)^.Message = WM_TestMessage then
        begin
          showMessage('已经截获该消息');
        end;
        Result := CallNextHookEx(HookHandle, Code, WParam, Longint(@Msg));
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      HookHandle:=SetWindowsHookEx(WH_GETMESSAGE,TestHookProc,0,GetCurrentThreadID);
    end;procedure TForm1.Button1Click(Sender: TObject);
    begin
      PostMessage(self.Handle,WM_TestMessage,0,0);
    end;end.
      

  2.   

    不用Hook也可以。   把窗体的KeyPreview设置为true, 然后在窗体的OnKeyPress中处理就可以了。这样,窗体就会在窗体上控件获取消息之前截获消息了。
      

  3.   

    to 楼主:不管答案如何,以下只是想对你说:
    即使你的窗体上有几十几百个Edit,只要他们的OnChange或OnKeyPress处理过程相同,也是很简单的:procedure TForm1.FormCreate(Sender: TObject);
    var
      I : integer;
    begin
      for I := Self.ComponentCount-1 downto 0 do
        if Self.Components[I] is TEdit then begin
          TEdit(Self.Components[I]).OnChange := EditChange;
          TEdit(Self.Components[I]).OnKeyPress := EditKeyPress;
        end;
    end;procedure TForm1.EditChange(Sender: TObject);
    begin
      Self.Memo1.Lines.Add(Format('%s BeChanged', [TEdit(Sender).Name]));
    end;procedure TForm1.EditKeyPress(Sender: TObject; var Key: Char);
    begin
      Self.Memo1.Lines.Add(Format('%s KeyPress %s', [TEdit(Sender).Name, Key]));
    end;
      

  4.   

    三楼朋友的代码我用了,谢谢,可以实现.
    一楼的代码有点长,我可以借此学HOOK,但还需要时间消化.
    我是VB转过来的.不过,好像有个更直接的方法.定义并写了一个editchange子过程,然后选定全部edit控件,在对象检查器的事件项里的onChange 选择editchange子过程,运行程序,刚才选定的edit控件的onchange事件是执行editchange子过程的代码的.这样做,和三楼朋友的有什么区别?
      

  5.   

    基本没什么大的区别。
    你那样做,方法赋值的代码在.dfm文件里(耐心找找看)
    既使这样赋值,也是可以动态改变的
    还有一个区别,就是你需要重复对象管理器的同一个操作,重复性的劳动量挺大的
      

  6.   

    来晚了
    三楼的朋友的方法不错
    该方法通用性强,
    而且简单,
    在Onchange时速度要快