【问题标题】:C++ Win32, easiest way to show a window with a bitmapC++ Win32,用位图显示窗口的最简单方法
【发布时间】:2011-01-17 05:09:50
【问题描述】:

这只是为了“调试”的目的,所以我不想花很多时间在这上面,也不是很重要。该程序将数据导出为 png、jpg、svg 等... - 所以这没什么大不了的,尽管在生成图像时看到图像可能会很好。此外,该程序将用于 Linux 服务器;但我会将此“功能”限制为 Win 版本。

我也不想使用库,除非它非常非常轻量级(我使用 CImg 有一段时间,但我对它的速度不太满意,所以我最终自己编写了重要的函数并且直接使用 libjpeg 和 libpng)。

我有 ARGB 格式 (32bpp) 的图像,但转换格式根本不成问题。我想使用 Win32,从代码深处的函数(没有已知的 hInstance 等)创建一个窗口,并编写位图。希望快速简单。

但我对 win32api 的了解还不够。我已经看到绘制(GDI)的唯一选项是通过 HBITMAP 对象...任何代码 sn-p 或我可以依赖的示例?有什么我不能忽视的考虑吗?或者——考虑到我的时间限制——我应该忘记它吗?

谢谢!

【问题讨论】:

    标签: c++ winapi bitmap gdi


    【解决方案1】:

    这里最大的工作实际上是注册窗口类并编写一个最小的窗口过程。但如果这是仅调试代码,您实际上可以跳过该部分。 (我稍后会回到那个)。

    如果你有 HBITMAP,那么你可以使用 BitBltStretchBlt 来绘制它,但如果你还没有图像作为 HBITMAP,那么 StretchDIBits 可能是一个更好的选择,因为你可以如果您只有一个指向位图数据的指针,请使用它。您必须将源矩形和目标矩形、BITMAPINFOHEADER 和指向原始位图数据的指针传递给它。像这样的

    SIZE sBmp = { 100, 200 };
    LPBITMAPINFOHEADER pbi;    // the bitmap header from the file, etc.
    LPVOID             pvBits; // the raw bitmap bits
    
    StretchDIBits (hdc, 0, 0, sBmp.cx, sBmp.cy, 
                   0, 0, sBmp.cx, sBmp.cy,
                   pvBits, pbi, 
                   DIB_RGB_COLORS, 
                   SRCCOPY);
    

    那么下一部分是如何让 HDC 进行绘制?对于调试代码,我经常直接在屏幕上绘制。 HDC hdc = GetDC(NULL) 将获得一个可以绘制到屏幕上的 DC,但是存在安全问题,并且它与 Windows Vista 中的 Aero 不一样,因此另一种方法是绘制到窗口上。如果您有一个可以直接绘制的窗口,那么 HDC hdc = GetDC(hwnd) 将起作用。

    这样做的好处是您不必创建和显示一个窗口,因此它对代码流的破坏性较小,有助于调试特定问题,但不是那种你可以离开的东西一直在。

    对于长期解决方案,您可以创建一个对话框并将位图绘制调用放在对话框的 WM_PAINT 或 WM_ERASEBKGND 消息处理程序中。但我不建议您从不应执行 UI 的深层代码中显示对话框。显示一个窗口,尤其是对话框窗口会干扰应用程序中的正常消息流。如果你想为这个位图查看器使用一个对话框,那么你希望那个对话框窗口是用户显示的东西,如果它在那里,你就可以在上面画画。

    如果您无权访问 HINSTANCE,仍然可以显示一个对话框,这只是更多的工作。这是一个不同的问题。

    【讨论】:

    • 感谢您的回复。好吧,确实,在 Windows 7 aero 中,如果我在屏幕上绘图,它会立即出现和消失。禁用 uxsms 可以更好地工作,但我想我更喜欢在对话框上绘制它,所以我需要另一个问题的答案:D。
    • @huff:这应该是一个新问题。类似“如何创建一个没有资源的简单对话框”。
    • 我会这样做的。我猜我的出路是CreateIndirect,但还是把问题放在这里会很好。
    【解决方案2】:

    您只需要一个设备上下文句柄 (HDC)。要在其上显示您的数据:

    1. CreateDibSection 创建一个 DIBSection。
    2. 将数据复制到 CreateDibSection 返回的内存块中。
    3. 创建一个与目标 DC 兼容的 DC。
    4. 在您新创建的 DC 中选择 DIBSection。
    5. 从您的 DC 到目标 DC 的 BitBlt(或 StretchBlt)。

    【讨论】:

      猜你喜欢
      • 2011-05-20
      • 2011-02-25
      • 2016-05-09
      • 2010-10-25
      • 1970-01-01
      • 1970-01-01
      • 2011-04-28
      • 1970-01-01
      • 2011-09-28
      相关资源
      最近更新 更多