首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >LRESULT函数之前的HWND的GetDC()

LRESULT函数之前的HWND的GetDC()
EN

Stack Overflow用户
提问于 2018-07-18 10:00:59
回答 2查看 777关注 0票数 -1

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

代码语言:javascript
复制
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) {
   ...
   }
}

但是,根据这个链接about SetPixel() crashing after a time,我应该将GetDC()移到循环之外。但是,我一定是做错了,因为如果我这么做了.

代码语言:javascript
复制
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);

...
}

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

代码语言:javascript
复制
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)。因此,它可以无限运行,但会在窗口外绘制,并且不能擦除。

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

EN

回答 2

Stack Overflow用户

发布于 2018-07-18 10:27:54

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

您的"LRESULT()循环“也不是一个循环,而是一个由message loop调用的回调函数。

关于您的问题:当您的应用程序接收到WM_PAINT时,它应该绘制它的窗口内容。

票数 1
EN

Stack Overflow用户

发布于 2018-07-19 06:35:09

您的代码设置完全错误。试着这样做:

代码语言:javascript
复制
HDC hmemdc = NULL;
HBITMAP membmp = NULL;
HBITMAP oldbmp = NULL;

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
    switch (message) {
        case WM_CREATE: {
            HDC hdc = GetDC(hWnd);
            membmp = CreateCompatibleBitmap(hdc, width, height);
            memdc = CreateCompatibleDC(hdc);
            oldbmp = (HBITMAP) SelectObject(memdc, membmp);
            ReleaseDC(hWnd, hdc);
            break;
        }

        case WM_DESTROY: {
            SelectObject(memdc, oldbmp);
            DeleteDC(memdc); memdc = NULL;
            DeleteObject(membmp); membmp = NULL;
            break;
        }

        case WM_ERASEBKGND: {
            return 1;
        }

        case WM_PAINT: {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            BitBlt(hdc, 0, 0, width, height, memdc, 0, 0, SRCCOPY);
            EndPaint(hWnd, &ps);
            break;
        }

        ...
    }

    return DefWindowProcc(hWnd, message, wParam, lParam);
}

然后,您可以根据需要简单地将3D图像绘制到hmemdc/membmp中,并在想要向操作系统发出需要用最新位图重新绘制窗口的信号时调用InvalidateRect()

不过,如果您打算在窗口中使用内存位图,则可以考虑使用UpdateLayeredWindow(),并完全摆脱WM_PAINT/WM_ERASEBKGND处理程序。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51392505

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档