原文: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. VirtualBox安装CentOS后分辨率和鼠标无缝切换问题

    问题:VirtualBox安装完后出现分辨率只有800*600和1024*768,鼠标不能在虚拟机和本机件无缝切换. 解决办法:在终端中执行以下命令 yum install kernel yum in ...

  2. vue 路由重定向

  3. Python基础---三大推导式

    推导式comprehensions(又称解析式),是Python的一种独有特性.推导式是可以从一个数据结构构建另一个新的数据结构的结构体. 共有三种推导,在Python2和3中都有支持: 列表(lis ...

  4. 2019-8-8-WPF-非客户区的触摸和鼠标点击响应

    title author date CreateTime categories WPF 非客户区的触摸和鼠标点击响应 lindexi 2019-08-08 16:48:31 +0800 2019-07 ...

  5. 入门servlet:request获取请求体数据

    @WebServlet("/RequestDemo5") public class RequestDemo5 extends HttpServlet { protected voi ...

  6. TZOJ 3522 Checker Challenge(深搜)

    描述 Examine the 6x6 checkerboard below and note that the six checkers are arranged on the board so th ...

  7. CentOS 6.5之zabbix2.2的简单部署

    Zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案.(目前,官方长期维护的稳定版本有2.2和3.0) 其他常见的监控工具还有: (1)Cacti:Cacti是一 ...

  8. 【html、CSS、javascript-6】JavaScript

    JavaScript是一门编程语言,浏览器内置了JavaScript语言的解释器,所以在浏览器上按照JavaScript语言的规则编写相应代码之,浏览器可以解释并做出相应的处理. 参考功能网站: ht ...

  9. Django项目:CRM(客户关系管理系统)--44--36PerfectCRM实现King_admin密码修改

    # king_urls.py # ————————02PerfectCRM创建ADMIN页面———————— from django.conf.urls import url from king_ad ...

  10. iBaties对比hibernate

    翻译至一篇2008年的文章(http://www.javaworld.com/article/2077875/open-source-tools/ibatis--hibernate--and-jpa- ...