#pragma comment(lib, "UxTheme") #include <windows.h> #include <uxtheme.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = NULL; wcex.hCursor = (HICON)LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = CreateSolidBrush(RGB(0, 128, 0)); wcex.lpszMenuName = NULL; wcex.lpszClassName = L"window"; wcex.hIconSm = NULL; RegisterClassEx(&wcex); HWND hWnd = CreateWindowEx( NULL, L"window", NULL, WS_OVERLAPPEDWINDOW, 100, 100, 600, 400, NULL, NULL, hInstance, NULL); ShowWindow(hWnd, nCmdShow); MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return static_cast<int>(msg.wParam); } LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_CREATE: SetWindowTheme(hWnd, L"", L""); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; case WM_NCCALCSIZE: { LPNCCALCSIZE_PARAMS ncParams = (LPNCCALCSIZE_PARAMS)lParam; ncParams->rgrc[0].top += 4; ncParams->rgrc[0].left += 4; ncParams->rgrc[0].bottom -= 4; ncParams->rgrc[0].right -= 4; return 0; } case WM_NCPAINT: { RECT rect; GetWindowRect(hWnd, &rect); HRGN region = NULL; if (wParam == NULLREGION) { region = CreateRectRgn(rect.left, rect.top, rect.right, rect.bottom); } else { HRGN copy = CreateRectRgn(0, 0, 0, 0); if (CombineRgn(copy, (HRGN)wParam, NULL, RGN_COPY)) { region = copy; } else { DeleteObject(copy); } } HDC dc = GetDCEx(hWnd, region, DCX_WINDOW | DCX_CACHE | DCX_INTERSECTRGN | DCX_LOCKWINDOWUPDATE); if (!dc && region) { DeleteObject(region); } HPEN pen = CreatePen(PS_INSIDEFRAME, 4, RGB(255, 0, 0)); HGDIOBJ old = SelectObject(dc, pen); int width = rect.right - rect.left; int height = rect.bottom - rect.top; Rectangle(dc, 0, 0, width, height); SelectObject(dc, old); ReleaseDC(hWnd, dc); DeleteObject(pen); return 0; } case WM_NCACTIVATE: RedrawWindow(hWnd, NULL, NULL, RDW_UPDATENOW); return 0; break; } return DefWindowProc(hWnd, uMsg, wParam, lParam); }
或者将WM_NCPAINT内的内容替换成下面的代码,效果一样
#ifndef DCX_USESTYLE #define DCX_USESTYLE 0x00010000 #endif case WM_NCPAINT: { HDC hdc = ::GetDCEx(hWnd, 0, DCX_WINDOW | DCX_USESTYLE); if (hdc) { RECT rcclient; ::GetClientRect(hWnd, &rcclient); RECT rcwin; ::GetWindowRect(hWnd, &rcwin); POINT ptupleft; ptupleft.x = rcwin.left; ptupleft.y = rcwin.top; ::MapWindowPoints(0, hWnd, (LPPOINT)&rcwin, (sizeof(RECT) / sizeof(POINT))); ::OffsetRect(&rcclient, -rcwin.left, -rcwin.top); ::OffsetRect(&rcwin, -rcwin.left, -rcwin.top); HRGN rgntemp = NULL; if (wParam == NULLREGION || wParam == ERROR) { ::ExcludeClipRect(hdc, rcclient.left, rcclient.top, rcclient.right, rcclient.bottom); } else { rgntemp = ::CreateRectRgn(rcclient.left + ptupleft.x, rcclient.top + ptupleft.y, rcclient.right + ptupleft.x, rcclient.bottom + ptupleft.y); if (::CombineRgn(rgntemp, (HRGN)wParam, rgntemp, RGN_DIFF) == NULLREGION) { // nothing to paint } ::OffsetRgn(rgntemp, -ptupleft.x, -ptupleft.y); ::ExtSelectClipRgn(hdc, rgntemp, RGN_AND); } HBRUSH hbrush = ::CreateSolidBrush(RGB(255, 0, 0)); ::FillRect(hdc, &rcwin, hbrush); ::DeleteObject(hbrush); ::ReleaseDC(hWnd, hdc); if (rgntemp != 0) { ::DeleteObject(rgntemp); } } return 0; }