简体   繁体   English

如何在C ++中的WM_PAINT中调试代码?

[英]How to debug code in WM_PAINT in c++?

I have the following code in the WM_PAINT message handler of the main window : 我在主窗口的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 );


};

I will be painting text on the skin aswell, that's why I am BitBlt ing on memory DC with a memory bitmap, I have tried with straight painting(directly to hdc) as well, but none worked, and I am not sure how to debug it. 我也将在皮肤上绘制文本,这就是为什么我要使用内存位图在内存DC上进行BitBlt操作,我也尝试了直接绘制(直接绘制为hdc),但是没有任何效果,而且我不确定如何调试它。 The only thing I could check was to check the skin against NULL in LoadBitmap function's return value and also in the void BossController::paint ( HWND hwnd, HBITMAP skin ). 我唯一可以检查的是检查外观是否为LoadBitmap函数的返回值以及无效的BossController :: paint(HWND hwnd,HBITMAP skin)中的NULL。 And BitBlt's return value. 还有BitBlt的返回值。

It always shows a rectangle with the background color I chose while creating the window. 它始终显示一个矩形,其背景颜色是我在创建窗口时选择的。 (window is a custom skinned one so, no title bar etc is there. (窗口是自定义外观的窗口,因此没有标题栏等。

Can someone point out the errors if any or the potential pitfalls or maybe how to debug it ? 有人可以指出错误(如果有)或潜在的陷阱,或者如何调试吗?

It looks like nobody ever answered this. 似乎没人回答过这个问题。

First off, I don't know what framework you're using, but there are normally a few checks before one starts painting. 首先,我不知道您使用的是哪种框架,但是在开始绘制之前通常需要进行一些检查。 A typical paint handler begins something like: 一个典型的油漆处理程序开始如下:

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;
}

Second, I don't know what 'skin' is (an HBITMAP, but I don't know anything about how it was created, where it come from, what its dimensions and bit depth are). 其次,我不知道什么是“皮肤”(HBITMAP,但是我不知道它是如何创建的,它来自哪里,它的尺寸和位深是什么)。

Third, your cleanup is incorrect. 第三,您的清理不正确。 Always call SelectObject to restore the previous selected bitmap, pen, brush, etc. Then call DeleteObject on whatever you created. 始终调用SelectObject来还原先前选择的位图,笔,画笔等。然后在创建的任何对象上调用DeleteObject。

As for how to debug, if something's broken in a paint handler, you should always strip it to the bare minimum, verify functionality, and start adding in things until it breaks. 至于调试方法,如果油漆处理程序中发生了某些故障,则应始终将其剥离到最低限度,验证功能,然后开始添加东西,直到发生故障为止。 In this case, I would replace all of your existing code with a simple filled rectangle in a weird color and see if that works. 在这种情况下,我将用一个奇怪的简单填充矩形替换所有现有代码,看看是否可行。 Then I'd do a BitBlt directly from the 'skin' bitmap on top of the funky color, and see if that works. 然后,我将直接从时髦的颜色顶部的“皮肤”位图上执行BitBlt,看看是否可行。

The most common errors with GDI programming are caused by things like using the wrong coordinates (eg Window coordinates instead of Client coordinates, or giving the wrong offset into your source in a BitBlt call), failure to correctly create resources (eg CreateCompatibleDC, then calling CreateCompatibleBitmap using the new DC, which results in a monochrome bitmap), or failure to properly clean up (eg the way you didn't select the old resources before disposing of your newly-created ones). GDI编程中最常见的错误是由于以下原因引起的:使用错误的坐标(例如,使用窗口坐标代替客户端坐标,或者在BitBlt调用中将错误的偏移量输入到源中),无法正确创建资源(例如,CreateCompatibleDC,然后调用使用新的DC的CreateCompatibleBitmap(生成单色位图),或者无法正确清理(例如,在处置新创建的资源之前未选择旧资源的方式)。 It's also common to not even initiate a repaint correctly, such that your WM_PAINT handler isn't even getting hit. 甚至不正确启动重新绘制也是很常见的,这样您的WM_PAINT处理程序甚至都不会受到打击。 The first step is always a breakpoint to make sure your code is even executing! 第一步始终是确保您的代码正在执行的断点!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM