《基于 DirectX11 的 3D 图形程序设计案例教程》学习一 HelloWorld

源程序:

/*************************************************************************
    > File Name: HelloWorld.cpp
    > Author: YLD10
    > Mail: [email protected]
    > Created Time: 2018.5.28 23:31
    > Describe: Win32 Application HelloWorld.
                《基于 DirectX11 的 3D 图形程序设计案例教程》
                2.2 节程序例子 Hello World
 ************************************************************************/

// 这个头文件包含 Win32 API 的基本元素所需要的结构
#include <windows.h>

// 一个窗口的句柄,这是一个全局变量,后面会用到
HWND MainWindowHandle = 0;

/* 
 * 声明初始化窗口的 InitWindowsApp 函数的函数体
 */
bool InitWindowsApp(HINSTANCE instanceHandle, int show);

/*
 * 声明用于封装消息循环的 Run 函数的函数体
 */
int Run();

/*
 * 声明回调函数 WnProc 的函数体
 */
LRESULT CALLBACK WndProc(HWND hWnd,
                         UINT msg,
                         WPARAM wParam,
                         LPARAM lParam);

/*
 * hInstance:是当前实例的句柄,所谓实例就是指应用程序本身
 * hPreInstance:不使用该参数,Win32 该参数始终为 NULL
 * pCmdLine:用于运行程序的命令行参数字符串
 * nShowCmd:指定窗口的显示方式
 */
int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPreInstance,
                   PSTR pCmdLine,
                   int nShowCmd)
{
// 调用窗口初始化函数,如果调用成功则进入消息循环,否则弹出一个对话框
    if (!InitWindowsApp(hInstance, nShowCmd))
    {
        ::MessageBox(0, L"Init - Failed", L"Error", MB_OK);

        return 0;
    }

    return Run();
}

/*
* 声明初始化窗口的 InitWindowsApp 函数的函数体
*/
bool InitWindowsApp(HINSTANCE instanceHandle, int show)
{
    WNDCLASS wc;
    wc.style        = CS_HREDRAW | CS_VREDRAW;
                    // 这就是一个窗口类 WNDCLASS 的对象定义窗口的样式,
                    // 这两个标记表明当窗口的水平或垂直尺寸发生变化时,
                    // 窗口将被重绘
    wc.lpfnWndProc   = WndProc;  // 这里指定回调函数的指针,与上方回调函数同名
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = instanceHandle;  // 当前应用程序实例的句柄,由 WinMain 传入
    wc.hIcon         = ::LoadIcon(0, IDI_APPLICATION);  // 指定图标
    wc.hCursor       = ::LoadCursor(0, IDC_ARROW);      // 指定光标
    wc.hbrBackground = static_cast<HBRUSH>(::GetStockObject(WHITE_BRUSH));
    wc.lpszMenuName  = 0;               // 指定有无菜单,0 为无菜单   
    wc.lpszClassName = L"Hello";        // 指向窗口名的指针

    if (!::RegisterClass(&wc))
    {
        ::MessageBox(0, L"RegisterClass - Failed", 0, 0);

        return false;
    }

    // 这是第一次用到 MainWindowHandle,用户创建窗口
    MainWindowHandle = ::CreateWindow(
                        L"Hello",       // 第一个 “Hello” 必须和 wc.lpszClassName 相同
                        L"Hello",       // 第二个 “Hello” 是窗口的显示名称
                        WS_OVERLAPPEDWINDOW,            // 指定这个窗口时重叠式窗口
                        CW_USEDEFAULT,  // 表示窗口的横坐标为默认值
                        CW_USEDEFAULT,  // 表示窗口的纵坐标为默认值
                        CW_USEDEFAULT,  // 表示窗口的宽为默认值
                        CW_USEDEFAULT,  // 表示窗口的高为默认值
                        0,
                        0,
                        instanceHandle,
                        0);

    // 如果窗口的创建失败 MainWindowHandle 将会为 0,则报错并返回
    if (!MainWindowHandle)
    {
        ::MessageBox(0, L"CreateWindow - Failed", 0, 0);

        return false;
    }

    // 显示窗口,用窗口句柄 MainWindoeHandle 来指定需要显示的窗口
    ::ShowWindow(MainWindowHandle, show);

    //更新窗口,用窗口句柄 MainWindowHandle 来指定需要更新的窗口
    ::UpdateWindow(MainWindowHandle);

    return true;
}

/*
* 声明用于封装消息循环的 Run 函数的函数体
*/
int Run()
{
    MSG msg;
    ::ZeroMemory(&msg, sizeof(msg));    // ZeroMemory 用 0 填充一块内存区域

    // GetMessage() 不断地从消息队列中检索消息,然后填充到 MSG 结构的成员
    while (::GetMessage(&msg, 0, 0, 0))
    {
        ::TranslateMessage(&msg);       // 将消息 msg 的虚拟键转换为字符信息
        ::DispatchMessage(&msg);        // 最终将消息传送到指定的窗口过程中,
                                        // 本程序中就是将消息传给回调函数 WndProc 中
    }

    return msg.wParam;
}

/*
* 声明回调函数 WnProc 的函数体
*/
LRESULT CALLBACK WndProc(HWND windowHandle,
                         UINT msg,
                         WPARAM wParam,
                         LPARAM IParam)
{
    // 根据参数 msg 的键值判断捕捉到的消息的类型
    switch (msg)
    {
    // 如果按下鼠标左键则弹出消息框,这里 WM_LBUTTONDOWN 是鼠标左键的键值
    case WM_LBUTTONDOWN:
        // L"Hello, World" 是消息框中显示的内容
        // L"Hello" 是所在父窗口的指针
        // MB_OK 表示消息框显示 “确定” 按钮
        ::MessageBox(0, L"Hello, World", L"Hello", MB_OK);

        return 0;

    // 如果按下键盘任意一个键
    case WM_KEYDOWN:
        // 如果是 ESC 键则关闭窗口
        if (wParam == VK_ESCAPE)
        {
            ::DestroyWindow(MainWindowHandle);
        }

        return 0;

    // 如果是关闭窗口的消息,则用 PostQuitMessage() 来退出消息循环
    case WM_DESTROY:
        ::PostQuitMessage(0);

        return 0;
    }

    // 用 DefWindowProc 处理一些默认的消息,比如窗口的最大化、最小化、调整尺寸等
    return ::DefWindowProc(windowHandle,
                           msg,
                           wParam,
                           IParam);
}

运行结果:

运行结果

项目工程:https://github.com/YLD10/VisualStudio_Projects/tree/master/DirectX11_3D/HelloWorld

猜你喜欢

转载自blog.csdn.net/yld10/article/details/80503747