Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
WM#U油漆处理器不';如果不能正常工作,就会出现闪烁效果 导言: 我决定在MS Visual Studio 2008中做一个测试项目,用C++来测试纯Win32中的一个小程序,把位图画成窗口的背景。 问题:_C++_Winapi - Fatal编程技术网

WM#U油漆处理器不';如果不能正常工作,就会出现闪烁效果 导言: 我决定在MS Visual Studio 2008中做一个测试项目,用C++来测试纯Win32中的一个小程序,把位图画成窗口的背景。 问题:

WM#U油漆处理器不';如果不能正常工作,就会出现闪烁效果 导言: 我决定在MS Visual Studio 2008中做一个测试项目,用C++来测试纯Win32中的一个小程序,把位图画成窗口的背景。 问题:,c++,winapi,C++,Winapi,窗口应该有灰色的画笔和一个位图图片在其客户端区域上延伸 在我的WM_PAINT代码中,如果我尝试在没有位图的情况下为窗口绘制灰色画笔,那么一切看起来都很好 如果我只是尝试将位图作为背景,也是一样的 然而,当我将这两个组合起来时,我可以得到一张拉伸的位图图片,位图后面是灰色背景,这就是发生的情况: 位图图片显示为“静止”,但灰色画笔在整个窗口上出现一秒钟,然后完全消失,所以只看到拉伸的位图,然后再次出现,依此类推 它似乎是从上到下绘制的,并且似乎应用程序正在从头再来 这就是我在启动程序时的看法 相

窗口应该有灰色的画笔和一个位图图片在其客户端区域上延伸

在我的
WM_PAINT
代码中,如果我尝试在没有位图的情况下为窗口绘制灰色画笔,那么一切看起来都很好

如果我只是尝试将位图作为背景,也是一样的

然而,当我将这两个组合起来时,我可以得到一张拉伸的位图图片,位图后面是灰色背景,这就是发生的情况:

位图图片显示为“静止”,但灰色画笔在整个窗口上出现一秒钟,然后完全消失,所以只看到拉伸的位图,然后再次出现,依此类推

它似乎是从上到下绘制的,并且似乎应用程序正在从头再来

这就是我在启动程序时的看法

相关信息: 程序是通过选择选项文件->新建,然后从选项中选择Win32 project来完成的

窗口类是自动设置的,下面的成员是这样设置的:

   wcex.style = CS_HREDRAW | CS_VREDRAW;

   wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
   case WM_ERASEBKGND:

        InvalidateRect( hWnd, NULL, TRUE );

        return 1L;
        break;

   case WM_SIZE:

        InvalidateRect( hWnd, NULL, TRUE );

        return 0L;
   case WM_DESTROY:

        DeleteObject( bmp );

        PostQuitMessage(0);
        break;
我添加了静态全局变量来存储位图句柄:

   static HBITMAP bmp;
在向导创建的窗口过程中,我使用以下代码对其进行了初始化:

   case WM_CREATE:

        bmp = LoadBitmap( hInst, MAKEINTRESOURCE(IDB_BITMAP1) );

        return 0;

        break;
    case WM_PAINT:
     {

        hdc = BeginPaint(hWnd, &ps);

        RECT r;

        GetClientRect( hWnd, &r );

        // TODO: Add any drawing code here...

            // fill client area with gray brush, just to test

            FillRect( hdc, &r, (HBRUSH)GetStockObject( GRAY_BRUSH ) );

            // memory DC for double buffering

        HDC MemDC = CreateCompatibleDC( hdc );

            // select our bitmap into memory DC

        HBITMAP old = (HBITMAP)SelectObject( MemDC, bmp );

            // get bitmap's width and height so we can stretch it  

        BITMAP b;

        GetObject( bmp, sizeof(BITMAP), &b );

            // stretch our bitmap

        StretchBlt( hdc, 0, 0, r.right - r.left, r.bottom - r.top, 
             MemDC, 0, 0, b.bmWidth, b.bmHeight, SRCCOPY );

            // perform proper cleanup

        SelectObject( MemDC, old );

        DeleteDC(MemDC);


        EndPaint(hWnd, &ps);

     }
     return 0L;
     break;
