Заблокирован
Регистрация: 11.11.2016
Сообщений: 261
|
Прозрачный фон кнопки и непрозрачная рамка (реализация groupbox)
Господа, хэлпаните с прозрачностью фона контрола. Сразу показываю код:
Код:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
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);
Rectangle(Item->hDC, Item->rcItem.left, Item->rcItem.top, Item->rcItem.right, Item->rcItem.bottom);
int len = GetWindowTextLength(Item->hwndItem);
LPSTR lpBuff[255];
GetWindowTextA(Item->hwndItem, lpBuff, len + 1);
DrawTextA(Item->hDC, lpBuff, len, &Item->rcItem, DT_CENTER);
}
void DrawGroup(HWND hWnd, DRAWITEMSTRUCT *item)
{
POINT pt;
SIZE size;
TCHAR buf[128];
SelectObject(item->hDC, GetStockObject(DC_PEN));
SetDCPenColor(item->hDC, RGB(0, 200, 0));
//FillRect(item->hDC, &item->rcItem, (HBRUSH)GetStockObject(BLACK_BRUSH));
GetWindowText(item->hwndItem, buf, 128);
GetTextExtentPoint32(item->hDC, buf, lstrlen(buf), &size);
POINT border[] = { { item->rcItem.left + size.cx + 14, item->rcItem.top + size.cy - 1 }, // Starting point
{ item->rcItem.right - 1, item->rcItem.top + size.cy - 1 }, // Top line
{ item->rcItem.right - 1, item->rcItem.bottom - 1 }, // Right line
{ item->rcItem.left, item->rcItem.bottom - 1 }, // Bottom line
{ item->rcItem.left, item->rcItem.top + size.cy }, // Left line
{ item->rcItem.left + 9, item->rcItem.top + size.cy } }; // Short top line
MoveToEx(item->hDC, border[0].x, border[0].y, NULL);
for (int i = 0; i < 6; ++i)
{
LineTo(item->hDC, border[i].x, border[i].y);
}
SetBkMode(item->hDC, TRANSPARENT);
SetTextColor(item->hDC, RGB(0, 200, 0));
TextOut(item->hDC, item->rcItem.left + 11, item->rcItem.top + size.cy / 2, buf, lstrlen(buf));
DeleteObject(SelectObject(item->hDC, GetStockObject(BLACK_PEN)));
}
void HandleVirtualKeyboardMessage(HWND hWnd, WPARAM wParam);
//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);
// Create keyboard controls
{
int startX = 10, startY = 253;
for (int i = 0; i < 16; i++)
{
CreateWindowEx(0, TEXT("BUTTON"),
TEXT(KeyboardButtonNames[i]),
WS_VISIBLE | WS_CHILD | BS_OWNERDRAW,
startX, startY, 20, 20,
hWnd,
(HMENU)KeyboardButtonIDs[i],
GetModuleHandle(NULL),
NULL);
startX += 25;
}
// Clear
CreateWindowEx(0, TEXT("BUTTON"),
TEXT("Clear"),
WS_VISIBLE | WS_CHILD | BS_OWNERDRAW,
startX, startY, 110, 20,
hWnd,
(HMENU)ID_BTN_CLEAR,
GetModuleHandle(NULL),
NULL);
}
// Groupbox
CreateWindowEx(WS_EX_TRANSPARENT, TEXT("BUTTON"), TEXT("Key"), WS_VISIBLE | WS_CHILD | BS_OWNERDRAW,
5, 230, 523, 80, hWnd, (HMENU)ID_KEY_GROUP, GetModuleHandle(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);
break;
case WM_COMMAND:
HandleVirtualKeyboardMessage(hWnd, wParam);
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:
case ID_BTN_ZERO:
case ID_BTN_ONE:
case ID_BTN_TWO:
case ID_BTN_THREE:
case ID_BTN_FOUR:
case ID_BTN_FIVE:
case ID_BTN_SIX:
case ID_BTN_SEVEN:
case ID_BTN_EIGHT:
case ID_BTN_NINE:
case ID_BTN_A:
case ID_BTN_B:
case ID_BTN_C:
case ID_BTN_D:
case ID_BTN_E:
case ID_BTN_F:
case ID_BTN_CLEAR:
DrawButton(dis, GetDlgItem(hWnd, dis->CtlID));
break;
case ID_KEY_GROUP:
DrawGroup(GetDlgItem(hWnd, dis->CtlID), dis);
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 HandleVirtualKeyboardMessage(HWND hWnd, WPARAM wParam)
{
char buffer[255];
char currentText[255];
}
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);
}
}
Комментирую. В программе создается виртуальная клавиатура для ввода 16-ричных цифр. Ее кнопки я хочу сгруппировать самодельным групбоксом. Этот групбокс я создаю как ownerdraw-кнопку и отрисовываю в отдельной процедуре. Но получается так, что этот нарисованный групбокс закрывает собой клавиатуру. Как сделать его область прозрачной? То есть я хочу, чтобы рамка и текст групбокса были видимы, но вся остальная площадь не закрывала собой интерфейс. В самое винде стиль BS_GROUPBOX реализован так, как надо. Я бы хотел реализовать свой так же.
|