Mdi子窗口之闪烁问题的解决
困惑了2天的mdi子窗口问题一直无法解决。其实也不是两天,两个晚上,白天上班,毕竟这是业余爱好。网上找了
一堆资料,什么把子窗口大小设置为屏幕大小,什么用LockUpdate锁定之类的都有,试了一下,发现都是没有解决根本。
苦恼中看来看去,对mdi子窗口最大化以后进行激活切换的时候闪烁是带了边框的的闪烁现象进行了思考,为什么有
个边框啊?最后猜想mdi子窗口最大化以后被隐藏起来的窗口肯定被设置为不是最大化状态了,也就是它的尺寸肯定小于
主框架的mdi client窗口,所以看到闪烁的时候一个边框。为什么闪烁?因为它被激活以后又再回复最大化尺寸。
最后把CMDIChildWnd基类的OnSize映射出来,看一看。进行跟踪,发现用windows菜单进行子窗口的切换,
首先是OnMDIActivate得到响应,然后的确跑到了OnSize。被激活了,发现尺寸不对,再处理一下尺寸,窗口的尺寸
变了,当然要闪烁了。怪不得连菜单条都在闪烁,和一个没有最大化状态的mdi子窗口最大化成了一样的情形,主框架菜
单条也要闪烁一下,因为是共享的嘛。
按照自己的想法,修改OnSize代码:
void CChildFrame::OnSize(UINT nType, int cx, int cy)
{
CMDIChildWnd::OnSize(nType,cx,cy);
this->MDIMaximize();
}
就是OnSize后用MDIMaximize();把窗口最大化。
运行,ok,问题解决。切换非常平稳。并且,再次跟踪代码,发现子窗口切换的时候只有OnMDIActivate得到了
响应,OnSize不再执行。看来,mfc认为窗口已经不需要改变尺寸了。
但是问题又来了,哈哈,总会有办法的。就是,假如你在一个子窗口上拖小了主窗口,出现了滚动条,再切换其它
一模一样的视图的子窗体,没有滚动条,所以边上要闪一下。因为mfc认为没有必要再OnSize嘛,所以切换到其它窗口
时没有onsize一下,滚动条无法产生。
另一个问题,调用MDIMaximize()最大化以后,子窗口的三个系统按钮没有再显示了。并且什么层叠,平铺的窗口
菜单命令也不起作用了。
下主框架就可以关闭了,因为系统按钮图像真正的到对应到了它的窗口上的应该的位置。
毕竟我想找到原因了,这些不是大问题了。
经过多次跟踪发现,CChildFrame的两个事件响应函数的执行顺序:当切换mdi子框架时:
首先是原先的激活窗口响应OnMDIActivate,也就是原来处于激活状态的窗口要变为非激活态了。
然后程序进入OnSize,所有的其它mdi子窗体都一一响应这个来改变尺寸;原来处于激活态的窗口如果是最大化的,经过
第一个OnSize,它的尺寸就变小了。所以躲在后面的窗口不是最大化的,这是后来引起闪烁的原因。其它非激活态的
mdi子窗口都会按照这个尺寸OnSize。
最后,被激活的窗口响应OnMDIActivate事件。此时这个窗口已经经过了OnSize,如果是最大化,那么它已经变成最大化
状态了。这个时候只是要激活,被显示出来了。
顺序大概就是这样,不过可能有点小差错,没关系的,不影响解决问题的思路就行。
未完待续........