我使用的組件內部有一個KeyDown處理程序,該處理程序發送用戶定義的PostMessage(WM_GROUPUNGROUP),並且還具有處理WM_GROUPUNGROUP的自定義消息處理程序。如何攔截用戶定義的消息兩次?
我希望我的應用程序在執行此消息處理程序後執行某些操作,而無需修改組件代碼。
(如何)可以這樣做嗎?
我使用的組件內部有一個KeyDown處理程序,該處理程序發送用戶定義的PostMessage(WM_GROUPUNGROUP),並且還具有處理WM_GROUPUNGROUP的自定義消息處理程序。如何攔截用戶定義的消息兩次?
我希望我的應用程序在執行此消息處理程序後執行某些操作,而無需修改組件代碼。
(如何)可以這樣做嗎?
實現此目的的一種方法是通過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
在將消息分發到控件之前觸發,這聽起來像是對您而言可能是錯誤的方式。
謝謝,這很好。我在我的FormCreate中掛接組件的WindowProc,並保持它乾淨重新分配給FormDestroy中的FOldWindowPoc。 –
您可以將'processed'設置爲true,並手動在OnMessage處理程序中分派消息(DispatchMessage),然後在執行順序非常重要時執行您的工作。 –
爲該組件創建一個插入器類,捕獲該WM_GROUPUNGROUP消息並觸發一個新事件,例如您將在應用程序中綁定的「OnGroupUngroup」。 – TLama
@TLama這隻有在你可以介入所有實例化時纔有效 –
@David,我沒有得到你的記錄。如果您可以按照您的建議更改'WindowProc',爲什麼您無法將一個單元(包含該攔截器)添加到uses子句中?而且這種攔截將適用於該特定單位的一次和全部實例。 – TLama