我一直认为创建一个窗口的时候,窗口处理过程处理WM_CREATE是在处理WM_SIZE之前的,所以很多初始化的东西都放在WM_CREATE处来做,但最近弄一个程序发现到了WM_SIZE处出错,原因是空指针,而这个指针应该是在WM_CREATE的时候被赋值的,奇怪了,难道WM_SIZE会在WM_CREATE之前?于是设两个断点,不看不知道,一看还真的如此,如下图:
程序每次总是先触到WM_SIZE的这个断点,难道我理解一直有误?于是我创建了一个hello world程序,调试了半天,又发觉没有这个问题,WM_CREATE总是在WM_SIZE之前,我尝试在别处重现问题,无果……现在,你再仔细看一下上图,你发现问题了么?
我想经过我这么提示,你应该知道了:原因就是WM_CREATE这个断点前一行的SetWindowLong这个调用,这个调用会引起一个WM_SIZE事件,所以这就制造了WM_SIZE在WM_CREATE之前这个假象。处理这个问题很简单,把SetWindowLong这行拿掉,然后把WS_NONAVDONEBUTTON这个属性交给CreateWindow,如下图:
这样就好了,我想顺便提个问题,我在设计一个程序的时候,也碰到了“布局”和“加载”的先后问题,因为布局可能需要重新调整加载的资源,而加载资源又需要参考布局的尺寸,由于功能上的原因,我必须把两者分开,所以存在我前面说的这个先鸡先蛋的难题。最后我是这么弄的,做一个“资源是否已经加载”的标志,然后总是先“布局”,布局的时候检查这个标志,如果没有资源的加载,那就只更改尺寸参数而不调整资源,这样看起来就没什么问题了,从逻辑上来说我的设计确实是WM_SIZE优先于WM_CREATE……
欢迎对这些方面的设计问题留言讨论。