原文:Directx11 教程(2) 基本的windows应用程序框架(2)

     在本教程中,我们把前面一个教程的代码,进行封装。把初始化函数,Run函数,窗口回调函数,ShutdownWindows函数等封装到一个System class中。

    首先我们要在前面建立的solution,myTutorialD3D11中,鼠标右键点击,选择New Project,

 

创建一个名为myTutorialD3D11_1的空工程,在工程中增加main.cpp文件。

main.cpp的代码如下:

#include "SystemClass.h"

//应用程序入口main函数
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pScmdline, int iCmdshow)
    {
    SystemClass* System;
    bool result;

    // 创建一个system对象.
    System = new SystemClass;
    if(!System)
        {
        return 0;
        }

    // 初始化system对象.
    result = System->Initialize();
    if(result)
        {
        System->Run();
        }

    // 关闭以及释放system对象.
    System->Shutdown();
    delete System;
    System = 0;
    return 0;
    }

 

在工程myTutorialD3D11_1上鼠标右键点击,选择Add->Class,创建一个名为SystemClass的类。

 

SystemClass.h的代码如下:

#pragma once
//定义该宏能够减少windows头文件的大小,使编译器不编译一些不必要的文件,加快编译时间
#define WIN32_LEAN_AND_MEAN

#include <windows.h>

const bool FULL_SCREEN = false;
static bool bexit = false;

class SystemClass
    {
    public:
        SystemClass(void);
        SystemClass(const SystemClass &);
        ~SystemClass(void);

        bool Initialize();
        void Shutdown();
        void Run();

        LRESULT CALLBACK MessageHandler(HWND, UINT, WPARAM, LPARAM);
    private:
        bool Frame();
        void InitializeWindows(int&, int&);
        void ShutdownWindows();

        LPCWSTR m_applicationName;
        HINSTANCE m_hinstance;
        HWND m_hwnd;
    };

//定义静态的回调函数以及应用程序句柄
//因为定义窗口类的时候,必须指定窗口回调函数,所以我们用静态的回调函数WndProc
static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

static SystemClass* ApplicationHandle = 0;

SystemClass.cpp代码如下:

#include "SystemClass.h"

SystemClass::SystemClass(void)
    {
    bexit = false;
    }

SystemClass::SystemClass(const SystemClass &)
    {

    }

SystemClass::~SystemClass(void)
    {
    }

//调用窗口初始化函数和其它一些类的初始化函数
//本例子中,只调用初始化窗口函数
bool SystemClass::Initialize()
    {
    int screenWidth = 0, screenHeight = 0;

    // 初始化窗口
    InitializeWindows(screenWidth, screenHeight);

    return true;
    }

void SystemClass::Shutdown()
    {
    //其它类的一些销毁工作
    //...

    // 执行窗口一些销毁工作.
    ShutdownWindows();

    }

//处理消息
void  SystemClass::Run()
    {
    MSG msg;
    bool done, result = 1;

    // 初始化消息结构.
    ZeroMemory(&msg, sizeof(MSG));

   // 循环进行消息处理,如果接收到WM_QUIT.
    done = false;
    while(!done)
        {
        // 处理windows消息.
        if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
            {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
            }

        // 接收到WM_QUIT消息,退出程序.
        if(msg.message == WM_QUIT)
            {
            done = true;
            }
        else
            {
            result = bexit; //如果按了ESC,也退出程序

            //我们的渲染或者其它处理,可以放在这儿
            //....
            //.....
            Frame();
            if(result)
                {
                done = true;
                }
            }

        }

    return;
    }

bool SystemClass::Frame()
    {
    return true;
    }

