C++ WIN32对话框上的自定义颜色形状

C++ WIN32对话框上的自定义颜色形状,c++,winapi,custom-controls,dialog,C++,Winapi,Custom Controls,Dialog,“我的”对话框以声音管理器在Windows Vista中的方式显示当前选定的音频输入: 这是我的WIN32对话框。形状的所需位置用箭头指向: 绘制此形状的最佳策略是什么。自定义绘制控件?GDI 请注意,应用程序实际上已经完成(因此没有WPF或Direct2D),颜色在COLORREF中给出,因此没有选项准备图标列表供选择 \\\\\\\\\\编辑[1]\\\\\\\\\\\\\\ 我做了一些额外的调查。看起来GDI被GDI+取代了,GDI+使用起来更简单,并且具有对我来说很重要的抗锯齿和Al

“我的”对话框以声音管理器在Windows Vista中的方式显示当前选定的音频输入:

这是我的WIN32对话框。形状的所需位置用箭头指向:

绘制此形状的最佳策略是什么。自定义绘制控件?GDI

请注意,应用程序实际上已经完成(因此没有WPF或Direct2D),颜色在COLORREF中给出,因此没有选项准备图标列表供选择

\\\\\\\\\\编辑[1]\\\\\\\\\\\\\\

我做了一些额外的调查。看起来GDI被GDI+取代了,GDI+使用起来更简单,并且具有对我来说很重要的抗锯齿和Alpha。 如果您仔细查看他们在Sound Manager中使用的图像,您会看到:

所以我已经编写了GDI+代码,它工作正常。也就是说,图像是合理的,但我用每幅WM_颜料创建了整个位图,这很难看。
我没有找到在内存中创建位图(相当于CreateCompatibleDC)然后将其复制到目标(相当于BitBlt)的方法(在GDI+)。我见过混合GDI和GDI+的例子。这是正确的方法吗?

最好的策略是使用GDI绘制一个HBITMAP,该HBITMAP将充当缓冲区,每次颜色更改时只需重新创建该位图。然后在形状的WndProc中,当控件的WM_绘制完成时,只需绘制它:

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绘制,请看

如果要从资源中绘制,请在WM_中创建并加载位图:

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_油漆上绘制:

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;
仅仅因为它是一个小图标,你就可以在窗户的WndProc的WM_油漆上画所有的画。。。但是为了避免创建另一个控件,因为它是一个小位图

希望有帮助

编辑

如果你打算使用GDI+(我想你对它不感兴趣……我很抱歉)。当然,您可以使用GDI+绘制位图。所有的东西都会改变,你只需要创建一个图形和绘图。此外,您还可以加载位图并使用“DrawImage”进行绘制,示例取自MSDN:

Image image(L"Grapes.jpg");
graphics.DrawImage(&image, 60, 10);
当您使用WinProc时,您可以从hDC创建图形,然后进行绘制。请记住处理图形,不要调用基本WinProc


您使用哪种语言编程?@ZeroWorks:Unmanaged C++如果使用蒙版位图资源,可以绘制背景,然后在顶部透明地渲染位图。另外,我经常使用HIMAGELIST来完成这项工作,因为它在内部处理所有的透明度。@user1793036请记住,我不选择图像。我需要画一个任意颜色的圆作为参数给我。它确实有帮助。是否可以将此动态位图用于静态控件?我想使用资源文件放置位图。或者创建一个控件,使用它的位置并使控件不可见?哦!使用资源文件更容易,因为所有的工作都是在WM_PAINT中完成的,我想我会创建一个没有文本的简单标签控件,这个标签的WM_P INT将绘制资源。使用自定义控件或WM_PAINT是一样的:只需一次绘制所有控件,以避免闪烁。编辑以绘制资源。是的。。。您可以将此动态位图用于静态控件,因为您可以按所示绘制它和WM_绘制。请参阅我的编辑[1]部分