2009-08-25 113 views
6

我無法讓全局系統鉤子工作。我希望在窗口移動時儘早得到通知,並更改窗口大小。這意味着CBT鉤子HCBT_MOVESIZE不會剪切它,它只發生在窗口移動後。我想勾住窗口的實際移動,並能夠在移動過程中更改窗口大小。全局攔截窗口運動

掛鉤是從DLL中設置的,並且回調函數在該DLL內。這是我試過的。

  • WH_CALLWNDPROC。它在移動窗口時收到警告(從其他應用程序的窗口收到WM_MOVING),但我無法更改消息的內容。與相同。
  • CBT掛鉤HCBT_MOVESIZE。事件發生的很晚。
  • WH_GETMESSAGE。永遠不要收到WM_MOVEWM_MOVINGWM_WINDOWPOSCHANGING。這個鉤子可以讓我改變消息。

更新:Windows事件掛鉤似乎讓我捕捉到它:

hWinEventHook = SetWinEventHook(EVENT_SYSTEM_MOVESIZESTART,  
    EVENT_SYSTEM_MOVESIZEEND, NULL, WinEventProc, 
    0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS); 

然而,這創造了一個不同的問題:改變使用SetWindowPos()不起作用窗口的大小(它改變尺寸沒問題,但立即變回原來的尺寸),即使我使用SWP_NOSENDCHANGING。想法?

更新2:子類化似乎工作,但是每個程序運行後Visual Studio崩潰(所以許多其他窗口)。如果我放置斷點並遍歷「unsubclassing」,而不是當我讓程序自行運行時,它會很好。想法?我有一個CBT鉤子(它早就在那裏),並且每當HCBT_ACTIVATE被髮送到一個新窗口時,我使用SetWindowLongPtr()(它也必須在64位上運行)刪除任何以前的子類,然後子類新窗口。如果我在任何地方放置斷點,並在斷開時立即恢復會話,則一切正常。但是,當我沒有任何斷點時,Visual Studio會在程序退出時崩潰。

回答

1

嗯,我會一直以爲HCBT_MOVESIZE是你想要的恰恰是,鑑於MSDN說,這大約CBT鉤子:

The system calls this function before activating, creating, destroying, 
minimizing, maximizing, moving, or sizing a window.

,特別是:

HCBT_MOVESIZE 
    A window is about to be moved or sized.

(這些報價取自http://msdn.microsoft.com/en-us/library/ms644977%28VS.85%29.aspx

...所以我想你會及時得到HCBT_MOVESIZE電話。處理HCBT_MOVESIZE的鉤子函數也允許返回一個整數,以便系統可以確定該操作是允許還是應該被阻止。因此,考慮到HCBT_MOVESIZE鉤子應該有一個選項來阻止操作,我會說它在移動事件發生之前被調用。

你確定在移動事件後鉤函數是否叫?如果你在你的鉤子函數中對特定的句柄執行GetWindowRect調用,返回的rect是否等於傳遞給鉤子函數的矩形?

+0

HCBT_MOVESIZE會發生什麼情況:用戶可以開始拖動窗口,繼續拖動窗口,並且在窗口放開之前通知不會到達。儘管如此,在窗口被技術性移動之前,你會收到通知,但它仍然非常沒用。 – 2009-08-25 12:07:12

1

掛鉤非常重。你只想在絕對必要時使用它們。

也就是說,您可以使用其中一個基本掛鉤作爲進入流程的一種方式。一旦進入這個過程,你可以繼承你感興趣的窗口,並在你的子類的proc中處理大小消息,而不是試圖在鉤子級別捕捉所有的東西。

根據您想要做什麼來響應調整大小,您可能需要一些進程間通信。

+0

子類似乎是去這裏的路。但是,當我沒有逐步完成子類的實際移除時,Visual Studio始終崩潰。 – 2009-08-26 09:02:28