//初始化窗口类,创建应用程序窗口
void SystemClass::InitializeWindows(int& screenWidth, int& screenHeight)
    {
    WNDCLASSEX wc;
    DEVMODE dmScreenSettings;
    int posX, posY;

    //得到System class对象(应用程序句柄)
    ApplicationHandle = this;

    // 得到应用程序实例句柄
    m_hinstance = GetModuleHandle(NULL);

    // 应用程序名字
    m_applicationName = L"Engine";

   // 设置窗口类参数.
    wc.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    wc.lpfnWndProc   = WndProc; //指定回调函数
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = m_hinstance;
    wc.hIcon         = LoadIcon(NULL, IDI_WINLOGO);
    wc.hIconSm       = wc.hIcon;
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); //默认黑色窗口黑色背景
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = m_applicationName;
    wc.cbSize        = sizeof(WNDCLASSEX);

   // 注册窗口类
    RegisterClassEx(&wc);

    // 得到windows桌面分辨率
    screenWidth  = GetSystemMetrics(SM_CXSCREEN);
    screenHeight = GetSystemMetrics(SM_CYSCREEN);

    // 根据是否全屏设置不同的分辨率.
    if(FULL_SCREEN)
        {
       //全屏模式下,设置窗口大小为windows桌面分辨率.
        memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));
        dmScreenSettings.dmSize       = sizeof(dmScreenSettings);
        dmScreenSettings.dmPelsWidth  = (unsigned long)screenWidth;
        dmScreenSettings.dmPelsHeight = (unsigned long)screenHeight;
        dmScreenSettings.dmBitsPerPel = 32;           
        dmScreenSettings.dmFields     = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;

        // 临时设置显示设备为全屏模式,注意:应用程序退出时候,将恢复系统默认设置。
        ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN);

        // 设置窗口的默认位置为(0,0).
        posX = posY = 0;
        }
    else
        {
        // 窗口模式:800*600.
        screenWidth  = 800;
        screenHeight = 600;

        // 窗口位置,posX, posY窗口左上角坐标
        posX = (GetSystemMetrics(SM_CXSCREEN) - screenWidth)  / 2;
        posY = (GetSystemMetrics(SM_CYSCREEN) - screenHeight) / 2;
        }

    // 全屏和窗口使用不同的参数.
    if( FULL_SCREEN)
        {
        m_hwnd = CreateWindowEx(WS_EX_APPWINDOW, m_applicationName, m_applicationName,
            WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_POPUP,
            posX, posY, screenWidth, screenHeight, NULL, NULL, m_hinstance, NULL);
        }
    else
        {
        m_hwnd = CreateWindowEx(WS_EX_APPWINDOW, m_applicationName, m_applicationName,
            WS_OVERLAPPEDWINDOW,
            posX, posY, screenWidth, screenHeight, NULL, NULL, m_hinstance, NULL);
        }

    // 显示窗口并设置其为焦点.
    ShowWindow(m_hwnd, SW_SHOW);
    SetForegroundWindow(m_hwnd);
    SetFocus(m_hwnd);

    // 隐藏鼠标.
    //ShowCursor(false);

    }

void SystemClass::ShutdownWindows()
    {
    //显示光标.
    //ShowCursor(true);

    // 恢复默认显示设置.
    if(FULL_SCREEN)
        {
        ChangeDisplaySettings(NULL, 0);
        }

    // 销毁窗口
    DestroyWindow(m_hwnd);
    m_hwnd = NULL;

    // 销毁应用程序实例.
    UnregisterClass(m_applicationName, m_hinstance);
    m_hinstance = NULL;
    ApplicationHandle = NULL;

    return;

    }

LRESULT CALLBACK SystemClass::MessageHandler(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam)
    {

    switch(umsg)
        {
        // 检测按键消息.
    case WM_KEYDOWN:
        if(wparam==VK_ESCAPE)
            bexit = true;
        return 0;
       //任何其它消息发送到windows缺省处理.
    default:
        {
        return DefWindowProc(hwnd, umsg, wparam, lparam);
        }
        }
    }

LRESULT CALLBACK WndProc(HWND hwnd, UINT umessage, WPARAM wparam, LPARAM lparam)
    {
    switch(umessage)
        {

        // 窗口销毁消息.
    case WM_DESTROY:
        {
        PostQuitMessage(0);
        return 0;
        }

        // 窗口关闭消息.
    case WM_CLOSE:
        {
        PostQuitMessage(0);       
        return 0;
        }

        //MessageHandle过程处理其它所有消息.
    default:
        {
        return ApplicationHandle->MessageHandler(hwnd, umessage, wparam, lparam);
        }
        }
    }

程序执行后的界面和上次是一样的。

完整的代码请参考:

工程文件myTutorialD3D11_1

代码下载:

http://files.cnblogs.com/mikewolf2002/myTutorialD3D11.zip

