1

我在主窗口的 WM_PAINT 消息处理程序中有以下代码:

void BossController::paint ( HWND hwnd, HBITMAP skin )
{


 PAINTSTRUCT ps;
 HDC hdc;



 hdc = BeginPaint ( hwnd, &ps );

     HDC dcSkin = CreateCompatibleDC ( hdc );                               // memory dc for skin

     HDC hMemDc = CreateCompatibleDC ( hdc );                               // memory dc for painting

     HBITMAP hmemBmp = CreateCompatibleBitmap ( hdc, width, height  );      // Create bitmap to draw on

     HBITMAP hOldMemBmp = (HBITMAP)SelectObject ( hMemDc, hmemBmp );        // select memory bitmap in memory dc

     HBITMAP hOldSkinBmp = (HBITMAP)SelectObject ( dcSkin, skin );  //select skin bitmap in skin memory dc


        BitBlt ( hMemDc, 0, 0, width, height, dcSkin, 0, 0, SRCCOPY );      // Paint Skin on Memory DC
        BitBlt ( hdc, 0, 0, width, height, hMemDc, 0, 0, SRCCOPY );         // Paint Skin on Window DC


     DeleteObject ( hOldSkinBmp );
     DeleteObject ( hOldMemBmp );
     DeleteObject(  hmemBmp );
     DeleteDC ( hMemDc );
     DeleteDC ( dcSkin );

 EndPaint ( hwnd, &ps );


};

我也会在皮肤上绘制文本,这就是为什么我使用内存位图在内存 DC 上进行 BitBlt ing,我也尝试过直接绘制(直接到 hdc),但没有奏效,我不知道如何调试它。我唯一能检查的是在 LoadBitmap 函数的返回值和 void BossController::paint (HWND hwnd, HBITMAP skin) 中检查皮肤是否为 NULL。还有BitBlt的返回值。

它总是显示一个带有我在创建窗口时选择的背景颜色的矩形。(窗口是自定义皮肤的,所以没有标题栏等。

有人可以指出错误(如果有的话)或潜在的陷阱,或者如何调试它?

4

1 回答 1

1

好像从来没有人回答过这个问题。

首先,我不知道您使用的是什么框架,但是在开始绘画之前通常会进行一些检查。典型的油漆处理程序开始于:

RECT r;
if (GetUpdateRect(&r) == 0)
{
    // Nothing to paint, exit function.
    return 0;
}

PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);

if (hdc == 0)
{
    // No display device context available, exit function.
    return 0;
}

其次,我不知道“皮肤”是什么(一个 HBITMAP,但我不知道它是如何创建的,它来自哪里,它的尺寸和位深度是多少)。

第三,您的清理不正确。 始终调用 SelectObject 来恢复先前选择的位图、笔、画笔等。然后在您创建的任何内容上调用 DeleteObject。

至于如何调试,如果在绘图处理程序中出现问题,您应该始终将其剥离到最低限度,验证功能,并开始添加东西直到它中断。在这种情况下,我会用一个奇怪颜色的简单填充矩形替换所有现有代码,看看是否可行。然后我会直接从时髦颜色顶部的“皮肤”位图做一个 BitBlt,看看是否有效。

The most common errors with GDI programming are caused by things like using the wrong coordinates (e.g. Window coordinates instead of Client coordinates, or giving the wrong offset into your source in a BitBlt call), failure to correctly create resources (e.g. CreateCompatibleDC, then calling CreateCompatibleBitmap using the new DC, which results in a monochrome bitmap), or failure to properly clean up (e.g. the way you didn't select the old resources before disposing of your newly-created ones). It's also common to not even initiate a repaint correctly, such that your WM_PAINT handler isn't even getting hit. The first step is always a breakpoint to make sure your code is even executing!

于 2013-08-29T02:20:41.557 回答