美文网首页Windows客户端开发
CreateWindowEx创建窗口失败的问题

CreateWindowEx创建窗口失败的问题

作者: mercurygear | 来源:发表于2018-06-14 20:26 被阅读0次
    问题

    测试同学反馈了一个持续几个版本都没解决的bug,程序带的内嵌播放器的截取与转码功能不能正常工作。

    定位

    日志上看到是CreateWindowEx失败了,当时就有点奇怪,一般比较少会创建窗口失败啊,再说这个功能之前也是正常的。

    打开代码一看,找到CreateWindowEx的调用之处,前后左右都检查了下,没发现代码有什么异常的地方,这更让人纳闷了。

    因为问题是必现的,所以直接debug模式开断点跑到问题所在之处,发现有更奇怪的地方,CreateWindowEx失败之后,GetLastError返回是0。

    赶紧打开MSDN,仔细查看了这个函数的说明之后,还是没察觉到什么。

    接着网上再找找这个问题,发现有个老外写了篇文章,专门总结了CreateWindowEx调用失败的原因,里面提到CreateWindowEx在创建了窗口之后,是会发送WM_NCCREATE, WM_NCCALCSIZE,WM_CREATE这三个消息给窗口的,如果在WM_CREATE的消息处理中,返回-1的话,窗口出来的窗口会被销毁,然后函数返回NULL。这下有点端倪了。

    再回过头看看代码,这里创建的是一个ATL的窗口(窗口类名是ATLAXWIN_CLASS宏),难道是这个地方出了问题?

    CreateWindowEx(WS_EX_TOOLWINDOW, _T(ATLAXWIN_CLASS), szProgid, 
        WS_CHILD|WS_CLIPCHILDREN|WS_CLIPSIBLINGS, GetDesktopWindow(), 
        NULL,_AtlBaseModule.m_hInst, NULL);
    

    继续开启断点调试,从AtlAxWinInit => AtlAxWindowProc => AtlAxCreateControlLic => AtlAxCreateControlLicEx => CreateControlLicEx => CreateNormalizedObject 一步步跟踪下来,终于发现失败的原因了:CoCreateInstance创建控件对象失败,最终使得WM_CREATE消息处理返回-1,从而终止窗口创建。

    呼~~~,接下来就好办了,检查了下控件的注册表信息,是完整的,但是InProcServer32里的路径对应的文件不存在了,再打开对应的目录一看,恍然大悟。
    原来这个控件对应的dll名字有带版本号,升级的时候应该是注册表信息没处理好,结果旧文件删除了,新文件也放上去了,但是注册表信息没更新,最终使得CoCreateInstance无法把控件创建出来。
    把这个问题反馈给了控件的作者,等他修复了。

    相关文章

      网友评论

        本文标题:CreateWindowEx创建窗口失败的问题

        本文链接:https://www.haomeiwen.com/subject/crkueftx.html