【问题标题】:GDI+ problems on windows XPWindows XP 上的 GDI+ 问题
【发布时间】:2012-03-03 20:34:09
【问题描述】:

我正在使用 GDI+ 来呈现登录窗口。在 Windows 7 上一切正常,但是 在 Windows XP(带有所有更新的 SP3)上绝对没有输出。

WM_PAINT 中的代码

PAINTSTRUCT ps;
HDC         hdc = BeginPaint( hwnd, &ps );
Graphics    *graphics= new Graphics( hdc );

if ( graphics->Clear( BACKGROUND_COLOR ) != Ok )
{
    LOGGER << "LoginWindow::Error clearing surface" << endl;
    goto clean;
}

if ( graphics->DrawImage( dialogHeader, 0, 0, dialogHeaderSize.cx, dialogHeaderSize.cy ) != Ok )
{
    LOGGER << "LoginWindow::Error drawing image" << endl;
    goto clean;
}

if ( graphics->DrawRectangle( dialogBorderPen, 0, 0, LOGIN_WINDOW_WIDTH - 1, LOGIN_WINDOW_HEIGHT - 1 ) != Ok )
{
    LOGGER << "LoginWindow::Error drawing rectangle" << endl;
    goto clean;
}

clean:
delete graphics;
EndPaint( hwnd, &ps );

dialogHeader 是一个带有以下代码的 .png 图像:

dialogHeader = Bitmap::FromFile( imagePath );

GDI+ 是这样初始化的:

GdiplusStartupInput gdiplusStartupInput;
Status              gdiplusStatus;
ULONG_PTR           gdiplusToken;

gdiplusStatus = GdiplusStartup( &gdiplusToken, &gdiplusStartupInput, NULL );

if ( gdiplusStatus != Ok )
{
    LOGGER << "Main::Failed to initialize GDI+. ErrorCode=" << gdiplusStatus << endl;
    return 1;
}

一些已知事实:

  • 绘制代码始终成功执行(使用调试器验证 - Visual Studio 2010)
  • 图片加载无误
  • 无论 Windows 主题/aero 是关闭还是打开,都会发生这种情况
  • 当我将 windows XP 上的窗口拖出屏幕然后返回时,图像显示如下:

http://imageshack.us/photo/my-images/851/winxp2.png/

Windows 7 上的输出

http://imageshack.us/photo/my-images/824/win7p.png/

Windows XP 上的输出

http://imageshack.us/photo/my-images/839/winxpu.png/

我希望有人可以提供帮助。谢谢。

【问题讨论】:

  • 您可能会通过关闭 Aero 在 Win7 上重现该问题。从您的 sn-p 中看不到原因。看不到 hdc 的来源。
  • 不管我是否打开了主题/aero,结果总是一样的 :(。哦,hdc 来自 hdc = BeginPaint(hwnd, &ps);
  • GDI+ 是否正确初始化? (可能是Win7在程序加载时自己做的......):XP中的gdiplusStatus是什么?
  • GDI+ 已初始化,gdiplusStatus 正常。
  • 如果添加显式 InvalidateRgn,行为会改变吗?

标签: c++ winapi gdi+


【解决方案1】:

原来它是 WS_EX_COMPOSITED 样式和 GDI+ 自定义绘画的组合。如果我启用此标志,Windows XP 上最初不会绘制任何内容。只有在调整大小后,事情才会开始出现。

经过一些研究,我发现它可能是一个错误。但是有一个解决方法

  1. 在内存中创建一个 DIB 部分 HBITMAP(或者您可以尝试标准 HBITMAP)并将其选择到 HDC 中(查看 CreateCompatibleBitmapCreateCompatibleDC 以及 选择对象)。
  2. 确保创建与客户端窗口大小一致的 HBITMAP。
  3. 现在,调用时使用这个“内存”HDC:

    Graphics graphics (m_hDC); 
    
  4. 当 GDI+ 绘制到内存 HDC 完成后,调用 BitBlt 在 pDC 上绘制图像。

【讨论】:

  • 必须在 WndProc 上调用 ::BeginPaint(),而不是在 OnPaint/OnDraw 中?
猜你喜欢
  • 2011-12-16
  • 2011-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-07
  • 2010-12-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多