如何在WM_NCCALCSIZE中设置菜单位置和边框大小 [英] How to set menu position and border size in WM_NCCALCSIZE

查看:233
本文介绍了如何在WM_NCCALCSIZE中设置菜单位置和边框大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,


I我正在用C ++ windows SDK编写桌面程序,我想自定义非客户区域,所以我处理了 WM_NCCALCSIZE消息,但是我遇到了一些奇怪的
问题可以帮忙,


1,当程序初始化时,一切看起来都符合我的预期,但是当我点击标题栏中的图标区域时,不是系统菜单弹出,而是菜单栏出现,如果我点击关闭按钮区域,原始关闭按钮将出现
i没有在WM_NCPAINT消息进程中绘制它,如果我删除了WM_NCCALCSIZE消息句柄进程,一切恢复到默认,所以我相信我必须在WM_NCCALCSIZE消息处理过程中遗漏一些东西,我还应该处理什么  WM_NCCALCSIZE消息中的e


应用初始状态下的屏幕截图


http://b.picphotos.baidu.com/album/s%3D1600%3Bq%3D90/sign=2343c30edff9d72a1364141be41a1345/d788d43f8794a4c24411401a08f41bd5ad6e39d4.jpg


鼠标点击后捕获的屏幕截图


http:// f。 picphotos.baidu.com/album/s%3D1000%3Bq%3D90/sign=0234ba391930e924cba498317c385577/bd315c6034a85edf888d59124f540923dd5475f9.jpg


2.第二个问题是关于边框的大小,我重新计算客户端的大小是在  WM_NCCALCSIZE
消息的过程中,我做的边框比windows标准,但是当主窗口最大化时,问题出现,边框没有完全隐藏,客户区域没有覆盖整个客户区域,客户端
区域和屏幕边缘之间仍然存在差距。如何更改  WM_NCCALCSIZE中的默认边框大小?


http://a.picphotos.baidu.com/album/s%3D680%3Bq%3D90/sign=6f45b2a5402309f7e36fae1a42357dce /960a304e251f95caf1c73587cf177f3e670952d4.jpg


我们将非常感谢任何帮助!


以下是源代码 

 

// test20150529.cpp:定义入口点对于控制台应用程序。
//

#include" stdafx.h"
#include" resource.h"

#define WIN32_LEAN_AND_MEAN //从Windows头文件中排除很少使用的东西
// Windows头文件:
#include< windows.h>

// C RunTime头文件
#include< stdlib.h>
#include< malloc.h>
#include< memory.h>
#include< tchar.h>

#include< windowsx.h>
#include< winuser.h>
#include< uxtheme.h>
#include< wingdi.h>
#include< comdef.h>
#include< gdiplus.h>


#define MAX_LOADSTRING 100
//全局变量:
HINSTANCE hInst; //当前实例
TCHAR szTitle [MAX_LOADSTRING]; //标题栏文本
TCHAR szWindowClass [MAX_LOADSTR ING]; //使用命名空间Gdiplus的主窗口类名


;
#pragma comment(lib," Gdiplus.lib")
// #include" Win32MyFw.h"

extern HINSTANCE hInst; //当前实例

INT_PTR CALLBACK关于(HWND hDlg,UINT消息,WPARAM wParam,LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch(message)
{
case WM_INITDIALOG:
return(INT_PTR)TRUE;

case WM_COMMAND:
if(LOWORD(wParam)== IDOK || LOWORD(wParam)== IDCANCEL)
{
EndDialog(hDlg,LOWORD(wParam) ));
return(INT_PTR)TRUE;
}
休息;
}
return(INT_PTR)FALSE;
}

void MainWnd_OnCommand(HWND hWnd,int id,HWND hWndCtl,UINT codeNotify)
{
switch(id)
{
case IDM_ABOUT:
DialogBox(hInst,MAKEINTRESOURCE(IDD_ABOUTBOX),hWnd,About);
休息;
case IDM_EXIT:
DestroyWindow(hWnd);
休息;
默认值:
FORWARD_WM_COMMAND(hWnd,id,hWndCtl,codeNotify,DefWindowProc);
休息;
}
//返回0;

}

