C++ 窗口类注册失败
我正在以Win32应用程序的形式编写游戏的开头。当我在Main.cpp中注册该类时,一切都很好,但现在我正尝试将其移动到一个游戏类,以使代码更易于使用 由于我已将代码移动到游戏类中,窗口类注册失败。这是我的代码,请注意,有些函数是空的,因为我还没有做到这一点 GetLastError()返回87 Main.cppC++ 窗口类注册失败,c++,winapi,C++,Winapi,我正在以Win32应用程序的形式编写游戏的开头。当我在Main.cpp中注册该类时,一切都很好,但现在我正尝试将其移动到一个游戏类,以使代码更易于使用 由于我已将代码移动到游戏类中,窗口类注册失败。这是我的代码,请注意,有些函数是空的,因为我还没有做到这一点 GetLastError()返回87 Main.cpp #include "Main.h" // entry point for the program, see Game for explanation of parameters in
#include "Main.h"
// entry point for the program, see Game for explanation of parameters
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
game = std::unique_ptr<Game>(new Game(hInstance, hPrevInstance, lpCmdLine, nCmdShow));
game->Init();
// main game loop
while(game->IsRunning())
{
game->HandleMessages();
game->Update(0.0f);
game->Render();
}
return EXIT_SUCCESS;
}
#包括“Main.h”
//程序的入口点,参见游戏中的参数说明
int WINAPI WinMain(HINSTANCE HINSTANCE,
HINSTANCE HPPrevenstance,
LPSTR lpCmdLine,
国际展览(nCmdShow)
{
game=std::unique_ptr(新游戏(hInstance、HPPreInstance、lpCmdLine、nCmdShow));
游戏->初始化();
//主游戏循环
同时(游戏->正在运行()
{
游戏->HandleMessages();
游戏->更新(0.0f);
游戏->渲染();
}
返回退出成功;
}
Game.cpp
#include "Game.h"
#include <Windows.h>
LPCWSTR g_szClassName = L"Life Simulator Window Class";
Game::Game(HINSTANCE _hInstance, // handle to an instance of the application
HINSTANCE _hPrevInstance, // handle to previous instance of the application
LPSTR _lpCmdLine, // command line parameters
int _nCmdShow) // controls how the window is show)
{
hInstance = _hInstance;
hPrevInstance = _hPrevInstance;
lpCmdLine = _lpCmdLine;
nCmdShow = _nCmdShow;
return;
}
Game::~Game(void)
{
}
bool
Game::Init()
{
// set paramaters for window class
wc.cbClsExtra = 0; // number of extra bytes to allocate after window class, not needed but showing for verbosity
wc.cbSize = sizeof(WNDCLASSEX); // stores the size of the WNDCLASSEX structure, helping future proof your application in case new fields are added
wc.cbWndExtra = 0; // similar to cbClsExtra, but refers to the window itself rather than the window class
wc.hbrBackground = (HBRUSH) (COLOR_WINDOW); // handle to a background brush, in this case it's simply a colour cast into a brush handle
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // handle to cursor, first paramater is a handle to the instance of the application containing the cursor (not needed in this case), second is the resource identifier
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); // similar to hCursor, but for the application icon instead
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); // as above, but for the smaller version of the icon
wc.hInstance = hInstance; // handle to the instance of the application that contains the window procedure
wc.lpfnWndProc = Game::WndProc; // a pointer to the window procedure
wc.lpszClassName = g_szClassName; // the window class name (see global variables)
wc.lpszMenuName = NULL; // specifies the resource name of the menu, which isn't used in this case
wc.style = CS_HREDRAW | CS_VREDRAW; // style for the window class, which in this case means to redraw if it's affected (i.e. resized or moved) vertically or horizontally
// register the window class
if(!RegisterClassEx(&wc))
{
// this code is executed if the window class fails to register successfully
MessageBox(NULL, // an owner for the message box can be specified here
L"Window Class Registation Failed.", // message to be displayed
L"Fatal Error", // title of the message box
MB_ICONEXCLAMATION | MB_OK); // type of message box, in this case it has an exclamation icon and an OK button
return EXIT_FAILURE; // return EXIT_FAILURE to indicate that the program closed due to a runtime error
}
// create the window
hWnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, // extended window style
g_szClassName, // class of window to be created (this is the window class created earlier)
L"Life Simulator", // title of the window
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // x position of the window, here default values are used
CW_USEDEFAULT, // as above, but for the y position
wndWidth, // width of the window
wndHeight, // height of the window
NULL, // parent window, if it has one
NULL, // handle to the menu for the window
hInstance, // handle to the instance of the application
NULL); // lpParam can be passed on here
if(hWnd == NULL)
{
// this code is executed if the creating the window failed
MessageBox(NULL, // an owner for the message box can be specified here
L"Window Creation Failed.", // message to be displayed
L"Fatal Error", // title of the message box
MB_ICONEXCLAMATION | MB_OK); // type of message box, in this case it has an exclamation icon and an OK button
return EXIT_FAILURE; // return EXIT_FAILURE to indicate that the program closed due to a runtime error
}
ShowWindow(hWnd, // handle to the window to be shown
nCmdShow); // passed on from WinMain, controls how the window should be shown (i.e. minimised or maximised)
UpdateWindow(hWnd); // forces the window the be updated by forcing a WM_PAINT message past the application queue
}
// window procedure for the game
LRESULT CALLBACK
Game::WndProc(HWND hWnd, // handle to the window
UINT msg, // message to be processed
WPARAM wParam, // additional message information
LPARAM lParam) // even more additional message information
{
switch(msg)
{
case WM_CLOSE: // red X has been clicked
DestroyWindow(hWnd); // sends WM_DESTROY to the window
break;
case WM_DESTROY: // some part of the program has requested the window to be destroyed
PostQuitMessage(0); // sends quit message to window
break;
default: // unhandled messages
return DefWindowProc(hWnd, msg, wParam, lParam);// windows will handle any messages that haven't been handled explicitly
}
return 0;
}
void
Game::HandleMessages()
{
while(PeekMessage(&msg, // container for the message
NULL, // when multiple windows are used, you can specify which one here
0, // used to filter messages, not needed here
0, // as above
PM_REMOVE)) // remove messages after they've been processed
{
TranslateMessage(&msg); // turns virtual key messages into character messages
DispatchMessage(&msg); // sends the message on to its window procedure (i.e. WndProc)
}
return;
}
void
Game::Update(float elapsedTime)
{
return;
}
void
Game::Render()
{
return;
}
#包括“Game.h”
#包括
LPCWSTR g_szClassName=L“生命模拟器窗口类”;
Game::Game(HINSTANCE _HINSTANCE,//应用程序实例的句柄
HINSTANCE _hPrevInstance,//应用程序上一个实例的句柄
LPSTR _lpCmdLine,//命令行参数
int _nCmdShow)//控制窗口的显示方式)
{
hInstance=_hInstance;
HPPreInstance=HPPreInstance;
lpCmdLine=_lpCmdLine;
nCmdShow=\u nCmdShow;
返回;
}
游戏::~游戏(无效)
{
}
布尔
游戏::Init()
{
//设置窗口类的参数
wc.cbClsExtra=0;//在窗口类之后要分配的额外字节数,不需要,但显示为详细
wc.cbSize=sizeof(WNDCLASSEX);//存储WNDCLASSEX结构的大小,以便在添加新字段时对应用程序进行验证
wc.cbWndExtra=0;//类似于cbClsExtra,但指的是窗口本身,而不是窗口类
wc.hbrBackground=(HBRUSH)(COLOR_WINDOW);//背景画笔的句柄,在本例中,它只是一个投射到画笔句柄中的颜色
wc.hCursor=LoadCursor(NULL,IDC_箭头);//句柄到游标,第一个参数是包含游标的应用程序实例的句柄(本例中不需要),第二个是资源标识符
wc.hIcon=LoadIcon(NULL,IDI_应用程序);//类似于hCursor,但适用于应用程序图标
wc.hIconSm=LoadIcon(NULL,IDI_应用程序);//如上所述,但适用于图标的较小版本
wc.hInstance=hInstance;//包含窗口过程的应用程序实例的句柄
wc.lpfnWndProc=Game::WndProc;//指向窗口过程的指针
wc.lpszClassName=g_szClassName;//窗口类名称(请参见全局变量)
wc.lpszMenuName=NULL;//指定菜单的资源名称,在本例中不使用该名称
wc.style=CS_HREDRAW | CS_VREDRAW;//窗口类的样式,在本例中,这意味着在垂直或水平方向受影响(即调整大小或移动)时重新绘制
//注册窗口类
如果(!RegisterClassEx(&wc))
{
//如果窗口类未能成功注册,则执行此代码
MessageBox(NULL,//可以在此处指定消息框的所有者
L“窗口类注册失败”,//要显示的消息
L“致命错误”,//消息框的标题
MB|iconclamation | MB|OK);//消息框的类型,在本例中,它有一个感叹号图标和一个OK按钮
return EXIT_FAILURE;//return EXIT_FAILURE指示程序由于运行时错误而关闭
}
//创建窗口
hWnd=CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,//扩展窗口样式
g_szClassName,//要创建的窗口的类(这是前面创建的窗口类)
L“生活模拟器”//窗口标题
WS\u重叠窗口,//窗口样式
CW_usefault,//窗口的x位置,此处使用默认值
CW_usefault,//如上所述,但用于y位置
wndWidth,//窗口的宽度
wndHeight,//窗的高度
NULL,//父窗口(如果有)
NULL,//窗口菜单的句柄
hInstance,//应用程序实例的句柄
NULL);//可以在此处传递lpParam
if(hWnd==NULL)
{
//如果创建窗口失败,则执行此代码
MessageBox(NULL,//可以在此处指定消息框的所有者
L“窗口创建失败”,//要显示的消息
L“致命错误”,//消息框的标题
MB|iconclamation | MB|OK);//消息框的类型,在本例中,它有一个感叹号图标和一个OK按钮
return EXIT_FAILURE;//return EXIT_FAILURE指示程序由于运行时错误而关闭
}
ShowWindow(hWnd,//要显示的窗口的句柄
nCmdShow);
#include <Windows.h>
// global variables
LPCWSTR g_szClassName = L"Life Simulator Window Class"; // the L casts the string to a wide string and it is called g_szClassName by convention, making the code easier to read for others
static const int wndHeight = 800;
static const int wndWidth = 600;
// window procedure for the program
LRESULT CALLBACK WndProc(HWND hWnd, // handle to the window
UINT msg, // message to be processed
WPARAM wParam, // additional message information
LPARAM lParam) // even more additional message information
{
switch(msg)
{
case WM_CLOSE: // red X has been clicked
DestroyWindow(hWnd); // sends WM_DESTROY to the window
break;
case WM_DESTROY: // some part of the program has requested the window to be destroyed
PostQuitMessage(0); // sends quit message to window
break;
default: // unhandled messages
return DefWindowProc(hWnd, msg, wParam, lParam);// windows will handle any messages that haven't been handled explicitly
}
}
// entry point for the program
int WINAPI WinMain(HINSTANCE hInstance, // handle to an instance of the application
HINSTANCE hPrevInstance, // handle to previous instance of the application
LPSTR lpCmdLine, // command line parameters
int nCmdShow) // controls how the window is show
{
// initialise variables
HWND hWnd; // handle to window
WNDCLASSEX wc; // window class container
MSG msg; // window message container
// set paramaters for window class
wc.cbClsExtra = 0; // number of extra bytes to allocate after window class, not needed but showing for verbosity
wc.cbSize = sizeof(WNDCLASSEX); // stores the size of the WNDCLASSEX structure, helping future proof your application in case new fields are added
wc.cbWndExtra = 0; // similar to cbClsExtra, but refers to the window itself rather than the window class
wc.hbrBackground = (HBRUSH) (COLOR_WINDOW); // handle to a background brush, in this case it's simply a colour cast into a brush handle
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // handle to cursor, first paramater is a handle to the instance of the application containing the cursor (not needed in this case), second is the resource identifier
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); // similar to hCursor, but for the application icon instead
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); // as above, but for the smaller version of the icon
wc.hInstance = hInstance; // handle to the instance of the application that contains the window procedure
wc.lpfnWndProc = WndProc; // a pointer to the window procedure
wc.lpszClassName = g_szClassName; // the window class name (see global variables)
wc.lpszMenuName = NULL; // specifies the resource name of the menu, which isn't used in this case
wc.style = CS_HREDRAW | CS_VREDRAW; // style for the window class, which in this case means to redraw if it's affected (i.e. resized or moved) vertically or horizontally
// register the window class
if(!RegisterClassEx(&wc))
{
// this code is executed if the window class fails to register successfully
MessageBox(NULL, // an owner for the message box can be specified here
L"Window Class Registation Failed.", // message to be displayed
L"Fatal Error", // title of the message box
MB_ICONEXCLAMATION | MB_OK); // type of message box, in this case it has an exclamation icon and an OK button
return EXIT_FAILURE; // return EXIT_FAILURE to indicate that the program closed due to a runtime error
}
// create the window
hWnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, // extended window style
g_szClassName, // class of window to be created (this is the window class created earlier)
L"Life Simulator", // title of the window
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // x position of the window, here default values are used
CW_USEDEFAULT, // as above, but for the y position
wndWidth, // width of the window
wndHeight, // height of the window
NULL, // parent window, if it has one
NULL, // handle to the menu for the window
hInstance, // handle to the instance of the application
NULL); // lpParam can be passed on here
if(hWnd == NULL)
{
// this code is executed if the creating the window failed
MessageBox(NULL, // an owner for the message box can be specified here
L"Window Creation Failed.", // message to be displayed
L"Fatal Error", // title of the message box
MB_ICONEXCLAMATION | MB_OK); // type of message box, in this case it has an exclamation icon and an OK button
return EXIT_FAILURE; // return EXIT_FAILURE to indicate that the program closed due to a runtime error
}
ShowWindow(hWnd, // handle to the window to be shown
nCmdShow); // passed on from WinMain, controls how the window should be shown (i.e. minimised or maximised)
UpdateWindow(hWnd); // forces the window the be updated by forcing a WM_PAINT message past the application queue
// message loop
while(true){ // program closes instantly otherwise
while(PeekMessage(&msg, // container for the message
NULL, // when multiple windows are used, you can specify which one here
0, // used to filter messages, not needed here
0, // as above
PM_REMOVE)) // remove messages after they've been processed
{
TranslateMessage(&msg); // turns virtual key messages into character messages
DispatchMessage(&msg); // sends the message on the its window procedure (i.e. WndProc)
}
}
return msg.wParam; // contains the exit code from the last message, most likely WM_QUIT
}
#pragma once
#include <Windows.h>
class Game
{
public:
Game(HINSTANCE hInstance, // handle to an instance of the application
HINSTANCE hPrevInstance, // handle to previous instance of the application
LPSTR lpCmdLine, // command line parameters
int nCmdShow); // controls how the window is show
~Game(void);
bool Init();
bool IsRunning(){return isRunning;}
// window procedure for the game
static LRESULT CALLBACK WndProc(HWND hWnd, // handle to the window
UINT msg, // message to be processed
WPARAM wParam, // additional message information
LPARAM lParam); // even more additional message information
void HandleMessages(); // messages are translated and dispatched here
void Update(float elapsedTime); // game logic
void Render(); // display results
public: // changed to public until I can get it all working
bool isRunning;
HINSTANCE hInstance;
HINSTANCE hPrevInstance;
LPSTR lpCmdLine;
int nCmdShow;
LPCWSTR g_szClassName; // the L casts the string to a wide string and it is called g_szClassName by convention, making the code easier to read for others
static const int wndHeight = 600; // window height
static const int wndWidth = 800; // window width
HWND hWnd; // handle to window
WNDCLASSEX wc; // window class container
MSG msg; // window message container
};