我想使用WinAPI制作黑色半透明GUI。我做了一个自定义按钮,但我不能创建自己的组合框。在WM_DRAWITEM
消息处理程序的情况下,甚至没有调用绘制我的groupbox的回调。这个回调包含甚至没有出现的MessageBox调用。
如何使用彩色框和彩色文字绘制组合框?另外,我想让我的分组框位于所有其他控件之下。怎么做?
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
// Main logic goes here...
ShowMainWindow();
}
void RegisterWndClass(WNDPROC Proc, LPCTSTR szName, UINT brBackground)
{
WNDCLASSEX wc;
wc.cbSize = sizeof(wc);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = Proc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = GetModuleHandle(NULL);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = CreateSolidBrush(RGB(0x14, 0x14, 0x14));
wc.lpszMenuName = NULL;
wc.lpszClassName = szName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if (!RegisterClassEx(&wc))
{
MessageBox(NULL, TEXT("Cannot register class"), TEXT("Error"), MB_OK);
}
}
// Draw custom button
void DrawButton(DRAWITEMSTRUCT *Item, HWND hwnd)
{
SelectObject(Item->hDC, CreateFont(16, 0, 0, 0, FW_NORMAL, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "Arial Black"));
FillRect(Item->hDC, &Item->rcItem, CreateSolidBrush(RGB(0x14, 0x14, 0x14)));
SelectObject(Item->hDC, CreateSolidBrush(0));
if (Item->itemState & ODS_SELECTED)
{
SetTextColor(Item->hDC, 0);
SelectObject(Item->hDC, CreateSolidBrush(0xFF00));
SelectObject(Item->hDC, CreatePen(PS_SOLID, 2, 0xFF00));
}
else
{
SetTextColor(Item->hDC, 0x00FF00);
SelectObject(Item->hDC, CreatePen(PS_SOLID, 2, 0x00FF00));
}
SetBkMode(Item->hDC, TRANSPARENT);
RoundRect(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, 20, 20);
int len = GetWindowTextLength(Item->hwndItem);
LPSTR lpBuff[255];
GetWindowTextA(Item->hwndItem, lpBuff, len + 1);
DrawTextA(Item->hDC, lpBuff, len, &Item->rcItem, DT_CENTER);
}
// Trying to draw customgroupbox
void DrawKeyGroup(DRAWITEMSTRUCT *Item, HWND hwnd)
{
SelectObject(Item->hDC, CreateSolidBrush(RGB(0, 255, 0)));
SelectObject(Item->hDC, CreateSolidBrush(0));
SetTextColor(Item->hDC, 0x00FF00);
SelectObject(Item->hDC, CreatePen(PS_SOLID, 2, 0x00FF00));
MessageBox(NULL, "", "", MB_OK);
//SetBkMode(Item->hDC, TRANSPARENT);
RoundRect(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom, 200, 200);
}
//Main windows proc
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hDC;
PAINTSTRUCT ps;
RECT rect;
switch (uMsg)
{
case WM_CREATE: // Init interface
// Text field
CreateWindow(TEXT("EDIT"),
NULL,
WS_VISIBLE | WS_CHILD | ES_LEFT | ES_AUTOHSCROLL,
10, 280, 350, 20,
hWnd,
(HMENU)ID_KEY_FIELD,
NULL,
NULL);
// Button to enter the text
CreateWindowEx(0, TEXT("BUTTON"),
TEXT("Unlock"),
WS_VISIBLE | WS_CHILD | BS_OWNERDRAW,
370, 280, 150, 20,
hWnd,
(HMENU)ID_KEY_ENTER,
GetModuleHandle(NULL),
NULL);
// Groupbox
CreateWindowEx(0, TEXT("BUTTON"),
TEXT("Key"),
WS_VISIBLE | WS_CHILD | BS_GROUPBOX | BS_OWNERDRAW,
5, 262, 523, 47,
hWnd,
(HMENU)ID_KEY_GROUP,
GetModuleHandle(NULL),
NULL);
break;
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rect);
EndPaint(hWnd, &ps);
break;
// Color text field
case WM_CTLCOLOREDIT:
{
HDC hdc = (HDC)wParam;
HWND hwnd = (HWND)lParam;
if (GetDlgCtrlID(hwnd) == ID_KEY_FIELD)
{
SetTextColor(hdc, 0xFF00);
SetBkColor(hdc, RGB(0x29, 0x29, 0x29));
return (LRESULT)CreateSolidBrush(RGB(0x29, 0x29, 0x29));
}
break;
}
// Color statie elements (group box caption)
/*case WM_CTLCOLORSTATIC:
SetTextColor((HDC)wParam, RGB(0x00, 0x8C, 0xBA));
SetBkMode((HDC)wParam, TRANSPARENT);
SetBkColor((HDC)wParam, RGB(0x14, 0x14, 0x14));
return (LRESULT)CreateSolidBrush(GetBkColor((HDC)wParam));*/
// Draw custom controls
case WM_DRAWITEM:
{
DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT*)lParam;
switch (dis->CtlID)
{
case ID_KEY_ENTER:
DrawButton(dis, GetDlgItem(hWnd, dis->CtlID));
break;
case ID_KEY_GROUP:
DrawKeyGroup(dis, GetDlgItem(hWnd, dis->CtlID));
break;
}
}
case WM_SIZE:
break;
case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
void ShowMainWindow(void)
{
HWND hMainWnd;
MSG msg;
RegisterWndClass(WndProc, TEXT("Info"), COLOR_WINDOW);
hMainWnd = CreateWindowEx(WS_EX_LAYERED, TEXT("Info"), TEXT("Info"),
WS_OVERLAPPEDWINDOW | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
CW_USEDEFAULT, 0, 550, 360, (HWND)NULL, (HMENU)NULL,
GetModuleHandle(NULL), NULL);
SetWindowLong(hMainWnd, GWL_EXSTYLE, GetWindowLong(hMainWnd, GWL_EXSTYLE) | WS_EX_LAYERED);
SetLayeredWindowAttributes(hMainWnd, 0, (255 * 70) / 100, LWA_ALPHA);
if (!hMainWnd)
{
MessageBox(NULL, TEXT("Can\'t create main window."), TEXT("Error"), MB_OK);
return;
}
ShowWindow(hMainWnd, SW_SHOW);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}