2013-09-26 39 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),然後在執行順序非常重要時執行您的工作。 –