none
如何在 WM_NCCALCSIZE 中 设置菜单 和边框 大小 RRS feed

  • 问题

  • 各位好,

    我的问题关于 windows SDK , 我在程序中想重绘 non-client 区 ,并把边框变粗,所以就处理了 WM_NCCALCSIZE消息,但是程序在启动的时候还行,但是只要鼠标点击 标题栏的图标,出现的不是系统菜单,而是菜单栏,同样的问题发生在 关闭按钮区,下面有截图

    启动时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

    但是当我把WM_NCCALCSIZE消息处理函数去掉,一切回复默认状态,菜单栏正确出现在 标题栏下方,所以我想在WM_NCCALCSIZE消息中肯定还有东西要处理,但是在网上没有找到答案。

    还有一个问题是关于边框的, 就算我在WM_NCCALCSIZE消息中缩小了 client 区,看上去边框变宽了,但是当窗口最大化后 client区和屏幕边缘会有留白,所以肯定还有东西要处理,才能真正改变边框

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

    如有相助,十分感谢!!

    // 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);
    		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;
    }



    2015年7月11日 2:42

全部回复

  •  您可以这样试试:Border设置为NONE,用客户区的一块区域来表示非客户区,这样可能比较容易一些,而且在不同的风格主题下应该也能够保持一致。

    Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.

    • 已建议为答案 Shu 2017 2015年7月13日 9:36
    2015年7月12日 12:58
    版主
  • 截图看不到。。。htttp 403 error


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2015年7月13日 9:36
  • 感谢回复,我就是练手,想搞明白non-client area 怎么弄,请问 border 怎么设为none,改window style?如果我只想改变粗细呢?

    谢谢

    2015年7月13日 13:02
  • 截图我可以看到啊,我退出baidu帐号了,也可以看到
    2015年7月13日 13:03