创建GDI矩形图像

时间:2014-04-02 14:24:21

标签: c++ winapi gdi

我一定是做错了什么或错过了什么,因为我真正想要的是将一个矩形渲染成一个位图,这样我就可以在它上面创建CreateWindowEx()了。有谁知道我错过了什么?

HDC hdc = GetDC(hWnd);

// Create Pen and brush for the rectangle
HPEN pn = CreatePen(style, stroke, pen);
HBRUSH br = CreateSolidBrush(brush);

// Create a compatible bitmap and DC from the window DC with the correct dimensions
HDC bm_hdc = CreateCompatibleDC(hdc);
HBITMAP hImage = CreateCompatibleBitmap(bm_hdc, sz.x, sz.y);

// Select the bitmap, pen, brush into the DC
HGDIOBJ bm_obj = SelectObject(bm_hdc, hImage);
HGDIOBJ pn_obj = SelectObject(bm_hdc, pn);
HGDIOBJ br_obj = SelectObject(bm_hdc, br);

// Draw the rectangle into the compatible DC with the bitmap selected
::Rectangle(bm_hdc, xPos, yPos, xPos + xSize, yPos + ySize);

// Restore the old selections
SelectObject(bm_hdc, br_obj);
SelectObject(bm_hdc, pn_obj);
SelectObject(bm_hdc, bm_obj);

// Delete the not needed DC, pen and brush
DeleteDC(bm_hdc);
DeleteObject(br);
DeleteObject(pn);
ReleaseDC(hWnd, hdc);

// Create the window and send a message to set the static image
HWND win = CreateWindow(TEXT("STATIC"), NULL, WS_CHILD | SS_BITMAP | WS_VISIBLE, pos.x, pos.y, sz.x, sz.y, hWnd, NULL, hInst, NULL)));
HGDIOBJ obj = (HGDIOBJ)SendMessage(win, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hImage);

// Delete the old image
if (obj)
    DeleteObject(hImage);

哼哼......但这不起作用......我得到的只是一个完全黑色的区域,而不是我绘制的矩形。有什么想法吗?我是否需要在设备上下文之间创建另一个DC和BitBlt()?

2 个答案:

答案 0 :(得分:2)

尝试将此行HBITMAP hImage = CreateCompatibleBitmap(bm_hdc, sz.x, sz.y);更改为:

HBITMAP hImage = CreateCompatibleBitmap(hdc, sz.x, sz.y);

Paul WattGDI撰写了优秀文章,并使用MsImage32.dll撰写了图像合成。

我正在向您this article提供帮助,因为它解决了您的问题,以下是相关的引号和代码段:

默认情况下,内存DC使用单色1x1像素位图进行初始化。

避免常见错误

在我们离开代码之前,我向你展示了你需要开始跑步的东西,我想确保你安全地拿着这把新剪刀。 不要使用Memory DC来调用CreateCompatibleBitmap。

...
// You may be tempted to do this; DON'T:
HDC     hMemDC = ::CreateCompatibleDC(hDC);
                                     // DON'T DO THIS
                                     //       |
                                     //       V
HBITMAP hBmp   = ::CreateCompatibleBitmap(hMemDC, width, height);
...
// TIP: Try to use the same DC to create
//      the Bitmap which you used to create the memory DC.

请记住关于如何默认情况下使用单色1x1像素位图初始化内存DC的部分?!

至于成员 Raymond Chen 的评论我相信他也是对的,但既然你说你的实际代码是不同的,那么这是我唯一能看到的错误。

希望这有帮助。

最好的问候。

答案 1 :(得分:2)

感谢所有人的帮助,但我自己实际上已经解决了这个问题,这也是一个愚蠢的错误......考虑一下......: -

::Rectangle(bm_hdc, xPos, yPos, xPos + xSize, yPos + ySize);

乍一看没有错,对吧?错误!如果你查看我的代码,我创建一个所需大小的兼容位图来包含我的矩形,并尝试将矩形渲染到这个位图(选择进入DC)。

但是...我在位图中的哪个呈现? xPos和yPos是矩形的窗口位置,但是我没有渲染到Window DC吗?!? d'哦!没错,xPos和yPos都应为0,因为我要渲染成正确大小的位图,并且当显示窗口时xPos和yPos应该包含屏幕坐标!

哇......真是个愚蠢的错误,感谢来自Window而不是来自兼容DC的HDC上的好地方。我确实知道内存DC的深度为1位,但仍然是经典的错误。谢谢大家。