1. 程式人生 > >Win10環境下,攔截WM_NCCREATE訊息時的一個詭異BUG

Win10環境下,攔截WM_NCCREATE訊息時的一個詭異BUG

Win10環境下,攔截WM_NCCREATE訊息時的一個 詭異BUG

這幾天在編寫一個測試渲染管線的程式時,我直接使用了一段大約在10年前封裝的一段視窗程式碼:

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {//視窗過程;
        LRESULT lRet = 0;
        CGRSWnd* pWnd = NULL;
        ......      
        switch (uMsg)
        {
        case WM_NCCREATE:
        {
            LPCREATESTRUCT pCS = reinterpret_cast
<LPCREATESTRUCT>(lParam); pWnd = reinterpret_cast<CGRSWnd*>(pCS->lpCreateParams); GRS_ASSERT(NULL != pWnd); ....... lRet = 1; } break; ...... return lRet; }

看上去也沒有什麼特別的,就是攔截了一下WM_NCCREATE訊息而已,當然目的也只是為了用自己的C++類封裝Windows視窗物件。而視窗過程必須是類的靜態方法,要在其中得到一個視窗控制代碼對應的C++物件的話,就要通過攔截這個訊息然後從lpCreateParams引數中將物件指標恢復回來。僅此而已!
於是我就愉快的編譯執行了這個程式,一切看上去沒什麼,程式執行也很正常,視窗顯示也正常,畫面也能正常渲染。可是,等等,視窗的標題呢?起先我並沒有注意這個小細節,以為是我視窗Style不對,用現在流行的話來說,可能是我開啟視窗的方式不對!當然不要太在意這些細節!
這裡寫圖片描述


於是簡單的修正了一下視窗的Style,設幾個小斷點跟蹤下,可是我居然沮喪的發現視窗依然沒有標題。鬼知道它都經歷了些什麼?!
最後我乾脆把所有攔截處理的訊息先統統註釋了,然後執行,發現視窗標題居然正常顯示了!好,那就排除法,一個一個恢復,然後執行,最後我發現一旦恢復了對WM_NCCREATE攔截處理,就鐵定沒有視窗標題,Oh,MyGod!之前這段程式碼都很正常啊?Why?我也沒做什麼處理啊,就是得到我傳給它的指標而已啊,其他的我都照著微軟的文件:

Return value
Type: LRESULT
If an application processes this message, it
should return TRUE to continue creation of the window. If the application returns FALSE, the CreateWindow or CreateWindowEx function will return a NULL handle.

正常返回TRUE給系統了啊?
突然我反應過來,於是在呼叫中插入了DefWindowProc的呼叫,改動之後程式碼如下:

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {//視窗過程;
        LRESULT lRet = 0;
        CGRSWnd* pWnd = NULL;
        ......      
        switch (uMsg)
        {
        case WM_NCCREATE:
        {
            LPCREATESTRUCT pCS = reinterpret_cast<LPCREATESTRUCT>(lParam);
            pWnd = reinterpret_cast<CGRSWnd*>(pCS->lpCreateParams);
            GRS_ASSERT(NULL != pWnd);
            .......
            lRet = DefWindowProc(hwnd, uMsg, wParam, lParam);
        }
        break;
        ......
        return lRet;
    }

ok,編譯,執行!一切正常了。
當然這反過來也說明Windows中的核心程式碼細節在這10年中還是經歷了很多修改,居然讓我這10年前的程式碼都出現了這種從來沒遇到過的BUG。再想想老夫硬碟上儲存的這麼多年來辛苦積累的程式碼沉澱,突然驚得我虎軀一震,菊花一緊。。。。。。。。。