介绍 一段时间前,我与Altera Max Plus II设计简单的电子芯片。 我注意到这个应用程序在主框架背景上绘制公司徽标。 一旦我有了比平时更多的空闲时间,我就想自己去实现它。 本文就是结果:) 实现 所以您可能想知道如何在MDI应用程序的背景窗口上绘制图像。 首先,你必须子类化你想要绘制的窗口。 为此调用GetWindowLong(hMain, GWL_WNDPROC)。 这个函数返回 指向旧窗口程序的指针,我们希望将其存储以备将来使用。这段代码的地方 在CBackgroundImageApp::InitInstance()在显示主框架之前。 隐藏,复制Code
HWND hMain = pMainFrame->GetWindow(GW_CHILD)->GetSafeHwnd(); pfnOldWndProc = (WNDPROC)GetWindowLong(hMain, GWL_WNDPROC); SetWindowLong(hMain, GWL_WNDPROC, (long)pfnNewWndProc);
现在我们有了窗口的子类,但是缺少窗口过程。现在写下来。 窗口程序应该至少处理两个消息才能正常工作: WM_ERASEBKGND弹出式 当Windows需要应用程序时,发送第一个消息 绘制它的背景-我们将使用这个来绘制我们的图像。 第二条消息也很重要,因为当你调整大小时 窗口图像也应该改变其大小,以适应 新窗口的大小。我们的窗口proc看起来像这样: 隐藏,复制Code
LRESULT CALLBACK pfnNewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam,LPARAM lParam) { // local variables goes here switch (uMsg) { case WM_SIZE : // ... case WM_ERASEBKGND : // ... return 1; default : return CallWindowProc(pfnOldWndProc, hwnd, uMsg, wParam, lParam); } }
重要提示 从WM_ERASEBKGND案例中返回1是非常重要的 因为它告诉Windows我们已经擦除了 它没有做什么,否则Windows将擦除这 窗口还是标准背景, 我想这不是我们想要实现的。 其他消息呢? 这里是我们现在使用的存储旧窗口的程序 指针。我们只需调用旧的过程并返回其结果。 所以让我们更接近WM_SIZE和WM_ERASEBKGND的情况。 简单地强制窗口背景重新绘制 通过发送WM_ERASEBKGND给它: 隐藏,复制Code
SendMessage(hwnd, WM_ERASEBKGND, (WPARAM)GetDC(hwnd), 0); return 1;
下面的代码将简单地BitBlt位图。 因为窗口大小通常很少与图像大小相同 BitBlt()成为StretchBlt()。最后它看起来如下: 隐藏,复制Code
hcompdc = CreateCompatibleDC(hdc); SelectObject(hcompdc, hBmp); GetClientRect(hwnd, &rect); if (0 == StretchBlt(hdc, rect.left, rect.top, rect.right, rect.bottom, hcompdc, 0, 0, 1152, 864, SRCCOPY)) MessageBox(hwnd, "error", "while StretchBlt", MB_OK); DeleteDC(hcompdc); return 1;
地点: hdc, hcompdc -设备上下文hBmp -位图句柄 调用DeleteDC()非常重要 因为我们不想引起内存泄漏。 最后指出 这个解决方案的性能很大程度上取决于操作系统, 图形卡安装,并对窗口大小进行调整。 就我而言,Windows 98比Windows 2000更好。 在第二种情况下,重画一幅图像需要很大的时间 更多的时间让用户感觉舒适。 运行在windows98上的应用程序看起来很不错。 我的图形设备是Geforce 2 GTS。如果你有 其他系统或配置的经验,请贴在下面 在文章的讨论区。StretchBlt函数 系统之间也有差异。 Windows 98中使用的一款也更好。 本文转载于:http://www.diyabc.com/frontweb/news5448.html