【发布时间】:2013-03-18 21:41:36
【问题描述】:
这是我的 WinMain:
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nShowCmd)
{
if(SUCCEEDED(CoInitialize(NULL)))
{
{
Game game;
game.CreateRessources(hInst);
game.ShowMainScreen();
HWND hwnd=game.Getm_hWnd();
HWND* pHWND=&hwnd;
game.pWinsock->Initialize(hwnd);
ShowWindow(game.Getm_hWnd(),SW_MAXIMIZE);
UpdateWindow(game.Getm_hWnd());
MSG msg;
ZeroMemory(&msg,sizeof(MSG));
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
CoUninitialize();
}
return 0;
}
还有我的窗口创建类:
void Game::CreateWindowClass(HINSTANCE hInst)
{
// 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",
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);
}
}
这是游戏::CreateRessources:
void Game::CreateRessources(HINSTANCE hInst)
{
CreateWindowClass(hInst);
pD2DResources=CreateD2DResources(m_hWnd);
pMessageLog=CreateMessageLog();
pWinsock=CreateWinsock();
}
最后,我的 WinProc 在以下几行之后:if(pGame==NULL) MessageBox(NULL,"Pointer pGame 为 NULL","Error",NULL);
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 if(msg==WM_DESTROY)
{
PostQuitMessage(0);
return 0;
}
else
{
Game* pGame = reinterpret_cast<Game*>(static_cast<LONG_PTR>(
::GetWindowLongPtrW(
hWnd,
GWLP_USERDATA
)));
if(pGame==NULL)
MessageBox(NULL,"Pointer pGame is NULL","Error",NULL);
if(pGame->pD2DResources!=NULL)
{
switch(msg)
{
由于某种原因,pGame 为 NULL,因为 MessageBox 弹出。为什么会这样?
编辑:顺便说一句,我正在动态创建一些对象,并且我的游戏对象内的私有指针被分配给这些动态创建的对象。会不会和问题有关?
【问题讨论】:
-
在 if(msg==WM_CREATE) 下面的括号中,以及下面的其他几行。
-
很高兴知道。在 WM_CREATE 之前发送了哪些消息?
-
WM_NCCREATE在WM_CREATE之前发送,但这不是问题,因为this指针与WM_CREATE消息一起发送。我看不到所有代码,但您应该在调用SetWindowLongPtrW后返回TRUE。 -
您可以在这里找到更好的 C++ 应用程序模板:blogs.msdn.com/b/oldnewthing/archive/2005/04/22/410773.aspx。它可以正确获取所有指针内容和窗口创建消息。
-
您是否尝试过使用调试器单步执行您的 WndProc?如果没有,为什么不呢?
标签: c++ windows oop winapi pointers