BOOL MainWnd_OnCreate(HWND hWnd,LPCREATESTRUCT lpCreateStruct)
{
#pragma comment(lib," UxTheme")
SetWindowTheme(hWnd,_T(""),_ T(""));
返回1;
}

void MainWnd_OnDestroy(HWND hWnd)
{
PostQuitMessage(0);
}

BOOL MainWnd_OnNCActivate(HWND hWnd,BOOL fActive,HWND hWndActDeact,BOOL fMimimized)
{
return 1;
}

UINT MainWnd_OnNCCalcSize(HWND hWnd,BOOL fCalcValidRects,NCCALCSIZE_PARAMS * lpcsp)
{
UINT uRc = 0;


int xFrame = 10;
int yFrame = 10;
int nTHight = 40;


RECT rcClientNew; //新客户端矩形(在父坐标中),第一个矩形包含由移动或调整大小产生的新客户端矩形的坐标。
RECT rcValidDst; //目标矩形(在父坐标中),第二个矩形包含有效的目标矩形。
RECT rcValidSrc; //源矩形(在父坐标中)第三个矩形包含有效的源矩形。


if(fCalcValidRects){

CopyRect(& rcValidSrc,& lpcsp-> rgrc [1]);
CopyRect(& rcValidDst,& lpcsp-> rgrc [0]);

rcClientNew.left = rcValidDst.left + xFrame;
rcClientNew.top = rcValidDst.top + nTHight;
rcClientNew.right = rcValidDst.right - xFrame;
rcClientNew.bottom = rcValidDst.bottom - yFrame;

CopyRect(& lpcsp-> rgrc [0],& rcClientNew);
CopyRect(& lpcsp-> rgrc [1],& rcValidDst);
CopyRect(& lpcsp-> rgrc [2],& rcValidSrc);
返回WVR_VALIDRECTS;
}
else {
RECT * rc;
rc =(RECT *)lpcsp;

rc-> left = rc-> left + xFrame;
rc-> top = rc-> top + nTHight;
rc-> right = rc-> right - xFrame;
rc-> bottom = rc-> bottom - yFrame;
返回0;
}

}

无效MainWnd_OnNCPaint(HWND hWnd,HRGN hrgn)
{
HDC hdc;
// hdc = GetDCEx(hWnd,hrgn,DCX_WINDOW | DCX_INTERSECTRGN | 0x10000);
hdc = GetWindowDC(hWnd);
//画到这个DC
RECT rcWnd;
GetWindowRect(hWnd,& rcWnd);
OffsetRect(& rcWnd,-rcWnd.left,-rcWnd.top);

//删除客户区
RECT ClientRect;
GetClientRect(hWnd,& ClientRect);
OffsetRect(& ClientRect,10,40);
ExcludeClipRect(hdc,ClientRect.left,ClientRect.top,ClientRect.right,ClientRect.bottom);

图形g(hdc);
Rect rcNcWnd(0,0,rcWnd.right - 1,rcWnd.bottom - 1);

Pen penFrame(Color(255,0,0,0),1);
g.DrawRectangle(& penFrame,rcNcWnd);

Rect rcCaption(rcNcWnd.GetLeft()+ 1,rcNcWnd.GetTop()+ 1,rcNcWnd.GetRight() - 1,rcNcWnd.GetTop()+ 19);
SolidBrush BrushCaption(颜色(255,70,90,125));


g.FillRectangle(& BrushCaption,rcCaption);

DrawIconEx(hdc,2,2,(HICON)GetClassLong(hWnd,GCL_HICONSM),16,16,0,0,DI_NORMAL);

ReleaseDC(hWnd,hdc);
}

void MainWnd_OnNCLButtonDown(HWND hWnd,BOOL fDoubleClick,int x,int y,UINT codeHitTest)
{

switch(codeHitTest)
{
case HTCAPTION:
case HTSYSMENU:
case HTBORDER:
case HTBOTTOM:
case HTBOTTOM
case HTBOTTOMRIGHT:
case HT
case HTRIGHT:
case HT
case HTTOP
case HTTOPRIGHT:
case HTCLOSE://自定义绘制
FORWARD_WM_NCLBUTTONDOWN(hWnd,fDoubleClick,x,y ,codeHitTest,DefWindowProc);
休息;

默认值:
break;
}
}

