我想创建一个容器控件,它有一个可选的边框,可以通过编程方式设置颜色和粗细。我还需要圆角,它必须只在C ++ win32中完成 - 没有MFC,ATL,winforms等。控件的目的只是包含其他控件。
我已经做了大量的阅读和实验,但是没有找到任何能够准确展示我尝试做什么的教程。以下代码最接近但失败,因为按钮侵占边框而不是被剪裁。如何剪辑儿童控件,使他们不要在边框上画画?
以下是在VS2015上运行的完整极简主义版本
#include "stdafx.h"
#include "Resource.h"
#include <windowsx.h>
#include <commctrl.h>
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK WndProcPanel(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
int APIENTRY wWinMain(_In_ HINSTANCE hInst, _In_opt_ HINSTANCE hPrevInst, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
WNDCLASSEX wc = {};
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.hInstance = hInst;
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszClassName = _T("main");
RegisterClassEx(&wc);
// Create main window.
HWND MWhwnd = CreateWindowEx(NULL, _T("main"), _T(""), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInst, NULL);
wc.lpfnWndProc = WndProcPanel;
wc.hbrBackground = NULL;
wc.lpszClassName = _T("CPanel");
RegisterClassEx(&wc);
// Create container panel
HWND Panelhwnd = CreateWindowEx(NULL, _T("CPanel"), _T(""), WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 100, 20, 110, 100, MWhwnd, NULL, hInst, NULL);
// Add Button to container panel
CreateWindowEx(NULL, WC_BUTTON, _T("OK"), WS_VISIBLE | WS_CHILD, 0, 0, 50, 24, Panelhwnd, NULL, hInst, NULL);
ShowWindow(MWhwnd, nCmdShow);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
/*--------------------------------------------------------------------------------------------------------------*/
LRESULT CALLBACK WndProcPanel(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_NCPAINT: // here I'm creating the border
{
RECT rect;
GetWindowRect(hwnd, &rect);
OffsetRect(&rect, -rect.left, -rect.top);
HDC hdc = GetWindowDC(hwnd);
HRGN g_hrgnButton = CreateRoundRectRgn(rect.left, rect.top, rect.right, rect.bottom, 40, 40);
FrameRgn(hdc, g_hrgnButton, CreateSolidBrush(RGB(50, 50, 255)), 5, 5);
ReleaseDC(hwnd, hdc);
return 0;
}
case WM_NCCALCSIZE: // here I think I'm setting the client area size.
{
RECT *rc = (RECT*)lParam;
InflateRect(rc, -5, -5);
return 0;
}
break;
case WM_PAINT: // Setting the client area background color
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
RECT rect = ps.rcPaint;
HRGN hrgn = CreateRoundRectRgn(rect.left, rect.top, rect.right, rect.bottom, 40, 40);
SelectObject(hdc, GetStockObject(DC_BRUSH));
SetDCBrushColor(hdc, RGB(0, 255, 0));
PaintRgn(hdc, hrgn);
EndPaint(hwnd, &ps);
}
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
结果是:
如您所见,左上角边框被按钮覆盖。