首页 > 解决方案 > LRESULT 函数之前的 HWND 的 GetDC()

问题描述

我正在尝试在不使用外部库的情况下构建具有 3d 渲染功能的软件。我对 GetDC() 和 ReleaseDC() 有点困惑。如果我在 LRESULT() 循环之后编写以下代码,程序会运行几秒钟然后冻结。(我用 BitBlt() 创建了两个 dc 用于双缓冲)

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {

   HDC hdc = GetDC(hWnd);
   HDC memdc = CreateCompatibleDC(hdc);
   HBITMAP membmp = CreateCompatibleBitmap(hdc, width, height);
   SelectObject(memdc, membmp);

   ...
   switch (message) {
   ...
   }
}

但是,根据这个关于 SetPixel() 在一段时间后崩溃的链接,我应该将 GetDC() 移到循环之外。但是,我一定做错了,因为如果我这样做......

HDC hdc = GetDC(hWnd);
HDC memdc = CreateCompatibleDC(hdc);
HBITMAP membmp = CreateCompatibleBitmap(hdc, width, height);


LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
    TCHAR greeting[] = _T("program_name");
    PAINTSTRUCT ps;
    SelectObject(memdc, membmp);

...
}

...我意识到我不能 SelectObject() 在 LRESULT 循环之外。事实上,Visual Studio 甚至不会在 LRESULT 循环之前使用 GetDC(hWnd),因为它是在循环的第一行创建的。因此,可悲的是,我唯一的选择似乎是将 hWnd 替换为 NULL。

HDC hdc = GetDC(NULL);
HDC memdc = CreateCompatibleDC(hdc);
HBITMAP membmp = CreateCompatibleBitmap(hdc, width, height);


LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
    TCHAR greeting[] = _T("program_name");
    PAINTSTRUCT ps;
    SelectObject(memdc, membmp);

...
}

现在我不能再清除窗口了,因为它依赖于 InvalidateRect(hWnd, NULL, TRUE)。所以它无限期地运行,但在窗口之外绘制并且无法擦除。

我是编程新手,如果有人能指出我的方向或让我知道发生了什么,我将不胜感激。:)

标签: c++winapi

解决方案


如果您是编程和 c++ 新手,您应该首先学习该语言的基础知识,而不是从使用 WinAPI 开始。

此外,您的“LRESULT() 循环”不是循环,而是消息循环调用的回调函数。

关于您的问题:您的应用程序应在收到WM_PAINT -消息时绘制其窗口内容。


推荐阅读