【发布时间】:2021-04-11 05:49:34
【问题描述】:
我正在尝试使用 D2D1 清除使用 CreateWindowEx 创建的窗口的背景,并将代码分成单独的类。这是代码。
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
switch (msg) {
case WM_PAINT:
graphics->BeginDraw();
graphics->EndDraw();
break;
case WM_CREATE:
window->onCreate();
break;
case WM_DESTROY:
window->onDestroy();
::PostQuitMessage(0);
break;
default:
return ::DefWindowProc(hwnd, msg, wparam, lparam);
}
return NULL;
}
^ Window.cpp
bool Graphics::init(HWND windowHandle) {
HRESULT hRes = D2D1CreateFactory(
D2D1_FACTORY_TYPE_SINGLE_THREADED,
&factory
);
if (hRes != S_OK) return false;
RECT wCS;
GetClientRect(windowHandle, &wCS);
hRes = factory->CreateHwndRenderTarget(
D2D1::RenderTargetProperties(),
D2D1::HwndRenderTargetProperties(windowHandle, D2D1::SizeU(wCS.right, wCS.bottom)),
&renderTarget
);
if (hRes != S_OK) return -1;
return true;
}
void Graphics::ClearScreen(float r, float g, float b) {
renderTarget->Clear(D2D1::ColorF(r, g, b));
}
^ Graphics.cpp
void BeginDraw() { renderTarget->BeginDraw(); }
void EndDraw() { renderTarget->EndDraw(); }
^ Graphics.h
我的错误在窗口打开后立即发生,就在它崩溃之前。 BeginDraw() 对此负责,因为从 WM_PAINT 中删除它可以解决问题,但这不是一个可行的选择。
错误:
抛出异常:读取访问冲突。 this 为 nullptr。
在Graphics.h中指定在void BeginDraw() { ... }行。
值得注意的事情(不重要):
过去几天我一直在尝试解决这个问题,但我不知道我阅读的大部分代码是什么意思,所以我为我缺乏知识表示歉意。
我认为问题是 BeginDraw() 在图形初始化之前被调用,但我不知道如何防止这种情况发生。
感谢您的任何建议。
【问题讨论】:
-
但我不确定如何防止这种情况发生。您可以在
Graphics中有一个 bool,在 @987654331 之前初始化为 false @ 被调用,如果为 false 则不调用renderTarget->BeginDraw();或renderTarget->EndDraw(); -
@drescherjm 不幸的是,这不起作用。我还尝试检查
this是否等于nullptr并且在运行时没有导致任何事情发生(没有崩溃也没有背景改变),因此this似乎只是一个空指针。编辑:要指定,仅对BeginDraw进行检查会将问题移至EndDraw。 -
那么您的问题是您在创建窗口后创建了
Graphics对象。 -
我认为您将不得不花一些时间在调试器上。错误不在呈现的代码中。
-
@drescherjm 感谢您的所有建议。您最近的一个结合使用调试器的建议帮助我意识到我的错误。如果您想查看答案,答案在帖子顶部。
标签: c++ direct2d winapp createwindowex