控件美化:自定义圆角边缘和填充效果,并实现鼠标交互特效
控件美化:自定义圆角边缘和填充效果,并实现鼠标交互特效
要对控件进行美化并实现自定义颜色的圆角边缘和填充效果,并且要实现鼠标交互特效而不遮挡控件的文字,你可以封装一个函数来实现。以下是一个示例代码,展示如何在对话框中实现这些效果:
#include <windows.h>
#include <commctrl.h>
#include <gdiplus.h>
#include <vector>
using namespace Gdiplus;
// 存储绘制效果所需的参数
struct CustomControlData {
RECT rect;
bool isHovered;
bool isPressed;
COLORREF borderColor;
COLORREF buttonColor;
CustomControlData(RECT r, COLORREF border, COLORREF button)
: rect(r), isHovered(false), isPressed(false), borderColor(border), buttonColor(button) {}
};
// 全局变量,存储所有控件的绘制效果数据
std::vector<CustomControlData> controlsData;
void DrawCustomControl(HDC hdc, const CustomControlData& data) {
// 绘制背景色
HBRUSH hBrush = CreateSolidBrush(data.buttonColor);
FillRect(hdc, &data.rect, hBrush);
DeleteObject(hBrush);
// 绘制圆角矩形边框
HPEN hPen = CreatePen(PS_SOLID, 2, data.borderColor);
SelectObject(hdc, hPen);
RoundRect(hdc, data.rect.left, data.rect.top, data.rect.right, data.rect.bottom, 10, 10);
DeleteObject(hPen);
}
INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_INITDIALOG: {
// 获取控件句柄并存储绘制数据
HWND hButton = GetDlgItem(hwndDlg, IDOK);
RECT rect;
GetClientRect(hButton, &rect);
CustomControlData data(rect, RGB(255, 0, 0), RGB(0, 255, 0));
controlsData.push_back(data);
return TRUE;
}
case WM_PAINT: {
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwndDlg, &ps);
// 遍历所有控件绘制数据,绘制控件
for (const auto& data : controlsData) {
DrawCustomControl(hdc, data);
}
EndPaint(hwndDlg, &ps);
return TRUE;
}
case WM_MOUSEMOVE: {
POINT pt;
pt.x = GET_X_LPARAM(lParam);
pt.y = GET_Y_LPARAM(lParam);
// 遍历所有控件绘制数据,更新鼠标悬停状态并重绘控件
for (auto& data : controlsData) {
data.isHovered = PtInRect(&data.rect, pt);
}
InvalidateRect(hwndDlg, NULL, FALSE);
return TRUE;
}
case WM_LBUTTONDOWN: {
POINT pt;
pt.x = GET_X_LPARAM(lParam);
pt.y = GET_Y_LPARAM(lParam);
// 遍历所有控件绘制数据,更新鼠标按下状态并重绘控件
for (auto& data : controlsData) {
if (PtInRect(&data.rect, pt)) {
data.isPressed = true;
SetCapture(hwndDlg);
}
}
InvalidateRect(hwndDlg, NULL, FALSE);
return TRUE;
}
case WM_LBUTTONUP: {
// 遍历所有控件绘制数据,更新鼠标按下状态并重绘控件
for (auto& data : controlsData) {
if (data.isPressed) {
data.isPressed = false;
ReleaseCapture();
}
}
InvalidateRect(hwndDlg, NULL, FALSE);
return TRUE;
}
case WM_COMMAND: {
if (LOWORD(wParam) == IDOK && HIWORD(wParam) == BN_CLICKED) {
// 点击了IDOK按钮,执行相应操作
MessageBox(hwndDlg, L'OK Button Clicked!', L'Button Clicked', MB_OK);
return TRUE;
}
break;
}
case WM_CLOSE: {
EndDialog(hwndDlg, 0);
return TRUE;
}
}
return FALSE;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
// 初始化 GDI+
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
// 初始化公共控件
InitCommonControls();
// 创建并显示对话框
DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DialogProc);
// 释放 GDI+
GdiplusShutdown(gdiplusToken);
return 0;
}
在上述代码中,我们定义了一个 CustomControlData 结构体来存储绘制效果的参数,包括控件的矩形边界、鼠标悬停状态、鼠标按下状态以及边框颜色和填充颜色。
在对话框的消息处理函数 DialogProc 中,我们在 WM_INITDIALOG 消息中获取IDOK控件的矩形边界并创建一个 CustomControlData 对象来存储绘制数据。然后,我们在 WM_PAINT 消息中遍历所有的控件绘制数据,并调用 DrawCustomControl 函数来绘制控件。在 WM_MOUSEMOVE、WM_LBUTTONDOWN 和 WM_LBUTTONUP 消息中,我们更新控件的鼠标状态并重绘控件。
最后,我们在 WM_COMMAND 消息中处理IDOK控件的点击事件,并在 DialogProc 函数中添加了关闭对话框的处理。
希望这个示例能帮助到你!如果还有其他问题,请随时提问。
原文地址: https://www.cveoy.top/t/topic/UX7 著作权归作者所有。请勿转载和采集!