UINT MainWnd_OnNCHitTest(HWND hWnd,int x,int y)
{
UINT uRes = HTNOWHERE; // FORWARD_WM_NCHITTEST(hWnd, x,y,DefWindowProc);
RECT rcWnd;
GetWindowRect(hWnd,& rcWnd);


RECT rcBottom;
RECT rcBottomLeft;
RECT rcBottomRight;
RECT rcLeft;
RECT rcRight;
RECT rcTop;
RECT rcTopLeft;
RECT rcTopRight;
RECT rcCaption;
RECT rcSysIcon;
RECT rcBtnClose;

//边框
SetRect(& rcBottom,rcWnd.left + 5,rcWnd.bottom - 5,rcWnd.right - 5,rcWnd.bottom);
SetRect(& rcBottomLeft,rcWnd.left,rcWnd.bottom - 5,rcWnd.left + 5,rcWnd.bottom);
SetRect(& rcBottomRight,rcWnd.right - 5,rcWnd.bottom - 5,rcWnd.right,rcWnd.bottom);

SetRect(& rcLeft,rcWnd.left,rcWnd.top + 5,rcWnd.left + 5,rcWnd.bottom - 5);
SetRect(& rcRight,rcWnd.right - 5,rcWnd.top + 5,rcWnd.right,rcWnd.bottom - 5);

SetRect(& rcTop,rcWnd.left + 5,rcWnd.top,rcWnd.right - 5,rcWnd.top + 5);
SetRect(& rcTopLeft,rcWnd.left,rcWnd.top,rcWnd.left + 5,rcWnd.top + 5);
SetRect(& rcTopRight,rcWnd.right - 5,rcWnd.top,rcWnd.right,rcWnd.top + 5);

// CaptionBar
SetRect(& rcCaption,rcWnd.left + 1,rcWnd.top + 1,rcWnd.right - 1,rcWnd.top + 19);

SetRect(& rcSysIcon,rcWnd.left + 2,rcWnd.top + 2,rcWnd.left + 18,rcWnd.top + 18);
SetRect(& rcBtnClose,rcWnd.right - 18,rcWnd.top + 2,rcWnd.right - 2,rcWnd.top + 18);

POINT pt;
pt.x = x;
pt.y = y;

if(PtInRect(& rcSysIcon,pt)){return HTSYSMENU; }
else if(PtInRect(& rcBtnClose,pt)){return HTCLOSE; }
else if(PtInRect(& rcBottom,pt)){return HTBOTTOM; }
else if(PtInRect(& rcBottomLeft,pt)){return HTBOTTOMLEFT; }
else if(PtInRect(& rcBottomRight,pt)){return HTBOTTOMRIGHT; }
else if(PtInRect(& rcLeft,pt)){return HTLEFT; }
else if(PtInRect(& rcRight,pt)){return HTRIGHT; }
else if(PtInRect(& rcTop,pt)){return HTTOP; }
else if(PtInRect(& rcTopLeft,pt)){return HTTOPLEFT; }
else if(PtInRect(& rcTopRight,pt)){return HTTOPRIGHT; }

else if(PtInRect(& rcCaption,pt)){return HTCAPTION; }
else
{
return uRes; // DefWindowProc(hWnd,WM_NCHITTEST,NULL,MAKELONG(x,y));
}
}