Directx11 教程(2) 基本的windows应用程序框架(2)的更多相关文章

  1. Directx11 教程(1) 基本的windows应用程序框架(1)

    原文:Directx11 教程(1) 基本的windows应用程序框架(1)        在vs2010中,建立一个新的win32工程,名字是: myTutorialD3D11, 注意:同时勾选Cr ...

  2. windows应用程序框架及实例

    应用程序框架:同一类型应用程序的结构大致相同,并有很多相同的源代码,因此可以通过一个应用程序框架AFX(Application FrameWorks)编写同一类型应用程序的通用源代码. 主要向导: D ...

  3. Directx11教程(3) 一个最基本D3D应用程序(1)

    原文:Directx11教程(3) 一个最基本D3D应用程序(1)       在前一篇教程程序代码的基础上,这次我们将增加2个类: InputClass,键盘处理的代码将放在这个类里面,Graphi ...

  4. Directx11教程(21) 修正程序最小化异常bug

    原文:Directx11教程(21) 修正程序最小化异常bug       很长时间竟然没有注意到,窗口最小化时候,程序会异常,今天调试水面程序时,随意间最小化了窗口,发现程序异常了.经过调试,原来程 ...

  5. Directx11教程(4) 一个最基本D3D应用程序(2)

    原文:Directx11教程(4) 一个最基本D3D应用程序(2) 接着上篇教程的代码,本篇加入基本的D3D代码,实现一个完整的D3D11程序框架. 我们增加一个新类D3DClass, 用来处理3D渲 ...

  6. Directx11教程(13) D3D11管线(1)

    原文:Directx11教程(13) D3D11管线(1)       从本篇教程开始,我们暂停代码的学习,先来了解一下D3D11的管线,这些管线不涉及具体的硬件,而是着重于理解能够支持D3D11的管 ...

  7. Directx11教程(9) 增加一个TimerClass类

    原文:Directx11教程(9) 增加一个TimerClass类      在上篇教程代码的基础上,我们增加一个TimerClass类,这个类的功能很简单,就是可以计算相邻2帧的时间差.利用这个时间 ...

  8. Directx11教程(6) 画一个简单的三角形(2)

    原文:Directx11教程(6) 画一个简单的三角形(2)      在上篇教程中,我们实现了在D3D11中画一个简单的三角形,但是,当我们改变窗口大小时候,三角形形状却随着窗口高宽比例改变而改变, ...

  9. Directx11教程(5) 画一个简单的三角形(1)

    原文:Directx11教程(5) 画一个简单的三角形(1)       在本篇教程中,我们将通过D3D11画一个简单的三角形.在D3D11中,GPU的渲染主要通过shader来操作(当然还有一些操作 ...

随机推荐

  1. http和tcp/ip,socket的区别

    http协议和tcp/ip协议乍看起来,感觉是同一类的东西,其实不然,下面简单的说说他们的区别. http协议是应用层的一种数据封装协议,类似的还有ftp,telnet等等,而tcp/ip是数据传输层 ...

  2. TZOJ 4267 An Easy Puz(深搜)

    描述 Wddpdh find an interesting mini-game in the BBS of WHU, called “An easy PUZ”. It’s a 6 * 6 chess ...

  3. Vertex Covers(高维前缀和)

    Vertex Covers 时间限制: 5 Sec  内存限制: 128 MB提交: 5  解决: 3 题目描述 In graph theory, a vertex cover of a graph ...

  4. c/c++ explicit用法

    试想一个类,它的构造函数只有一个参数, class test { test( int a ) {} 4 } 这时我想用一个int b = 10初始化它,这当然没问题,但如果你用一个字符例如'c'初始化 ...

  5. Luogu P1092 虫食算(枚举+剪枝)

    P1092 虫食算 题面 题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 + 8468#6633 4 ...

  6. poj1961

    poj1961主要是考察对next数组的理解,abaabaabaaba abaabaabaabaabaaba错开的部分便是循环节 7月29日更 如果n%(n-kmp[k])==0,那么n-kmp[k] ...

  7. 公司-广告-WPP:WPP

    ylbtech-公司-广告-WPP:WPP WPP集团 (LSE:WPP) (NASDAQ:WPPGY),是世界上最大的传播集团,总部位于英国伦敦.WPP集团拥有 60 多个子公司,主要服务于本地.跨 ...

  8. jnhs[未解决]无法使用选定的hibernate配置文件建立数据库连接.请验证hibernate.cfg.xml中的数据库连接详情信息

    工程可以正常的使用读写数据库,当然model和model.hbm.xml文件是自己写的. 解决中

  9. new 在C++ 中的用法

    我对C++一无所知 看参考手册 来看一下参考手册,总共有三种用法 下面是网站上给出的例子 // operator new example #include <iostream> // st ...

  10. day18 9.转账汇款案例(1)