WM_NCCALCSIZE消息处理详解修正

来源:互联网 发布:淘宝个人店铺收费 编辑:程序博客网 时间:2024/05/17 04:52


【前言】

看了网上的一篇《关于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 thesize and position of the client area.

The rgrc[1] and rgrc[2] rectangles are valid only if bCalcValidRectsis TRUE. In this case, the rgrc[1]rectangle contains the coordinatesof 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 basedon 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 originallypassed with the message and not the parameters you supply to the function.

翻译后的大概意思为:当wParam为FALSE时,只有rgrc[0]可用,为新窗口的窗口区域(B),此时需返回新窗口的

客户区大小(BC)。

clip_image001

当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],使其为当前窗口客户区的区域。

rgrc[0]从入参数获取到的是指窗口的大小的RECT,包含了标题栏和边框的大小。用户可以修改rgrc[0]的大小。修改后rgrc[0]的值会被取走用来作为新窗口的client 客户区的大小。所以当用户实现了OnNcCalcSize消息函数,但是没做任何操作直接返回时,就相当于设置了客户区大小为窗口的大小了。导致了窗口无标题栏无边框的效果

【更改】

因此该函数可以改为:

void CLOLKapai20Dlg::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp){// TODO: 在此添加消息处理程序代码和/或调用默认值int nTHight = 30; //标题栏的高度int xFrame = 2; //左右边框的厚度int yFrame = 2; //下边框的厚度RECT    * rc;rc = (RECT *)lpncsp;//返回的是坐标值,不表示大小rc->top = rc->top + nTHight;//坐标加表示软件大小不变,客户区上边往下移2像素rc->left = rc->left + xFrame;//坐标加表示软件大小不变,客户区左边往右移2像素rc->right = rc->right - xFrame;//坐标加表示软件大小不变,客户区右边往左移2像素rc->bottom = rc->bottom - yFrame;   //坐标加表示软件大小不变,客户区下边往上移2像素//CDialogEx::OnNcCalcSize(bCalcValidRects, lpncsp);}




大家可以参看原版文章,了解整个处理过程。(望大家多交流,只有多交流才能进步!)

0 0
原创粉丝点击