void MainWnd_OnPaint(HWND hWnd)
{
PAINTSTRUCT ps;
HDC hdc;
hdc = BeginPaint(hWnd,& ps);

RECT rc;
GetClientRect(hWnd,& rc);
Rectangle(hdc,0,0,rc.right,rc.bottom);
DrawText(hdc,_T("Hello,Windows 8!"), - 1,& rc,DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint(hWnd,& ps);

//返回0;
}

///////////////////////////////////// /////////////////////////////////////

LRESULT CALLBACK MainWnd_WndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch(msg)
{
HANDLE_MSG(hWnd,WM_COMMAND,MainWnd_OnCommand);
HANDLE_MSG(hWnd,WM_CREATE,MainWnd_OnCreate);
HANDLE_MSG(hWnd,WM_DESTROY,MainWnd_OnDestroy);
HANDLE_MSG(hWnd,WM_NCACTIVATE,MainWnd_OnNCActivate);

//删除WM_NCCALCSIZE,一切都变为默认
HANDLE_MSG(hWnd,WM_NCCALCSIZE,MainWnd_OnNCCalcSize);
HANDLE_MSG(hWnd,WM_NCPAINT,MainWnd_OnNCPaint);
HANDLE_MSG(hWnd,WM_NCHITTEST,MainWnd_OnNCHitTest);
HANDLE_MSG(hWnd,WM_PAINT,MainWnd_OnPaint);

默认值:return DefWindowProc(hWnd,msg,wParam,lParam);
}
}


ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;

wcex.cbSize = sizeof(WNDCLASSEX);

wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = MainWnd_WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(IDI_WIN32MYFW));
wcex.hCursor = LoadCursor(NULL,IDC_ARROW);
wcex.hbrBackground =(HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_TEST20150529);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance,MAKEINTRESOURCE(IDI_SMALL));

返回RegisterClassEx(& wcex);
}


BOOL InitInstance(HINSTANCE hInstance,int nCmdShow)
{
HWND hWnd;

hInst = hInstance; //在我们的全局变量中存储实例句柄

hWnd = CreateWindow(szWindowClass,szTitle,WS_OVERLAPPEDWINDOW,// ^ WS_CAPTION,//&〜(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU),
CW_USEDEFAULT,0,CW_USEDEFAULT,0,NULL,NULL,hInstance,NULL);

if(!hWnd)
{
返回FALSE;
}

ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);

返回TRUE;
}




int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);

// TODO:在这里放置代码。
MSG msg;
HACCEL hAccelTable;

GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;

GdiplusStartup(& gdiplusToken,& gdiplusStartupInput,NULL);

//初始化全局字符串
LoadString(hInstance,IDS_APP_TITLE,szTitle,MAX_LOADSTRING);
LoadString(hInstance,IDC_WIN32MYFW,szWindowClass,MAX_LOADSTRING);
MyRegisterClass(hInstance);

//执行应用程序初始化:
if(!InitInstance(hInstance,nCmdShow))
{
return FALSE;
}

hAccelTable = LoadAccelerators(hInstance,MAKEINTRESOURCE(IDC_WIN32MYFW));

//主消息循环:
while(GetMessage(& msg,NULL,0,0))
{
if(!TranslateAccelerator(msg.hwnd) ,hAccelTable,& msg))
{
TranslateMessage(& msg);
DispatchMessage(& msg);
}
}
GdiplusShutdown(gdiplusToken);

return(int)msg.wParam;
}








$


$

解决方案

如果您想绘制非客户区域,您的代码必须在其中绘制所有内容。 来自MSDN:


"系统发送
WM_NCPAINT
消息框架,必须更新。系统还可以发送其他消息来指示窗口更新其
客户区的一部分;例如,当一个窗口变为活动或非活动时,它会发送

WM_NCACTIVATE
消息以更新其标题栏。通常,不建议为标准窗口处理这些消息,因为应用程序必须能够为窗口绘制非客户区域的所有必需部分。对于
这个原因,大多数应用程序将这些消息传递给
DefWindowProc
用于默认处理。"


您的代码是否需要绘制所有内容?




Hi,

I am writing a desktop program with C++ windows SDK, I want to customize the non-client area, so I processed the WM_NCCALCSIZE message, but I got some strange problem which I hop someone can help,

1, when the program initial , everything looks what I expected, but when I click the icon area in the caption bar ,not the system menu popup, but the menu bar appear , also if I click on close button area, the original close button will appear which i did not draw it in the WM_NCPAINT message process, If I remove the WM_NCCALCSIZE message handle process, everything resume to default , so I believe I must missed something in the WM_NCCALCSIZE message handle process, What else shall I handle in the WM_NCCALCSIZE message ?

