C ++ Как Allegro или SDL создает окно? - PullRequest
2 голосов
/ 02 января 2011

Как Allegro или SDL создает окно для Windows и как это сделать самостоятельно?

Я пытаюсь написать оболочку WinApi для игр, но я полностью теряюсь, когда вижу базовый шаблон WinApi и хочу обернуть его в нечто вроде этого

init();
while()
{
   update();
}
exit();

1 Ответ

6 голосов
/ 02 января 2011

Они используют 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...