我留下了一些//评论以帮助您解决问题
我有 Main.cpp
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nShowCmd)
{
Game game;
game.Initialize(hInst);
game.MainMenu();
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
游戏.h
#pragma once
#define WIN32_LEAN_AND_MEAN
/*Various includes*/
template<class Interface>
inline void SafeRelease(Interface** ppInterfaceToRelease)
{
if (*ppInterfaceToRelease != NULL)
{
(*ppInterfaceToRelease)->Release();
(*ppInterfaceToRelease) = NULL;
}
}
class Game{
public:
Game();
~Game();
HRESULT Initialize(HINSTANCE);
void MainMenu();
void OnResize(UINT width, UINT height);
void OnRender();
private:
static LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
private:
HWND m_hWnd;
ID2D1Factory* pD2DFactory;
ID2D1HwndRenderTarget* pRT;
};
和游戏.cpp
#include "Game.h"
#include <comdef.h>
Game::Game() :
pD2DFactory(NULL),
pRT(NULL)
{
}
Game::~Game()
{
SafeRelease(&pD2DFactory);
SafeRelease(&pRT);
}
HRESULT Game::Initialize(HINSTANCE hInst)
{
HRESULT hr;
// Create factory
hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &pD2DFactory);
// 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=Game::WinProc;
wClass.lpszClassName="Window Class";
wClass.lpszMenuName=NULL;
wClass.style=CS_HREDRAW|CS_VREDRAW;
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,
NULL);
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);
}
ShowWindow(m_hWnd,SW_MAXIMIZE); //When my program gets there, WinProc gets called with the WM_PAINT message. The problem then happens.
UpdateWindow(m_hWnd);
return hr;
}
void Game::OnRender()
{
// The following code will eventually be deleted. It is left for test purpose only.
HRESULT hr;
RECT rc;
GetClientRect(m_hWnd,&rc); // The error happens when my program gets to this line of code.
ID2D1SolidColorBrush* pBlackBrush = NULL;
pRT->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF::White),
&pBlackBrush);
pRT->BeginDraw();
pRT->DrawRectangle(
D2D1::RectF(
rc.left + 100.0f,
rc.top + 100.0f,
rc.right - 100.0f,
rc.bottom - 100.0f),
pBlackBrush);
hr = pRT->EndDraw();
}
LRESULT Game::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_PAINT:
{
pGame->OnRender();
ValidateRect(hWnd, NULL);
}
break;
case WM_SIZE:
{
UINT width = LOWORD(lParam);
UINT height = HIWORD(lParam);
pGame->OnResize(width, height); //OnResize is called here
}
break;
case WM_DISPLAYCHANGE:
{
InvalidateRect(hWnd, NULL, FALSE);
}
break;
case WM_DESTROY:
{
//SafeRelease(p2D2Factory);
PostQuitMessage(0);
return 0;
}
break;
}
}
return DefWindowProc(hWnd,msg,wParam,lParam);
}
这是我收到的例外:
Arena Clash client.exe 中 0x001f1666 处的未处理异常:0xC0000005:访问冲突读取位置 0x00000000。
我删除了一些代码以使其更易于阅读。发生的事情是我得到一个未处理的异常。由于我不明白的原因, m_hWnd 似乎没有任何价值。
我已经尝试了几个小时找到解决方案。实际上几乎一整天。我真的需要帮助。
实际上,我想要的是在调整大小和类似更改时重绘我的图像。