[英]C++ How does Allegro or SDL create window?
Allegro或SDL如何創建Windows的窗口,以及如何自己創建窗口?
我正在嘗試為游戲編寫WinApi包裝器,但是當我看到基本的WinApi模板並想將其包裝到這樣的東西時,我完全迷失了
init();
while()
{
update();
}
exit();
他們使用CreateWindowEx
。 一個非常簡單的WinAPI應用程序可以創建一個窗口,看起來像這樣:
#include <Windows.h>
// If you're using MSVC, this is the easiest HINSTANCE. Other compilers
// get it from WinMain and pass in to constructor.
extern "C" IMAGE_DOS_HEADER __ImageBase;
HINSTANCE hInstance = (HINSTANCE)&__ImageBase;
class Window {
HWND hWnd;
static LRESULT __stdcall WindowProc(
HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
if (Window* ptr = reinterpret_cast<Window*>(GetWindowLongPtr(hWnd, GWLP_USERDATA)))
return ptr->DoMessage(hWnd, message, wParam, lParam);
else
return DefWindowProc(hWnd, message, wParam, lParam);
}
LRESULT DoMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch(msg) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
public:
bool DoMessages() {
MSG msg;
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
// Translate the message and dispatch it to WindowProc()
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (msg.message == WM_QUIT) {
return false;
}
return true;
}
Window() {
WNDCLASSEX wc;
// clear out the window class for use
ZeroMemory(&wc, sizeof(WNDCLASSEX));
// fill in the struct with the needed information
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.lpszClassName = L"WindowClass1";
RegisterClassEx(&wc);
// create the window and use the result as the handle
hWnd = CreateWindowEx(NULL,
L"WindowClass1", // name of the window class
L"Wide::Development", // title of the window
WS_OVERLAPPEDWINDOW, // window style. Always windowed for now.
0, // x-position of the window
0, // y-position of the window
1, // width of the window
1, // height of the window
NULL, // we have no parent window, NULL
NULL, // we aren't using menus, NULL
hInstance, // application handle
NULL);
ShowWindow(hWnd, SW_MAXIMIZE); // Snap our window to the user's desktop res, minus taskbar etc.
SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
SetWindowPos(hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); // Make sure that our WindowLongPtr is updated.
}
};
int main() {
Window window;
while(window.DoMessages()) {
// Do app updates, or sleep() if you're mostly waiting on user input
Sleep(50);
}
// When DoMessages() returns false, the window was destroyed, so return.
}
您可以查找MSDN文檔以獲取有關這些功能的更多信息。 本質上,它所做的就是創建一個非常簡單的最大化的非全屏窗口,注冊輸入,然后在銷毀該窗口時退出應用程序。 您會注意到,我實際上將輸入轉發給了Window對象,因此,所有框架中最基本的都是面向對象的,如果需要,您可以在此處進行繼承,只是不要忘記WindowLongPtr函數使用void *並且類型不安全。
還值得一提的是,在某些編譯器(如MSVC)上,如果您#include <Windows.h>
,他們希望您使用WinMain入口點,而不是main()。
游戲渲染和更新代碼通常比WinAPI復雜得多,而且難度更高,因此我想買一本有關DirectX9.0c或DirectX10的書。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.