Пользовательская цветовая форма в диалоговом окне WIN32

Мое диалоговое окно отображает текущий выбранный аудиовход так же, как в Windows Vista:

Менеджер звука

Вот мое диалоговое окно WIN32. На нужное место фигуры указывает стрелка:
Мой Диалог

Какова лучшая стратегия для рисования этой формы. Пользовательский нарисованный элемент управления? GDI?

Обратите внимание, что приложение практически готово (поэтому нет ни WPF, ни Direct2D) и что цвет задан в COLORREF, поэтому нет возможности подготовить список значков на выбор.

\\\\\\\\\\ РЕДАКТИРОВАТЬ [1] \\\\\\\\\\\\\\

Я провел несколько дополнительных расследований. Похоже, GDI был заменен GDI +, который проще в использовании и имеет сглаживание и альфа, которые важны для меня.
Если вы внимательно посмотрите на изображение, которое они используют в Sound Manager, вы увидите это сами:

Аудио разъем крупным планом

Итак, я написал код GDI +, и он работает нормально. То есть изображение является разумным, но я создаю его для каждого растрового изображения с каждым WM_PAINT, что ужасно.
Я не нашел способ (В GDI +), чтобы создать растровое изображение в памяти (Эквивалент CreateCompatibleDC), а затем скопировать его в целевой объект (Эквивалент BitBlt). Я видел примеры, которые смешивают GDI и GDI +. Это правильный путь?

1

Решение

Лучшая стратегия — рисовать с использованием GDI HBITMAP, который будет действовать как буфер, каждый раз, когда цвет меняется, просто воссоздайте этот битовый массив. Затем в WndProc фигуры, когда WM_PAINT элементов управления сделан, просто нарисуйте его:

case WM_PAINT:
PAINTSTRUCT     ps;
HDC             hdc;
BITMAP          bitmap;
HDC             hdcMem;
HGDIOBJ         oldBitmap;

hdc = BeginPaint(hWnd, &ps);

hdcMem = CreateCompatibleDC(hdc);
oldBitmap = SelectObject(hdcMem, hBitmap);

GetObject(hBitmap, sizeof(bitmap), &bitmap);
BitBlt(hdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, hdcMem, 0, 0, SRCCOPY);

SelectObject(hdcMem, oldBitmap);
DeleteDC(hdcMem);

EndPaint(hWnd, &ps);
break;

Для простоты желаемого рисования (кружок внутри окружности) вы можете нарисовать все это в WM_PAINT, но рекомендуется создать буфер, как это предлагается, который будет быстрее и позволит избежать мерцания, а также позволит вам рисовать части, а не целые образ. Для создания буфера используйте: CreateCompatibleBitmap создать память DC:

HDC hDC;
int width = 16;
int height= 16;

HDC     hMemDC = ::CreateCompatibleDC(NULL);
HBITMAP hBmp   = ::CreateCompatibleBitmap(hDC, width, height);
::SelectObject(hMemDC, hBmp);

И рисовать с помощью WINAPI, посмотрите на Win32 GDI Рисование круга

Если вы хотите рисовать из ресурса, в WM_CREATE загрузите растровое изображение:

HBITMAP g_hbmBall = NULL;

case WM_CREATE:
g_hbmBall = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_BALL));
if(g_hbmBall == NULL)
MessageBox(hwnd, "Could not load IDB_BALL!", "Error", MB_OK | MB_ICONEXCLAMATION);
break;

Тогда просто нарисуйте на WM_PAINT:

case WM_PAINT:
{
BITMAP bm;
PAINTSTRUCT ps;

HDC hdc = BeginPaint(hwnd, &ps);

HDC hdcMem = CreateCompatibleDC(hdc);
HBITMAP hbmOld = SelectObject(hdcMem, g_hbmBall);

GetObject(g_hbmBall, sizeof(bm), &bm);

BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);

SelectObject(hdcMem, hbmOld);
DeleteDC(hdcMem);

EndPaint(hwnd, &ps);
}
break;

Просто потому, что это маленький значок, вы можете рисовать все на WM_PAINT WndProc окна … но только для того, чтобы избежать создания другого элемента управления, и потому что это маленький растровый рисунок.

Надеюсь, поможет!

РЕДАКТИРОВАТЬ

Если вы планируете использовать GDI + (хотя вы не интересовались этим … извините). Конечно, вы можете нарисовать растровое изображение, используя GDI +. Все меняется, чтобы рисовать, вам нужно только создать графику и сделать рисунки. Также вы можете загрузить Bitmap и нарисовать его, используя DrawImage, пример взят из MSDN:

Image image(L"Grapes.jpg");
graphics.DrawImage(&image, 60, 10);

Когда вы работаете в WinProc, вы можете создать графику из hDC, а затем рисовать. Не забывайте распоряжаться графикой и не вызывайте базу WinProc.

Справочник по MSDN

2

Другие решения


По вопросам рекламы [email protected]