Окна по умолчанию являются прямоугольниками.Когда вы рисуете их, вы должны нарисовать целый прямоугольник.Тем не менее, есть по крайней мере три способа, которыми владелец может нарисовать кнопку в виде круглого прямоугольника:
Простой способ : закрасить область вне кнопки круглого прямоугольника таким же цветом, что и фонцвет его родителя
Старый школьный путь : используйте SetWindowRgn (...), чтобы кнопка нарисованная владельцем имела область обрезки в форме круглого прямоугольника.Код для этого приведен ниже.Проблема этого метода в том, что нельзя сглаживать границу круглого прямоугольника.
Новый способ : поскольку дочерние окна Windows 8 могут быть созданы с расширенным WS_EX_LAYEREDстиль.Это должно позволить вам просто нарисовать окно в виде круглого прямоугольника;однако, это осложняется тем фактом, что (я думаю) вам нужно включить манифест, который устанавливает поддерживаемую ОС вашего исполняемого файла на Windows 8 и выше, иначе вызов CreateWindowEx (WS_EX_LAYERED, ...) просто потерпит неудачу (по крайней мере, это делает для меня, когда я пытаюсь это сделать).К сожалению, я не могу показать, как добавить манифест на макушку головы.
Ниже приведен очень элементарный код, демонстрирующий путь области окна.Вы можете исправить это, используя GDI + для рисования и настройки сглаженного рисования или перетаскивая растровое изображение вместо рисования вызовами GDI / GDI +.
// RoundRectButton.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "RoundRectButton.h"
#define BTN_ID 101
HINSTANCE g_instance = 0;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
g_instance = hInstance;
MSG msg = { 0 };
WNDCLASS wc = { 0 };
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_BACKGROUND);
wc.lpszClassName = L"owner_draw_btn";
if (!RegisterClass(&wc))
return -1;
if (!CreateWindow(wc.lpszClassName, L"foobar", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 640, 480, 0, 0, hInstance, NULL))
return -1;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT HandleDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam, int corner_wd, int corner_hgt,
COLORREF unclicked_color, COLORREF clicked_color)
{
auto* dis = reinterpret_cast<DRAWITEMSTRUCT*>(lParam);
if (dis->CtlType != ODT_BUTTON)
return 0;
COLORREF fill_color = (dis->itemState & ODS_SELECTED) ? clicked_color : unclicked_color;
auto rect = &dis->rcItem;
//DrawFrameControl(dis->hDC, rect, DFC_BUTTON, style);
HPEN pen = CreatePen(PS_SOLID, 6, RGB(0, 0, 0));
HPEN old_pen = (HPEN) SelectObject(dis->hDC, pen);
HBRUSH brush = CreateSolidBrush(fill_color);
HBRUSH old_brush = (HBRUSH) SelectObject(dis->hDC, brush);
RoundRect(dis->hDC, rect->left, rect->top, rect->right, rect->bottom, corner_wd, corner_hgt);
SelectObject(dis->hDC, old_pen);
SelectObject(dis->hDC, old_brush);
DeleteObject(pen);
DeleteObject(brush);
TCHAR text[512];
auto n = GetWindowText(dis->hwndItem, text, 512);
SetBkMode(dis->hDC, TRANSPARENT);
DrawText(dis->hDC, text, n, rect, DT_SINGLELINE | DT_VCENTER | DT_CENTER);
return 0;
}
HWND CreateRoundRectButton(HWND parent, int x, int y, int wd, int hgt, int corner_wd, int corner_hgt, int id)
{
HWND button = CreateWindow(
L"button", L"foobar",
BS_OWNERDRAW | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS,
x, y, wd, hgt, parent,
(HMENU) id,
g_instance,
0
);
SetWindowRgn(button, CreateRoundRectRgn(0, 0, wd, hgt, corner_wd, corner_hgt), TRUE);
return button;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND button = NULL;
DWORD err;
switch (message)
{
case WM_CREATE:
button = CreateRoundRectButton(hWnd, 15, 15, 150, 35, 15, 15, BTN_ID);
return 0;
case WM_DRAWITEM:
return HandleDrawItem(hWnd, wParam, lParam, 15, 15, RGB(230,230,230), RGB(255,255,255));
case WM_CLOSE:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}