在向导创建的窗口过程中,我添加了
WM_PAINT
handler,代码如下:

   case WM_CREATE:

        bmp = LoadBitmap( hInst, MAKEINTRESOURCE(IDB_BITMAP1) );

        return 0;

        break;
    case WM_PAINT:
     {

        hdc = BeginPaint(hWnd, &ps);

        RECT r;

        GetClientRect( hWnd, &r );

        // TODO: Add any drawing code here...

            // fill client area with gray brush, just to test

            FillRect( hdc, &r, (HBRUSH)GetStockObject( GRAY_BRUSH ) );

            // memory DC for double buffering

        HDC MemDC = CreateCompatibleDC( hdc );

            // select our bitmap into memory DC

        HBITMAP old = (HBITMAP)SelectObject( MemDC, bmp );

            // get bitmap's width and height so we can stretch it  

        BITMAP b;

        GetObject( bmp, sizeof(BITMAP), &b );

            // stretch our bitmap

        StretchBlt( hdc, 0, 0, r.right - r.left, r.bottom - r.top, 
             MemDC, 0, 0, b.bmWidth, b.bmHeight, SRCCOPY );

            // perform proper cleanup

        SelectObject( MemDC, old );

        DeleteDC(MemDC);


        EndPaint(hWnd, &ps);

     }
     return 0L;
     break;
在调整窗口大小或清除背景时,我也会使客户端区域无效,如下所示:

   wcex.style = CS_HREDRAW | CS_VREDRAW;

   wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
   case WM_ERASEBKGND:

        InvalidateRect( hWnd, NULL, TRUE );

        return 1L;
        break;

   case WM_SIZE:

        InvalidateRect( hWnd, NULL, TRUE );

        return 0L;
   case WM_DESTROY:

        DeleteObject( bmp );

        PostQuitMessage(0);
        break;
位图被销毁如下:

   wcex.style = CS_HREDRAW | CS_VREDRAW;

   wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
   case WM_ERASEBKGND:

        InvalidateRect( hWnd, NULL, TRUE );

        return 1L;
        break;

   case WM_SIZE:

        InvalidateRect( hWnd, NULL, TRUE );

        return 0L;
   case WM_DESTROY:

        DeleteObject( bmp );

        PostQuitMessage(0);
        break;
重要提示:

即使我注释掉
WM_SIZE
WM_ERASEBKGND
的处理程序,效果仍然会出现

我没有太多的双缓冲经验,但这是一件简单的事情

我只是看不出错误,所以我请更有经验和技能的同事帮忙


如果需要额外的源代码,请索取它,我将发布它,但在此之前,我将省略它以保持问题的简短

您不应在
WM_ERASEBKGND
中调用
invalidate
。这将迫使一系列无休止的绘画循环


WM_ERASEBKGND
的工作就是绘制背景,这就是你应该做的一切。如果您的
WM_PAINT
要绘制整个窗口,则无需绘制任何背景。在这种情况下,我认为这是您的场景,您不应该在
WM_ERASEBKGND
中执行任何操作您不应该在
WM_ERASEBKGND
中调用
invalidate
。这将迫使一系列无休止的绘画循环


WM_ERASEBKGND
的工作就是绘制背景,这就是你应该做的一切。如果您的
WM_PAINT
要绘制整个窗口,则无需绘制任何背景。在这种情况下,我认为这是您的场景,您不应该在
WM_-ERASEBKGND
中执行任何操作,不要在
WM_-ERASEBKGND
中调用
invalidate
。你在那里的工作就是抹去背景。它似乎是有效的,如果你确定这是问题所在,发表一个答案,我会接受并投赞成票。非常感谢。问候。不要在
WM_ERASEBKGND
中调用
invalidate
。你在那里的工作就是抹去背景。它似乎是有效的,如果你确定这是问题所在,发表一个答案,我会接受并投赞成票。非常感谢。谢谢你,海夫曼先生,谢谢你的帮助,我很感激。谢谢你,海夫曼先生,谢谢你的帮助,我很感激。当做