最近在产品中遇到一个回退问题:产品的主窗口在点击最大化按钮后,无法最大化显示,和整个屏幕残留了一些gap,并且只有的win7上发生。
1. 由于是从branch合并回到main之后的产生的问题,一开始希望通过changelist对比找到有问题的代码,但由于branch合并后有数十个源文件,难以找到可疑代码而放弃这种方法;
2. 由于主窗口是MFC程序,通过查询MSDN知道窗口最大化时,窗口大小,位置发生变化,onsize,windowposchanged消息函数会被调用,并且MFC framework会发出MAXMIN消息函数去处理对应屏幕的最大化面积的计算;
因此,先使用spy确定了这些消息函数确实被调用,然后在对应函数入口设置断点调试,发现在发送最大化时首先调用MAXMIN消息函数,而后是windowposchanged,onsize函数;
进入MAXMIN时的屏幕最大化参数正确,但等到进入随后两个函数时,最大化参数变小,因此怀疑在MAXMIN有重算最大化面积的逻辑。
调试MAXMIN后发现,该函数会针对无边框类型的主窗口进行最大化面积重算,但在检查创建主窗口函数时,窗口风格为有边框,因此,在此之前有逻辑除去了边框风格;
于是在代码中搜索除去边框风格的代码,最后发现在处理visualmanager的消息函数中会除去边框风格,而在产品中我们继承了MFC的visual manager office2007做了自己的实现。在该函数中,有虚函数会检查是否由windows或GPU去own窗口的渲染,而该函数在office2007的visualmanager的实现中会调用API去检查DWM(desktop window manager)是否被打开运行。在win7中由于该函数始终返回false,导致虚函数的返回值false,从而移除了边框风格,最终导致最大化面积的重算。
最终,重现该虚函数即可修复问题。
但问题在于,1. 为何DWM的检查总是false,即使该服务已经打开运行?2. 为何同样使用office2007 visualmanager的visualstudiodemo没有出现无法最大化的问题?