的可用区域的高和宽(要所有的子窗口都紧排在一起,形成一个大的矩形,这个值才有意义)拷贝到lpRectParam指向的RECT结构的bottom 和right成员里,其top和left成员被置零。使用这个nFlag值来调用RepositionBars的目的不是要重排子窗口,而是要看看,假如重排子窗口的话,这些子窗口将占去多大一块,最后剩下的可用区域在什么位置等等信息。
当nFlag等于reposExtra时,该函数的功能和nFlag等于reposDefault时差不多,有点小小的区别。此时需要用到lpRectParam。前面说过,当 nFlag等于reposDefault时,RepositionBars函数将在最后把id为nIDLeftOver的子窗口的大小和位置调整到被其他子窗口切剩的可用区域内,使这个子窗口正好完全覆盖最后的可用区域。而当nFlag等于reposExtra时,RepositionBars在调整id为nIDLeftOver的子窗口的大小和位置前,还要用 lpRectParam来对最后剩下的可用区域做修正。假设lpRect指向的是最后的可用区域,那么这个修正是这样进行的:
lpRect->top+=lpRectParam->top;
lprect->left+=lpRectParam->left;
lpRect->right-=lpRectParam->right;
lpRect->bottom-=lpRectParam->bottom;
通过这样的修正,可以使最后剩下的可用区域不被id为nIDLeftOver的子窗口占满,而是空出一些地方来留作他用。
(5)bStretch
这个参数上面已经提到一点它的作用。它主要是提供给各个响应WM_SIZEPARENT消息的子窗口用的,子窗口例如工具栏,状态条等在决定自己将从父窗口客户区的可用空间里划走多少时,这个参数也是个判断的依据。详细可以参阅工具栏和状态条响应WM_SIZEPARENT的函数OnSizeParent()。
2。消息WM_SIZEPARENT
这是个mfc自定义的消息。在msdn里的TN024这篇技术文章里有关于这个消息的说明。
该消息的两个参数中wParam不用,lParam是指向一个AFX_SIZEPARENTPARAMS结构变量的指针,这个结构变量是在RepositionBars函数里定义的:
AFX_SIZEPARENTPARAMS layout;
AFX_SIZEPARENTPARAMS结构定义如下:
struct AFX_SIZEPARENTPARAMS
{
HDWP hDWP;
RECT rect;
SIZE sizeTotal;
BOOL bStretch;
};
这个结构变量的成员是在RepositionBars函数里填写的:它的bStretch成员就是RepositionBars的参数bStretch,它的sizeTotal成员的两个成员cx和cy都被设置为零,它的rect成员就是从RepositionBars的参数lpRectClient里拷贝过来的,就是父窗口客户区的初始可用区域嘛。每个响应这个消息的子窗口都必须修改rect成员的值,以便切去自己所占据的部分。
成员hDWP是什么?这得知道三个api函数:BebinDeferWindowPos(),DeferWindowPos()和EndDeferWindowPos()。这三个api函数是用来成批设置窗口的位置和尺寸的。BebinDeferWindowPos()先通知windows分配一个将用来存贮窗口的位置和尺寸信息的结构,它不是返回这个结构的指针,而是返回代表这个结构的句柄,句柄的类型是HDWP。然后每个需要重新设置位置和尺寸的窗口都要调用DeferWindowPos()函数(该函数需要那个HDWP 类型的句柄为参数),以便往那个结构里填写各自的窗口位置和大小信息。最后,在某个合适的时候调用EndDeferWindowPos(),windows就会根据那个结构里的信息把有关的窗口的位置和大小一次性设置好。比起针对每个窗口分别用SetWindowPos()等函数逐个设置来说,这种方法速度快。
好了,在RepositionBars函数里正是调用了BebinDeferWindowPos(),获得一个HDWP类型的句柄,这个句柄就被填写到了上面那个结构变量 layout的成员hDWP里。然后RepositionBars函数给每个符合条件的子窗口发送WM_SIZEPARENT消息。在每个响应WM_SIZEPARENT消息的子窗口里,要调用DeferWindowPos()来设置位置和尺寸信息。当所有的子窗口都响应完毕WM_SIZEPARENT消息后,RepositionBar