椭圆作为菜单

时间:2015-05-14 20:06:23

标签: c++ winapi gdi dev-c++

我正在为一个窗口创建一个上下文菜单,我希望在一个子菜单中填充椭圆,每个椭圆都有不同的颜色,而不是文本 - 这个子菜单负责选择颜色。我不知道该怎么做......有人知道任何具体的例子吗?我已经在MSDN页面上阅读了所有者绘制的菜单项,但没有关于这个特定任务的例子 - 所以,我不知道该怎么做。后来我尝试更改菜单项的已检查图标 - 但事实证明我的Dev-C ++(在Windows 7下)既不知道SetDCBrushColor也不知道DC_BRUSH,我仍然不知道如何在不加载图像的情况下更改已检查图标一份文件。然后我在程序开头添加了以下几行:

#define _WIN32_IE 0x0600
#define WINVER  0x0700
#define _WIN32_WINNT 0x0700

然后编译器没有抗议,但是,当我尝试以下代码和我选择的任何颜色时,图标总是黑色的:

HWND hwnd = GetDesktopWindow();
HDC hdc = GetDC( hwnd );
HDC hdcMem = CreateCompatibleDC( hdc );
SIZE size = { GetSystemMetrics( SM_CXMENUCHECK ), GetSystemMetrics( SM_CYMENUCHECK ) };
HBITMAP bitmap = CreateCompatibleBitmap( hdcMem, size.cx, size.cy );
HBITMAP bitmapOld = (HBITMAP) SelectObject( hdcMem, bitmap );
PatBlt( hdcMem, 0, 0, size.cx, size.cy, WHITENESS );
HBRUSH brushOld = (HBRUSH) SelectObject( hdcMem, GetStockObject( NULL_BRUSH ) );
Ellipse( hdcMem, 0, 0, size.cx, size.cy);
SetDCBrushColor( hdcMem, RGB(0,0,255) );
SelectObject( hdcMem, GetStockObject( DC_BRUSH ) );
Ellipse( hdcMem, 2, 2, size.cx-2, size.cy-2 );
SelectObject( hdcMem, brushOld );
SelectObject( hdcMem, bitmapOld );
DeleteDC( hdcMem );
ReleaseDC( hwnd, hdc );
SetMenuItemBitmaps( mnu_t, (30*M_MENU_T+25), MF_BYCOMMAND, bitmap, bitmap);// mnu_t and M_MENU_T are my variables

任何人都可以帮助我吗?

1 个答案:

答案 0 :(得分:1)

问题在于:

HBITMAP bitmap = CreateCompatibleBitmap( hdcMem, size.cx, size.cy );

这是一个非常自然而理性的写作陈述,但它并没有做到大多数人期望它做的事情。这是一个常见的错误,可能需要永远弄清楚问题的根源在这里。我知道这是因为我不止一次犯这个错误。

CreateCompatibleBitmap 创建与指定设备上下文(DC)兼容的位图。嗯,确实如此 - 但实际上它更加微妙:它创建了一个与位图兼容的新位图。指定DC。

使用CreateCompatibleDC创建内存DC时,新DC会获得一个1像素宽,1像素高且颜色深度为1位的默认位图。这根本不直观,因为您要求DC与屏幕DC兼容,并且屏幕(几乎可以肯定)具有超过1位的颜色深度。

因此,当您调用CreateCompatibleBitmap时,您将获得一个指定大小的新位图,每个像素使用1位。你可以画它,如果星星对齐,你会看到你绘制的粗略轮廓。但如果星星没有对齐,那么你最终所有的像素都是单一颜色。

当您将每像素1位位图blit到另一个DC时,将使用当前文本前景色和背景色。由于前景文字颜色通常是黑色的,因此您最终会得到一个黑色矩形,而且几乎不知道您出错的地方。

解决方案是在调用CreateCompatibleBitmap时指定屏幕或窗口DC而不是内存DC。这将创建一个新的位图,其颜色深度与屏幕使用的位图相同,这更有用。