a screenshot in app initial state

http://b.picphotos.baidu.com/album/s%3D1600%3Bq%3D90/sign=2343c30edff9d72a1364141be41a1345/d788d43f8794a4c24411401a08f41bd5ad6e39d4.jpg

a screenshot captured after mouse clicked

http://f.picphotos.baidu.com/album/s%3D1000%3Bq%3D90/sign=0234ba391930e924cba498317c385577/bd315c6034a85edf888d59124f540923dd5475f9.jpg

2. the second problem is about the size of border, I recalculate the size of client are in the WM_NCCALCSIZE message  process, I made the border thicker than the windows standard, but the problem appear when the main window maximized , the border not completely hide and the client area not covered whole client area, there still have a gap between client area and screen edge. How can I change the default border size in the WM_NCCALCSIZE?

http://a.picphotos.baidu.com/album/s%3D680%3Bq%3D90/sign=6f45b2a5402309f7e36fae1a42357dce/960a304e251f95caf1c73587cf177f3e670952d4.jpg

Any help will be greatly appreciated!

Below is the source code 

// test20150529.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "resource.h" #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers // Windows Header Files: #include <windows.h> // C RunTime Header Files #include <stdlib.h> #include <malloc.h> #include <memory.h> #include <tchar.h> #include <windowsx.h> #include <winuser.h> #include <uxtheme.h> #include <wingdi.h> #include <comdef.h> #include <gdiplus.h> #define MAX_LOADSTRING 100 // Global Variables: HINSTANCE hInst; // current instance TCHAR szTitle[MAX_LOADSTRING]; // The title bar text TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name using namespace Gdiplus; #pragma comment (lib,"Gdiplus.lib") //#include "Win32MyFw.h" extern HINSTANCE hInst; // current instance INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; } void MainWnd_OnCommand(HWND hWnd, int id, HWND hWndCtl, UINT codeNotify) { switch (id) { case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: FORWARD_WM_COMMAND(hWnd, id, hWndCtl, codeNotify, DefWindowProc); break; } //return 0; } BOOL MainWnd_OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct) { #pragma comment( lib, "UxTheme") SetWindowTheme(hWnd, _T(""), _T("")); return 1; } void MainWnd_OnDestroy(HWND hWnd) { PostQuitMessage(0); } BOOL MainWnd_OnNCActivate(HWND hWnd, BOOL fActive, HWND hWndActDeact, BOOL fMinimized) { return 1; } UINT MainWnd_OnNCCalcSize(HWND hWnd, BOOL fCalcValidRects, NCCALCSIZE_PARAMS * lpcsp) { UINT uRc = 0; int xFrame = 10; int yFrame = 10; int nTHight = 40; RECT rcClientNew;//new client rectangle (in parent coordinates), The first rectangle contains the coordinates of the new client rectangle resulting from the move or resize. RECT rcValidDst; //destination rectangle (in parent coordinates), The second rectangle contains the valid destination rectangle. RECT rcValidSrc; //source rectangle (in parent coordinates)the third rectangle contains the valid source rectangle. if (fCalcValidRects) { CopyRect(&rcValidSrc, &lpcsp->rgrc[1]); CopyRect(&rcValidDst, &lpcsp->rgrc[0]); rcClientNew.left = rcValidDst.left + xFrame; rcClientNew.top = rcValidDst.top + nTHight; rcClientNew.right = rcValidDst.right - xFrame; rcClientNew.bottom = rcValidDst.bottom - yFrame; CopyRect(&lpcsp->rgrc[0], &rcClientNew); CopyRect(&lpcsp->rgrc[1], &rcValidDst); CopyRect(&lpcsp->rgrc[2], &rcValidSrc); return WVR_VALIDRECTS; } else { RECT *rc; rc = (RECT *)lpcsp; rc->left = rc->left + xFrame; rc->top = rc->top + nTHight; rc->right = rc->right - xFrame; rc->bottom = rc->bottom - yFrame; return 0; } } void MainWnd_OnNCPaint(HWND hWnd, HRGN hrgn) { HDC hdc; //hdc= GetDCEx(hWnd, hrgn, DCX_WINDOW | DCX_INTERSECTRGN | 0x10000); hdc = GetWindowDC(hWnd); // Paint into this DC RECT rcWnd; GetWindowRect(hWnd, &rcWnd); OffsetRect(&rcWnd, -rcWnd.left, -rcWnd.top); //Remove Client area RECT ClientRect; GetClientRect(hWnd, &ClientRect); OffsetRect(&ClientRect, 10, 40); ExcludeClipRect(hdc, ClientRect.left, ClientRect.top, ClientRect.right, ClientRect.bottom); Graphics g(hdc); Rect rcNcWnd(0, 0, rcWnd.right - 1, rcWnd.bottom - 1); Pen penFrame(Color(255, 0, 0, 0), 1); g.DrawRectangle(&penFrame, rcNcWnd); Rect rcCaption(rcNcWnd.GetLeft() + 1, rcNcWnd.GetTop() + 1, rcNcWnd.GetRight() - 1, rcNcWnd.GetTop() + 19); SolidBrush BrushCaption(Color(255, 70, 90, 125)); g.FillRectangle(&BrushCaption, rcCaption); DrawIconEx(hdc, 2, 2, (HICON)GetClassLong(hWnd, GCL_HICONSM), 16, 16, 0, 0, DI_NORMAL); ReleaseDC(hWnd, hdc); } void MainWnd_OnNCLButtonDown(HWND hWnd, BOOL fDoubleClick, int x, int y, UINT codeHitTest) { switch (codeHitTest) { case HTCAPTION: case HTSYSMENU: case HTBORDER: case HTBOTTOM: case HTBOTTOM case HTBOTTOMRIGHT: case HT case HTRIGHT: case HT case HTTOP case HTTOPRIGHT: case HTCLOSE: //custom draw FORWARD_WM_NCLBUTTONDOWN(hWnd, fDoubleClick, x, y, codeHitTest, DefWindowProc); break; default: break; } } UINT MainWnd_OnNCHitTest(HWND hWnd, int x, int y) { UINT uRes = HTNOWHERE;//FORWARD_WM_NCHITTEST(hWnd, x, y, DefWindowProc); RECT rcWnd; GetWindowRect(hWnd, &rcWnd); RECT rcBottom; RECT rcBottomLeft; RECT rcBottomRight; RECT rcLeft; RECT rcRight; RECT rcTop; RECT rcTopLeft; RECT rcTopRight; RECT rcCaption; RECT rcSysIcon; RECT rcBtnClose; //Border SetRect(&rcBottom, rcWnd.left + 5, rcWnd.bottom - 5, rcWnd.right - 5, rcWnd.bottom); SetRect(&rcBottomLeft, rcWnd.left, rcWnd.bottom - 5, rcWnd.left + 5, rcWnd.bottom); SetRect(&rcBottomRight, rcWnd.right - 5, rcWnd.bottom - 5, rcWnd.right, rcWnd.bottom); SetRect(&rcLeft, rcWnd.left, rcWnd.top + 5, rcWnd.left + 5, rcWnd.bottom - 5); SetRect(&rcRight, rcWnd.right - 5, rcWnd.top + 5, rcWnd.right, rcWnd.bottom - 5); SetRect(&rcTop, rcWnd.left + 5, rcWnd.top, rcWnd.right - 5, rcWnd.top + 5); SetRect(&rcTopLeft, rcWnd.left, rcWnd.top, rcWnd.left + 5, rcWnd.top + 5); SetRect(&rcTopRight, rcWnd.right - 5, rcWnd.top, rcWnd.right, rcWnd.top + 5); //CaptionBar SetRect(&rcCaption, rcWnd.left + 1, rcWnd.top + 1, rcWnd.right - 1, rcWnd.top + 19); SetRect(&rcSysIcon, rcWnd.left + 2, rcWnd.top + 2, rcWnd.left + 18, rcWnd.top + 18); SetRect(&rcBtnClose, rcWnd.right - 18, rcWnd.top + 2, rcWnd.right - 2, rcWnd.top + 18); POINT pt; pt.x = x; pt.y = y; if (PtInRect(&rcSysIcon, pt)) { return HTSYSMENU; } else if (PtInRect(&rcBtnClose, pt)) { return HTCLOSE; } else if (PtInRect(&rcBottom, pt)) { return HTBOTTOM; } else if (PtInRect(&rcBottomLeft, pt)) { return HTBOTTOMLEFT; } else if (PtInRect(&rcBottomRight, pt)) { return HTBOTTOMRIGHT; } else if (PtInRect(&rcLeft, pt)) { return HTLEFT; } else if (PtInRect(&rcRight, pt)) { return HTRIGHT; } else if (PtInRect(&rcTop, pt)) { return HTTOP; } else if (PtInRect(&rcTopLeft, pt)) { return HTTOPLEFT; } else if (PtInRect(&rcTopRight, pt)) { return HTTOPRIGHT; } else if (PtInRect(&rcCaption, pt)) { return HTCAPTION; } else { return uRes;//DefWindowProc(hWnd, WM_NCHITTEST, NULL, MAKELONG(x, y)); } } void MainWnd_OnPaint(HWND hWnd) { PAINTSTRUCT ps; HDC hdc; hdc = BeginPaint(hWnd, &ps); RECT rc; GetClientRect(hWnd, &rc); Rectangle(hdc, 0, 0, rc.right, rc.bottom); DrawText(hdc, _T("Hello, Windows 8!"), -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER); EndPaint(hWnd, &ps); //return 0; } ////////////////////////////////////////////////////////////////////////// LRESULT CALLBACK MainWnd_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { HANDLE_MSG(hWnd, WM_COMMAND, MainWnd_OnCommand); HANDLE_MSG(hWnd, WM_CREATE, MainWnd_OnCreate); HANDLE_MSG(hWnd, WM_DESTROY, MainWnd_OnDestroy); HANDLE_MSG(hWnd, WM_NCACTIVATE, MainWnd_OnNCActivate);

