Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 25.11.2016, 21:56   #1
Aoizora
Заблокирован
 
Регистрация: 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 реализован так, как надо. Я бы хотел реализовать свой так же.
Aoizora вне форума Ответить с цитированием
Старый 25.11.2016, 22:19   #2
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

Начните с wc.hbrBackground = 0;
или с обработки WM_ERASEBKGND
waleri вне форума Ответить с цитированием
Старый 26.11.2016, 05:16   #3
Hailov
Пользователь
 
Регистрация: 08.10.2016
Сообщений: 18
По умолчанию

групбокс ?

Это должно означать что он является родительским по отношению к другим кнопкам.
У Вас не так.
Hailov вне форума Ответить с цитированием
Старый 26.11.2016, 10:32   #4
Aoizora
Заблокирован
 
Регистрация: 11.11.2016
Сообщений: 261
По умолчанию

Цитата:
Сообщение от Hailov Посмотреть сообщение
групбокс ?

Это должно означать что он является родительским по отношению к другим кнопкам.
У Вас не так.
Но когда при создании кнопок я прописывал вместо hWnd хэндл групбокса, все становилось вообще плохо. Групбокс создавал до кнопок и запоминал хэндл.
Aoizora вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Прозрачный фон quadrat Win Api 7 15.02.2012 01:03
Прозрачный градиент - Фон не просто прозрачный, есть градиент - к верху он светлеет DrStrangeLove HTML и CSS 3 26.05.2011 00:44
Прозрачный фон у *.bmp Cerebro Компоненты Delphi 1 14.05.2011 18:35
Прозрачный фон EnemyT2 Общие вопросы Delphi 0 26.04.2010 23:28
Прозрачный фон xakkkkker Мультимедиа в Delphi 10 24.12.2008 09:44