Directx11 教程(2) 基本的windows应用程序框架(2)
原文: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

posted on 2019-05-06 02:08 NET未来之路 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/lonelyxmas/p/10817458.html

Directx11 教程(2) 基本的windows应用程序框架(2)相关推荐

  1. 程序员的内涵之基于SDK的Windows应用程序框架代码详解

    基于SDK的Windows应用程序框架代码需要注意以下几个方面: 1.必须包含头文件windows.h WINDOWS.H是一个最重要的头文件,它包含了其他Windows头文件,这些头文件的某些也包含 ...

  2. winpython使用教程-使用Python开发windows桌面程序【超简单】

    一.开发前期准备 1. boa-constructor-0.6.1.bin.setup.exe #一个wxWidges的集成开发环境,简单如Delphi,可以直接拖拽控件,并且和其他集成环境不一样, ...

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

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

  4. 第二章 WINDOWS应用程序框架

    创建窗口只需调用CreateWindow 函数即可,但实际上并不这么简单. 但实际上并非真得这么简单.虽然创建窗口的函数确实被命名为CreateWindow, 但您将发现 CreateWindow的第 ...

  5. 自强不息系列之基于SDK的Windows应用程序框架代码详解

    1.必须包含头文件windows.h WINDOWS.H是一个最重要的头文件,它包含了其他Windows头文件,这些头文件的某些也包含了其他头文件.这些头文件中最重要的和最基本的是: WINDEF.H ...

  6. 美团小程序框架mpvue入门教程

    美团小程序框架mpvue入门教程 自打写了 美团小程序框架mpvue蹲坑指南, 一发不可收拾,今天趁周末空闲,来写个mpvue(没朋友)的简单入门教程,本教程只针对新手,老鸟勿喷. 另外,我还专门为本 ...

  7. Mac系统如何运行Windows exe程序?mac打开exe文件方法教程

    使用了Mac系统之后,总会惦记着Windows系统的软件,无奈两个系统的程序文件不一样,所以也互不相通.为了让MacBook能够使用上Windows的应用程序,许多人都会给电脑安装一个Windows系 ...

  8. 【C#】SharpDevelop使用教程,C#写windows下第一个窗口程序,简单粗暴,初学者进,全图文,一看就明白

    VS不说,功能强大,但是挺大. 下面,来说说轻量级IDE来写一个简单的windows程序. 首先,下载,不说了,最新版本5.x需要.net4.x支持,需要先安装.net framework 4.x框架 ...

  9. 《ArcGIS Engine+C#实例开发教程》第一讲桌面GIS应用程序框架的建立

    原文:<ArcGIS Engine+C#实例开发教程>第一讲桌面GIS应用程序框架的建立 摘要:本讲主要是使用MapControl.PageLayoutControl.ToolbarCon ...

最新文章

  1. SAP QM初阶之启用了Multiple Specification功能后检验批的不同之处?
  2. 基于FPGA的以太网开发
  3. Objective-C中block的底层原理
  4. java 判断数字变化增减_java String 强化操作 判断数字 字符串转阿拉伯数字,相似度等等...
  5. IOS_多线程_GET_POST_AFN_上传下载_视频播放
  6. 数据库字段数据(昵称)排序,规则: 数字英文字母汉字首字母 兼容简繁体排序
  7. mysql查询条件忽略大小写_mysql 查询条件不区分大小写问题
  8. mw150r 虚拟服务器,水星MW150R V1.3路由器刷DD-WRT使用WIWIZ或wifiap做web认证登录
  9. 计算机的硬盘如何查看,怎样查看电脑硬盘信息 电脑中的硬盘信息
  10. Cookie和Session的作用,区别和各自的应用范围,cookie、Session工作原理
  11. 力扣刷题 DAY_75 贪心
  12. Eli Lilly(礼来) | RPA在医疗行业的应用案例
  13. 爬虫之旅(一):爬取b站首页的源代码
  14. 暴力递归转动态规划----以货币数问题展开
  15. 世界上最成功的人一开始是个程序员-《程序员大本营》1999版
  16. 基于ROS2开发的点云体素化
  17. U盘数据不见了怎么恢复?
  18. 离散数学20_第1章_等价符号⇔的定义
  19. ffmpeg 从视频中提取WAV格式的音频
  20. Centos7 防火墙配置

热门文章

  1. selector与layer-list 单边框效果
  2. java与c/c++之间的数据交互-----jni点滴
  3. 一次HP 阵列卡排障
  4. 开发管理 CheckLists(4) -风险管理
  5. thinkpad 61系机器(T61 X61/X61S R61)休眠掉电问题解决办法
  6. Vim对中文编码的支持[转]
  7. 计算机编程课程顺序_您可以在6月开始参加630项免费的在线编程和计算机科学课程...
  8. 老年痴呆 数字化_设计老年人愉快数字体验的5条原则
  9. Spring Cloud应用开发(二:实现服务间的调用)
  10. 计组--习题--总线