怎么了?它和指针有关吗
What is wrong? Does it have to do with a pointer?
我的WinMain是这样开始的:
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nShowCmd)
{
if(SUCCEEDED(CoInitialize(NULL)))
{
{
HRESULT hr = S_OK;
Game game;
D2DResources d2DResources;
game.SetPointer(d2DResources);
hr = d2DResources.Initialize(hInst);
我的编译器将执行上面最后显示的行,然后中断未处理的异常。我知道它不会走得更远,因为我在hr = d2DResources.Initialize(hInst)之前和之后添加了一个MessageBox命令,并且只有第一个显示。
所以,D2DResources:: initialize (HINSTANCE)是这样的:
HRESULT D2DResources::Initialize(HINSTANCE hInst)
{
HRESULT hr;
// Create factory
hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &pD2DFactory);
// Create WIC factory
if(SUCCEEDED(hr))
{
hr = CoCreateInstance(
CLSID_WICImagingFactory,
NULL,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&pIWICIF)
);
}
// Create a window class
WNDCLASSEX wClass;
ZeroMemory(&wClass,sizeof(WNDCLASSEX));
wClass.cbClsExtra=NULL;
wClass.cbSize=sizeof(WNDCLASSEX);
wClass.cbWndExtra=NULL;
wClass.hbrBackground=(HBRUSH)COLOR_WINDOW;
wClass.hCursor=LoadCursor(NULL,IDC_ARROW);
wClass.hIcon=NULL;
wClass.hIconSm=NULL;
wClass.hInstance=hInst;
wClass.lpfnWndProc=WinProc;
wClass.lpszClassName="Window Class";
wClass.lpszMenuName=NULL;
wClass.style=CS_HREDRAW|CS_VREDRAW;
if(!RegisterClassEx(&wClass))
{
int nResult=GetLastError();
MessageBox(NULL,"Failed to register window class","Window Class Failed",MB_ICONERROR);
}
m_hWnd=CreateWindowEx(NULL,
"Window Class",
"Game", // Replace with gameName
WS_OVERLAPPEDWINDOW|WS_MAXIMIZE,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInst,
this);
if(!m_hWnd)
{
int nResult=GetLastError();
MessageBox(NULL,"Window class creation failed","Window Class Failed",MB_ICONERROR);
}
RECT rc;
GetClientRect(m_hWnd,&rc);
// Creates render target
if(SUCCEEDED(hr))
{
pD2DFactory->CreateHwndRenderTarget(
D2D1::RenderTargetProperties(),
D2D1::HwndRenderTargetProperties(
m_hWnd,
D2D1::SizeU(
rc.right - rc.left,
rc.bottom - rc.top)),
&pRT);
}
D2D1_SIZE_F pRTSize = pRT->GetSize();
RECT rect = {50, (long)pRTSize.height-(LogLineSize*5), (long)pRTSize.width, (long)pRTSize.height};
logArea = rect;
if(SUCCEEDED(hr))
{
pRT->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF::White),
&pWhiteBrush
);
}
if(SUCCEEDED(hr))
{
hr = DWriteCreateFactory(
DWRITE_FACTORY_TYPE_SHARED,
__uuidof(pWF),
reinterpret_cast<IUnknown**>(&pWF)
);
}
if(SUCCEEDED(hr))
{
hr = pWF->CreateTextFormat(
L"Verdana",
NULL,
DWRITE_FONT_WEIGHT_NORMAL,
DWRITE_FONT_STYLE_NORMAL,
DWRITE_FONT_STRETCH_NORMAL,
14.0f,
L"",
&pTextFormat
);
}
return hr;
}
和重载的Game::SetPointer,在与D2DResources对象一起调用时看起来是这样的:
void Game::SetPointer(D2DResources& p)
{
pD2DResources=&p;
}
pD2DResources是一个D2DResources*。
问题发生在D2DResources::Initialization(HINSTANCE)期间,当一个WM_SIZE消息被发送到我的WinProc。这里有一些我的WinProc:
LRESULT CALLBACK WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if(msg==WM_CREATE)
{
LPCREATESTRUCT pcs = (LPCREATESTRUCT)lParam;
Game* pGame = (Game*)pcs->lpCreateParams;
::SetWindowLongPtrW(
hWnd,
GWLP_USERDATA,
PtrToUlong(pGame)
);
}
else
{
Game* pGame = reinterpret_cast<Game*>(static_cast<LONG_PTR>(
::GetWindowLongPtrW(
hWnd,
GWLP_USERDATA
)));
switch(msg)
{
case WM_SIZE:
{
UINT width = LOWORD(lParam);
UINT height = HIWORD(lParam);
pGame->pD2DResources->OnResize(width, height);
}
break;
当OnResize被调用时,问题发生了
void D2DResources::OnResize(UINT width, UINT height)
{
if(pRT)
{
HRESULT hr = pRT->Resize(D2D1::SizeU(width, height));
if(hr!=0) MessageBox(NULL,"Render target could not be resized","ID2D1HwndRenterTarget Error",MB_ICONERROR);
}
}
编译器中断,有一个黄色箭头指向if(pRT) (pRT是一个指向渲染目标的指针)行。
有趣的是,在调试过程中查看autos显示了这一点。
- this 0x00000000 {log=0x00000000 nLogLines=??logArea ={…} ...} D2DResources * const
- log 0x00000000 wchar_t [511]nLogLines CXX0030:错误:表达式无法求值
- logArea{顶级= ? ?底= ? ?左= ? ?= ? ?} tagRECTm_hWnd CXX0017:错误:符号"未找到pD2DFactory CXX0017:错误:没有找到符号"pIWICIF CXX0017:错误:符号"未找到pWF CXX0017:错误:符号"未找到pRT CXX0030:错误:表达式无法求值
pCurrentScreen CXX0017:错误:符号"未找到pWhiteBrush CXX0017:错误:符号"未找到pTextFormat CXX0017:错误:符号"未找到
那么,问题是什么,解决办法是什么?
在调用WinProc时,您在WinMain中声明的D2DResources对象已经超出了作用域,但是您仍然持有指向它的指针。当您通过指针调用方法时,它是针对堆栈中不再指向D2DResources对象的位置执行的(注意——您的MessageBox误导了您——它实际上已经超出了作用域)
解决这个问题最简单的方法是修改D2DResources d2DResources;
在WinMain中到
D2DResources& d2DResources = *(new D2DResources());
,这将把相同的对象放在堆上。
虽然我不会发誓这是你的代码的唯一问题…
你传递错误的指针到你的窗口。您在D2DResources::Initialize
中创建窗口并将this
传递为lpParam
,但在窗口过程中您将其转换为Game*
。
- 不断收到相同的错误...怎么了?C++
- 编译器没有显示错误,但我没有得到任何输出.怎么了?
- qsort 不适用于我的 impl 中的浮点类型。怎么了?
- 一个对象的两个指针.删除了一个指针,对象仍然存在
- 在C++中表现不佳.怎么了?
- 我的程序怎么了?(C )
- 这里怎么了?单位转换器
- 错误:未定义对 .. 的引用.怎么了
- 我试图编写一个代码来查找一个单词是否是回文,但它不起作用。怎么了?
- 我在C++文件中的简单代码块上有 2 个错误。错误 C2059:语法错误:"?"。第二智能感知:预期表达式。怎么了?
- 我的代码怎么了?带有QT的原始输入API
- 指针怎么能有一个字符串作为它的值
- 这两个指针怎么能有相同的值
- 使用 cin.get() 似乎没有读取我期望的字符。怎么了?
- 当其中一个字符串来自cin时,无法比较两个字符串.这里怎么了
- "5"怎么了?纸上一切都很好
- 我的cout怎么了
- 删除char阵列指针触发了一个神秘的断点
- 怎么了?悬空指针?
- 怎么了?它和指针有关吗