Win10环境下,拦截WM_NCCREATE消息时的一个诡异BUG

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014038143/article/details/78493998

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。再想想老夫硬盘上存储的这么多年来辛苦积累的代码沉淀,突然惊得我虎躯一震,菊花一紧。。。。。。。。。

猜你喜欢

转载自blog.csdn.net/u014038143/article/details/78493998