Win32自定义圆角按钮白色背景及抗锯齿失效问题求助
Win32自定义圆角按钮白色背景问题求助
我通过Win32的BS_OWNERDRAW样式实现了自定义矩形按钮,但在创建圆角按钮时,按钮后方出现白色背景的问题,经大量研究仍未解决,特寻求帮助。
以下是我使用的代码:
#define UNICODE #include <windows.h> #include <gdiplus.h> using namespace Gdiplus; LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // Define window properties variables const wchar_t g_szClassName[] = L"myWindowClass"; WNDCLASSEX wc; HWND hwnd; MSG Msg; // Registering the Window Class wc.cbSize = sizeof(WNDCLASSEX); wc.style = 0; wc.lpfnWndProc = MainWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = g_szClassName; wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if (!RegisterClassEx(&wc)) { MessageBox(NULL, L"Failed to register window class", L"Error", MB_OK); return 1; } // Creating the window HWND hWnd = CreateWindowEx(0, L"myWindowClass", L"New Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 350, NULL, NULL, GetModuleHandle(NULL), NULL); if (hWnd == NULL) { MessageBox(NULL, L"Failed to create window", L"Error", MB_OK); return 1; } // Show the window ShowWindow(hWnd, SW_SHOW); // Message loop while (GetMessage(&Msg, NULL, 0, 0)) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam; } LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { HWND buttonHandle; Gdiplus::GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); switch (uMsg) { case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; case WM_CREATE: { // cretae the button buttonHandle = CreateWindowEx(0, L"BUTTON", L"OK", WS_VISIBLE | WS_CHILD | BS_OWNERDRAW, 50, 50, 200, 100, hwnd, (HMENU)1, NULL, NULL); break; } case WM_PAINT: { // fill the window with a solid color PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); HBRUSH hBrush = CreateSolidBrush(RGB(30, 30, 30)); FillRect(hdc, &ps.rcPaint, hBrush); DeleteObject(hBrush); EndPaint(hwnd, &ps); return 0; } case WM_DRAWITEM: { LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam; // Get button rectangle RECT buttonRect = lpdis->rcItem; // Create Gdiplus::Graphics object from device context Gdiplus::Graphics graphics(lpdis->hDC); graphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias); // Set anti-alias mode for smoother edges // Define button color with alpha channel (transparency) Gdiplus::Color buttonColor = Gdiplus::Color(255, 170, 70, 70); // Create solid brush for button color Gdiplus::SolidBrush brush(buttonColor); int x = buttonRect.left; int y = buttonRect.top; int width = buttonRect.right - buttonRect.left; int height = buttonRect.bottom - buttonRect.top; // Draw a rounded rectangle int cornerRadius = 40; Gdiplus::GraphicsPath path; path.AddArc(x, y, cornerRadius, cornerRadius, 180, 90); path.AddArc(x + width - cornerRadius, y, cornerRadius, cornerRadius, 270, 90); path.AddArc(x + width - cornerRadius, y + height - cornerRadius, cornerRadius, cornerRadius, 0, 90); path.AddArc(x, y + height - cornerRadius, cornerRadius, cornerRadius, 90, 90); path.CloseFigure(); graphics.FillPath(&brush, &path); break; } default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } return 0; }
运行效果:
更新记录
- 更新1:尝试了Remy Lebeau提供的两种解决方案,第一种方法无效;第二种使用
SetLayeredWindowAttributes的方法结果接近预期,但存在瑕疵。 - 更新2:为第一种方法添加
WS_CLIPSIBLINGS后成功解决白色背景问题,但失去了平滑边缘特性;若在第二种方法中去掉SetSmoothingMode,也能解决背景问题,但同样丢失抗锯齿效果。
内容的提问来源于stack exchange,提问作者stepic Game
相关产品推荐
相关产品推荐

