标 题:【原创】WM_NCCALCSIZE消息处理详解修正
作 者:mycaibo
邮 箱:mycaibo@126.com
关键字:C语言、Windows API、WM_NCCALCSIZE消息
时 间:2010-12-09
【前言】
看了网上的一篇《关于WM_NCCALCSIZE消息处理详解(原帖由niesongsong发表)》
的文章,正好自己正在写换肤程序,用了以后发现了一些问题,特贡献出来供
大家参考学习!
【问题】
主要问题是原作者把处理后的NCCALCSIZE_PARAMS结构搞错了。借鉴
MSDN中的CWnd::OnNcCalcSize 函数注释,其原文如下:
afx_msg void OnNcCalcSize( BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp );
Parameters
bCalcValidRects
Specifies whether the application should specify which part of the client area contains
valid information. Windows will copy the valid information to the specified area within
the new client area. If this parameter is TRUE, the application should specify which
part of the client area is valid.
lpncsp
Points to a NCCALCSIZE_PARAMS data structure that contains information an
application can use to calculate the new size and position of the CWnd rectangle
(including client area, borders, caption, scroll bars, and so on).
Remarks
The framework calls this member function when the size and position of the client
area needs to be calculated. By processing this message, an application can
control the contents of the window’s client area when the size or position of
the window changes.
Regardless of the value of bCalcValidRects, the first rectangle in the array
specified by the rgrc structure member of the NCCALCSIZE_PARAMS
structure contains the coordinates of the window. For a child window,
the coordinates are relative to the parent window’s client area.
For top-level windows, the coordinates are screen coordinates.
An application should modify the rgrc[0] rectangle to reflect the
size and position of the client area.
The rgrc[1] and rgrc[2] rectangles are valid only if bCalcValidRects
is TRUE. In this case, the rgrc[1] rectangle contains the coordinates
of the window before it was moved or resized. The rgrc[2] rectangle
contains the coordinates of the window’s client area before the
window was moved. All coordinates are relative to the parent
window or screen.
The default implementation calculates the size of the client area based
on the window characteristics (presence of scroll bars, menu, and so on),
and places the result in lpncsp.
Note This member function is called by the framework to allow your
application to handle a Windows message. The parameters passed to
your function reflect the parameters received by the framework when
the message was received. If you call the base-class implementation
of this function, that implementation will use the parameters originally
passed with the message and not the parameters you supply to the function.
翻译后的大概意思为:当wParam为FALSE时,只有rgrc[0]可用,为新窗口的窗口区域(B),此时需返回新窗口的
客户区大小(BC)。
当wParam为TRUE时,rgrc[0]、rgrc[1]、rgrc[2]都有效.rgrc[0]和前面的一样,rgrc[1]为原先窗口的区域(A),
rgrc[2]为原先窗口的客户区大小(AC),处理后:rgrc[1]、rgrc[2]不变,rgrc[1]还是为原先窗口的区域(A),rgrc[2]还是为原先窗口的客户区区域(AC)(就是这出现问题的,大家可以对照看原版),rgrc[0]为当前当前窗口的
客户区大小(BC)。
因此不管wParam为FALSE还是为TRUE,都是处理rgrc[0],使其为当前窗口客户区的区域。
【更改】
因此该函数可以改为:
case WM_NCCALCSIZE:
ProcNCCalcSize(hWnd,message,wParam,lParam);
int ProcNCCalcSize(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int xFrame = 2; //左右边框的厚度
int yFrame = 2; //下边框的厚度
int nTHight = 30; //标题栏的高度
RECT * rc;
rc = (RECT *)lParam;
rc->left = rc->left + xFrame;
rc->top = rc->top + nTHight;
rc->right = rc->right - xFrame;
rc->bottom = rc->bottom - yFrame;
return GetLastError();
}
大家可以参看原版文章,了解整个处理过程。(望大家多交流,只有多交流
才能进步!)
原址:http://dqzx.neuq.edu.cn/bbs/viewthread.php?tid=17&extra=page%3D1