C++自定义控件绘制:实现圆角按钮、颜色填充及鼠标交互
C++自定义控件绘制:实现圆角按钮、颜色填充及鼠标交互
想要让你的Windows应用程序界面更加美观,自定义控件绘制是必不可少的一环。本文将带你学习如何使用C++代码自定义绘制一个按钮控件,实现圆角边缘、背景填充以及鼠标交互效果。
示例代码cpp#include <windows.h>#include <commctrl.h>#include <uxtheme.h>#include <vsstyle.h>#include <vssym32.h>
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { static HWND button; static RECT buttonRect; static bool isHovered = false; static bool isPressed = false;
switch (msg) { case WM_CREATE: { button = CreateWindowEx(0, WC_BUTTON, L'Custom Button', WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 50, 50, 200, 100, hwnd, NULL, NULL, NULL); GetClientRect(button, &buttonRect); return 0; } case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps);
// 绘制按钮背景 HTHEME hTheme = OpenThemeData(hwnd, VSCLASS_BUTTON); if (hTheme != NULL) { int state = isPressed ? PBS_PRESSED : isHovered ? PBS_HOT : PBS_NORMAL; DrawThemeBackground(hTheme, hdc, BP_PUSHBUTTON, state, &buttonRect, NULL); CloseThemeData(hTheme); }
// 绘制按钮的文字 wchar_t text[256]; GetWindowText(button, text, sizeof(text)/sizeof(wchar_t)); DrawText(hdc, text, -1, &buttonRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
EndPaint(hwnd, &ps); return 0; } case WM_MOUSEMOVE: { POINT pt; pt.x = GET_X_LPARAM(lParam); pt.y = GET_Y_LPARAM(lParam); isHovered = PtInRect(&buttonRect, pt); InvalidateRect(button, NULL, FALSE); // 重绘按钮 return 0; } case WM_LBUTTONDOWN: { isPressed = true; SetCapture(hwnd); InvalidateRect(button, NULL, FALSE); // 重绘按钮 return 0; } case WM_LBUTTONUP: { isPressed = false; ReleaseCapture(); InvalidateRect(button, NULL, FALSE); // 重绘按钮 return 0; } case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, msg, wParam, lParam);}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { InitCommonControls();
WNDCLASSEX wc = {0}; wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; wc.hInstance = hInstance; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wc.lpszClassName = L'WindowClass'; RegisterClassEx(&wc);
HWND hwnd = CreateWindowEx(0, L'WindowClass', L'Custom Control Demo', WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 300, NULL, NULL, hInstance, NULL); ShowWindow(hwnd, nCmdShow);
MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); }
return (int)msg.wParam;}
代码解析
-
创建按钮控件: 在
WM_CREATE消息中,我们使用CreateWindowEx函数创建一个按钮,并使用GetClientRect获取按钮的矩形区域。 -
绘制按钮背景: 在
WM_PAINT消息中,我们使用DrawThemeBackground函数绘制按钮背景。根据鼠标状态选择不同的按钮状态(PBS_NORMAL、PBS_HOT、PBS_PRESSED)。 -
绘制按钮文字: 使用
DrawText函数在按钮矩形区域内居中绘制按钮文字。 -
处理鼠标交互: - 在
WM_MOUSEMOVE消息中,判断鼠标位置是否在按钮区域内,并设置isHovered变量。 - 在WM_LBUTTONDOWN和WM_LBUTTONUP消息中,根据鼠标左键按下和释放状态设置isPressed变量。 - 在每次鼠标状态改变后,调用InvalidateRect函数强制重绘按钮,以显示不同的状态效果。
总结
通过以上步骤,我们成功实现了一个具有自定义外观和交互效果的按钮控件。你可以根据自己的需求修改代码,例如:
- 使用不同的主题函数绘制更复杂的按钮样式- 添加阴影、渐变等效果- 自定义按钮点击时的行为
希望这篇博客能够帮助你掌握C++自定义控件绘制的基础知识,创造出更加美观的应用程序界面!
原文地址: https://www.cveoy.top/t/topic/UUW 著作权归作者所有。请勿转载和采集!