流程

一般windows平台下win32程序的流程是这样的

st=>start
e=>end
init=>operation: Init
loop=>operation: Message Loop
tick=>operation: Tick();
cond=>condition: Quit?
cleanup=>operation: CleanUp

st->init->loop->tick->cond
cond(yes)->cleanup->e
cond(no)->loop

  • Init 初始化,这里创建全局的管理器,变量,加载配置文件,
  • MessageLoop 消息循环 这里接收,分发,处理window消息 如果收到的消息是关闭应用的消息 , 就要退出循环
  • Tick 这里做每帧都处理的事情.
  • CleanUp 清理 打开的文件句柄,连接的socke端口 都要清理掉

我们可以这样写main函数

int main()
{
    App app;
    app.Run();
    return 0;
}

这样可以利用C++的RALL机制 在app结构体的构造函数里做初始化工作,在其析构函数里做清理工作.而不用担心因为程序中出现的异常而跳过清理阶段. 那么App类怎么写呢

struct IApp
{
    virtual void Run() = 0
};

struct Win32App:public IApp
{
    virtual void Tick() = 0;
    virtual void Run() override
    {
        bool isQuit = false;
        while (!isQuit)
        {
            MSG msg;
            // 主消息循环:
            while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
            {
                if (msg.message == WM_QUIT)
                    isQuit = true;
                // translate keystroke messages into the right format
                TranslateMessage(&msg);

                // send the message to the WindowProc function
                DispatchMessage(&msg);
            }
            Tick();
        }
    }
};

struct GameApp:public Win32App
{
    GameApp()
    {
        //Init
    }
    ~GameApp()
    {
        //CleanUp
    }
    virtual void Tick() override
    {

    }
};

int main()
{
    GameApp app;
    app.Run();
    return 0;
}

我们通过几次继承使代码看起来清晰一些,当我们需要实现一个其他平台上的GameApp类,也可以使GameApp继承自另一个平台的”Win32App”当然你也可以展开直接写在GameApp里面. 现在把代码写到vs工程里面,你可以在这里看到它们 现在调试运行一下会发现 它什么都没有,毕竟我们什么也没做嘛,

要显示一个窗口,可以创建一个窗口的对象,然后在 gameapp的构造函数初始化它, 析构函数清理掉它,

//MainWnd.h

class MainWnd
{
    bool Init();
    void Destroy();
}

MainWnd* GetMainWnd();

//MainWnd.cpp

MainWnd g_MainWnd;

MainWnd* GetMainWnd()
{
    return &g_MainWnd;
}

//gameapp.cpp

#include "mainWnd.h"

struct GameApp:public Win32App
{
    GameApp()
    {
        GetMainWnd()->Init();
    }
    ~GameApp()
    {
        GetMainWnd()->Destroy();
    }
    virtual void Tick() override
    {

    }
};

有同学可能会想用单例来实现主窗口类,也是可以的. 窗口的具体代码没太多可以说的,可以直接在这里看代码.

下一章我们添加d3d11