C++ Win32,显示带有位图的窗口的最简单方法

发布于 2024-08-21 20:18:27 字数 471 浏览 3 评论 0原文

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

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

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

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

谢谢!

It's only for 'debugging' purposes, so I don't want to spend a lot of time with this, nor it is very important. The program exports the data as a png, jpg, svg, etc... -so it's not a big deal, though it could be good to see the image while it is being generated. Also, the program is going to be used in a Linux server; but I'll limit this 'feature' to the Win version.

I also don't want to use a library, except if it is very, very lightweight (I used CImg for a while, but I wasn't very happy with its speed, so I ended up writing the important functions myself and just using libjpeg and libpng directly).

I have the image in an ARGB format (32bpp), though converting the format won't be a problem at all. I would like to use Win32, creating a window from a function deep inside the code (no known hInstance, etc), and writing the bitmap. Fast and easy, hopefully.

But I don't know the win32api enough. I've seen that the only option to draw (GDI) is trough a HBITMAP object... Any code snippet or example I can rely on? Any consideration I might not overlook? Or maybe -considering my time constrains- should I just forget it?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

蝶舞 2024-08-28 20:18:27

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

如果您有 HBITMAP,那么您可以使用 BitBlt 或 StretchBlt 来绘制它,但是如果您还没有将图像作为 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,仍然可以显示一个对话框,只是需要更多工作。这是一个不同的问题。

The biggest piece of work here is actually registering the window class and writing a minimal window procedure. But if this is debug only code, you can actually skip that part. (I'll come back to that later).

If you have an HBITMAP, then you would use BitBlt or StretchBlt to draw it, but if you don't already have the image as an HBITMAP, then StretchDIBits is probably a better choice since you can use it if you only have a pointer to the bitmap data. You have to pass it a source and destination rectangle, a BITMAPINFOHEADER and a pointer to the raw bitmap data. Something like this

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

So the next part is how do I get a HDC to draw in? Well for Debug code, I often draw directly to the screen. HDC hdc = GetDC(NULL) will get a DC that can draw to the screen, but there are security issues and it doesnt' work the same with Aero in Windows Vista, so the other way is to draw onto a window. If you have a window that you can just draw over, then HDC hdc = GetDC(hwnd) will work.

The advantage of doing it this way is that you don't have to create and show a window, so it's less disruptive of code flow, It's helpful for debugging a specific problem, but not the sort of thing you can leave turned on all of the time.

For a longer term solution, You could create a dialog box and put your bitmap drawing call in the WM_PAINT or WM_ERASEBKGND message handler for the dialog box. But I don't recommend that you show a dialog box from deep inside code that isn't supposed to be doing UI. Showing a window, especially a dialog window will interfere with normal message flow in your application. If you want to use a dialog box for this bitmap viewer, then you want that dialog window to be something that the User shows, and that you just draw onto if it's there.

If you don't have access to an HINSTANCE, it's still possible to show a dialog box, it's just more work. That's sort of a different question.

掀纱窥君容 2024-08-28 20:18:27

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

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

About all you need is a handle to a device context (HDC). To display your data on it:

  1. CreateDibSection to create a DIBSection.
  2. Copy your data to the memory block returned by CreateDibSection.
  3. create a DC compatible with the target DC.
  4. Select the DIBSection into your newly created DC.
  5. BitBlt (or StretchBlt) from your DC to the target DC.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文