2014-02-25 78 views
0

我最近開始使用C++進行編碼,而且我對它很陌生。 (我更經常使用Javascript,PHP,Java和Obj-C編寫代碼)C++:嘗試掛鉤消息框並更改其位置

我正在練習如何掛鉤消息框並更改其位置。這是我在.cpp文件中的內容(在閱讀this SO post後)。

#include <iostream> 
#pragma comment(lib,"User32.lib") 
#include <windows.h> 

HHOOK hhookCBTProc = 0; 

LRESULT CALLBACK pfnCBTMsgBoxHook(int nCode, WPARAM wParam, LPARAM lParam){ 
    if (nCode == HCBT_CREATEWND) 
    { 
    CREATESTRUCT *pcs = ((CBT_CREATEWND *)lParam)->lpcs; 
    if ((pcs->style & WS_DLGFRAME) || (pcs->style & WS_POPUP)) 
    { 
     HWND hwnd = (HWND)wParam; 
     SetWindowPos(hwnd, HWND_TOP,130,122, 0, 0,SWP_NOSIZE); 
    } 
    } 
    return (CallNextHookEx(hhookCBTProc, nCode, wParam, lParam)); 
} 

int main(void) 
{ 
    hhookCBTProc = SetWindowsHookEx(WH_CBT,pfnCBTMsgBoxHook, 
           0, GetCurrentThreadId()); 
    int sResult = MessageBox (NULL, "Hooked!", "oh my", MB_OK); 
    UnhookWindowsHookEx(hhookCBTProc); 
    return 0; 

} 

由於某種原因,消息框的位置不變。它出了什麼問題?

(我知道我可以創建自定義窗口或對話框,但我做這種方式,因爲我想學習如何掛鉤一個消息框,並在那裏我做錯了。)

回答

1

首先,你應該檢查調試器,你的鉤子實際上被調用,如果你還沒有。

其次,在觸發HCBT_CREATEWND鉤子事件時,窗口剛剛創建 - 系統尚未確定大小並定位它。它將使用CREATESTRUCT中的值在鉤子返回後覆蓋SetWindowPos呼叫。

查看從MSDN的docslParam值對於此特定掛機事件:

指定長指向包含該窗口 初始化參數CBT_CREATEWND結構。這些參數包括窗口的座標和尺寸。通過更改這些參數,CBTProc掛鉤程序可以設置窗口的初始大小和位置。

因此,使用此掛鉤更改窗口位置的正確方法是直接修改CREATESTRUCT中的值。

另外請注意,這是相當有可能的是,對話管理器的尺寸和後創作定位的窗口,所以如果你發現這仍然不是爲你工作,你可能需要嘗試留意HCBT_MOVESIZE事件來代替。

+0

謝謝!我現在明白了!但我很笨,不知道如何直接修改它。你能詳細說明一下嗎?非常感謝! –

+0

例如'((LPCBT_CREATEWND)lParam) - > lpcs-> x = 130;' –

+0

哦,非常感謝!所以可以通過這種方式訪問​​:)精彩!非常感謝!但是,似乎以這種方式重新定位窗口會影響內容在其中的位置(文本)。如何將內容與中心/過去的位置對齊? –

1

docs

在HCBT_CREATEWND通知時,窗口已被創建,但其最終大小和位置可能尚未確定 並且其父窗口可能尚未建立。

也許嘗試掛鉤到CBT_ACTIVATE。