//remove WM_NCCALCSIZE, everything goes to default HANDLE_MSG(hWnd, WM_NCCALCSIZE, MainWnd_OnNCCalcSize); HANDLE_MSG(hWnd, WM_NCPAINT, MainWnd_OnNCPaint); HANDLE_MSG(hWnd, WM_NCHITTEST, MainWnd_OnNCHitTest); HANDLE_MSG(hWnd, WM_PAINT, MainWnd_OnPaint); default: return DefWindowProc(hWnd, msg, wParam, lParam); } } ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = MainWnd_WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32MYFW)); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wcex.lpszMenuName = MAKEINTRESOURCE(IDC_TEST20150529); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassEx(&wcex); } BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; hInst = hInstance; // Store instance handle in our global variable hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,//^ WS_CAPTION,// &~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU), CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPTSTR lpCmdLine, _In_ int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: Place code here. MSG msg; HACCEL hAccelTable; GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); // Initialize global strings LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_WIN32MYFW, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); // Perform application initialization: if (!InitInstance(hInstance, nCmdShow)) { return FALSE; } hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WIN32MYFW)); // Main message loop: while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } GdiplusShutdown(gdiplusToken); return (int)msg.wParam; }


解决方案

If you want to draw the non-client area your code has to draw everything in it.  From MSDN:

"The system sends a WM_NCPAINT message to the window whenever a part of the nonclient area of the window, such as the title bar, menu bar, or window frame, must be updated. The system may also send other messages to direct a window to update a portion of its client area; for example, when a window becomes active or inactive, it sends the WM_NCACTIVATE message to update its title bar. In general, processing these messages for standard windows is not recommended, because the application must be able to draw all the required parts of the nonclient area for the window. For this reason, most applications pass these messages to DefWindowProc for default processing."

Is your code drawing everything required?



这篇关于如何在WM_NCCALCSIZE中设置菜单位置和边框大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