2013-09-26 41 views
0

我使用的组件内部有一个KeyDown处理程序,该处理程序发送用户定义的PostMessage(WM_GROUPUNGROUP),并且还具有处理WM_GROUPUNGROUP的自定义消息处理程序。如何拦截用户定义的消息两次?

我希望我的应用程序在执行此消息处理程序后执行某些操作,而无需修改组件代码。

(如何)可以这样做吗?

+0

为该组件创建一个插入器类,捕获该WM_GROUPUNGROUP消息并触发一个新事件,例如您将在应用程序中绑定的“OnGroupUngroup”。 – TLama

+0

@TLama这只有在你可以介入所有实例化时才有效 –

+0

@David,我没有得到你的记录。如果您可以按照您的建议更改'WindowProc',为什么您无法将一个单元(包含该拦截器)添加到uses子句中?而且这种拦截将适用于该特定单位的一次和全部实例。 – TLama

回答

4

实现此目的的一种方法是通过WindowProc属性。

只需为您想挂钩的实例分配WindowProc即可提供您自己的窗口过程。您需要复制一份以前的值WindowProc,以便确保执行原始处理。

大约是这样的:

type 
    TMyClass = class 
    .... 
    FOldWindowProc: TWndMethod; 
    procedure NewWindowProc(var Message: TMessage); 
    .... 
    end; 

重定向你做这个窗口过程:

FOldWindowProc := SomeControl.WindowProc; 
SomeControl.WindowProc := NewWindowProc; 

然后实现这样新的窗口过程:

procedure TMyClass.NewWindowProc(var Message: TMessage); 
begin 
    FOldWindowProc(Message); 
    if Message.Msg = WM_GROUPUNGROUP then 
    .... 
end; 

当您完成了控制,将旧窗口过程重新放回原位:

SomeControl.WindowProc := FOldWindowProc; 

另一种方法是利用消息排队的事实。您可以添加一个Application.OnMessage处理程序,很可能通过使用TApplicationEvents对象。这将查看所有排队的消息。但是,OnMessage在将消息分发到控件之前触发,这听起来像是对您而言可能是错误的方式。

+0

谢谢,这很好。我在我的FormCreate中挂接组件的WindowProc,并保持它干净重新分配给FormDestroy中的FOldWindowPoc。 –

+1

您可以将'processed'设置为true,并手动在OnMessage处理程序中分派消息(DispatchMessage),然后在执行顺序非常重要时执行您的工作。 –