C++ GDI+ 绘制自定义控件 - 优化后的代码
C++ GDI+ 绘制自定义控件 - 优化后的代码
上述代码并没有在窗口中绘制自定义控件。为了在窗口中绘制自定义控件,我们可以使用 GDI 或 GDI+ 函数来进行绘制操作。
以下是修改后的示例代码,用于在对话框中绘制自定义控件:
#include <windows.h>
#include <gdiplus.h>
#include "resource.h"
#pragma comment(lib, "gdiplus.lib")
using namespace Gdiplus;
HWND ghwnd = nullptr;
void DrawCustomControl(HDC hdc, COLORREF borderColor = RGB(125, 191, 80), COLORREF buttonColor = RGB(126, 70, 20))
{
RECT rect;
GetClientRect(ghwnd, &rect);
// 创建内存绘图上下文
HDC memDC = CreateCompatibleDC(hdc);
HBITMAP memBitmap = CreateCompatibleBitmap(hdc, rect.right - rect.left, rect.bottom - rect.top);
HBITMAP hOldBitmap = (HBITMAP)SelectObject(memDC, memBitmap);
// 绘制背景色
HBRUSH hBrush = CreateSolidBrush(buttonColor);
FillRect(memDC, &rect, hBrush);
DeleteObject(hBrush);
// 绘制圆角矩形边框
HPEN hPen = CreatePen(PS_SOLID, 2, borderColor);
SelectObject(memDC, hPen);
RoundRect(memDC, rect.left, rect.top, rect.right, rect.bottom, 10, 10);
DeleteObject(hPen);
// 将绘制结果复制到窗口的设备上下文
BitBlt(hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, memDC, 0, 0, SRCCOPY);
// 清理资源
SelectObject(memDC, hOldBitmap);
DeleteObject(memBitmap);
DeleteDC(memDC);
}
INT_PTR CALLBACK DialogProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
ghwnd = hWnd;
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK)
{
HDC hdc = GetDC(ghwnd);
DrawCustomControl(hdc);
ReleaseDC(ghwnd, hdc);
}
break;
case WM_CLOSE:
EndDialog(hWnd, IDCANCEL);
return (INT_PTR)TRUE;
}
return (INT_PTR)FALSE;
}
BOOL InitInstance(HINSTANCE hInstance)
{
ghwnd = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), nullptr, DialogProc);
if (!ghwnd)
{
return FALSE;
}
ShowWindow(ghwnd, SW_SHOW);
UpdateWindow(ghwnd);
MSG msg;
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!IsDialogMessage(ghwnd, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return FALSE;
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = DefWindowProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = nullptr;
wcex.lpszClassName = L"windows";
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_ICON1));
return RegisterClassExW(&wcex);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
// 初始化 GDI+
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, nullptr);
MyRegisterClass(hInstance);
InitInstance(hInstance);
// 释放 GDI+
GdiplusShutdown(gdiplusToken);
return 0;
}
在修改后的代码中,我们在对话框的 WM_COMMAND 消息中添加了对按钮点击的处理。当点击 ID 为 IDOK 的按钮时,将获取窗口的设备上下文(HDC),并在该上下文上调用 DrawCustomControl 函数进行绘制。
请确保在资源文件中正确添加了对话框和按钮的定义,并将 IDOK 的 ID 分配给按钮。
希望这次的回答能够满足你的需求,如果还有其他问题,请随时提问。
原文地址: https://www.cveoy.top/t/topic/UP0 著作权归作者所有。请勿转载和采集!