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
Directx11 教程(2) 基本的windows应用程序框架(2)的更多相关文章
- Directx11 教程(1) 基本的windows应用程序框架(1)
原文:Directx11 教程(1) 基本的windows应用程序框架(1) 在vs2010中,建立一个新的win32工程,名字是: myTutorialD3D11, 注意:同时勾选Cr ...
- windows应用程序框架及实例
应用程序框架:同一类型应用程序的结构大致相同,并有很多相同的源代码,因此可以通过一个应用程序框架AFX(Application FrameWorks)编写同一类型应用程序的通用源代码. 主要向导: D ...
- Directx11教程(3) 一个最基本D3D应用程序(1)
原文:Directx11教程(3) 一个最基本D3D应用程序(1) 在前一篇教程程序代码的基础上,这次我们将增加2个类: InputClass,键盘处理的代码将放在这个类里面,Graphi ...
- Directx11教程(21) 修正程序最小化异常bug
原文:Directx11教程(21) 修正程序最小化异常bug 很长时间竟然没有注意到,窗口最小化时候,程序会异常,今天调试水面程序时,随意间最小化了窗口,发现程序异常了.经过调试,原来程 ...
- Directx11教程(4) 一个最基本D3D应用程序(2)
原文:Directx11教程(4) 一个最基本D3D应用程序(2) 接着上篇教程的代码,本篇加入基本的D3D代码,实现一个完整的D3D11程序框架. 我们增加一个新类D3DClass, 用来处理3D渲 ...
- Directx11教程(13) D3D11管线(1)
原文:Directx11教程(13) D3D11管线(1) 从本篇教程开始,我们暂停代码的学习,先来了解一下D3D11的管线,这些管线不涉及具体的硬件,而是着重于理解能够支持D3D11的管 ...
- Directx11教程(9) 增加一个TimerClass类
原文:Directx11教程(9) 增加一个TimerClass类 在上篇教程代码的基础上,我们增加一个TimerClass类,这个类的功能很简单,就是可以计算相邻2帧的时间差.利用这个时间 ...
- Directx11教程(6) 画一个简单的三角形(2)
原文:Directx11教程(6) 画一个简单的三角形(2) 在上篇教程中,我们实现了在D3D11中画一个简单的三角形,但是,当我们改变窗口大小时候,三角形形状却随着窗口高宽比例改变而改变, ...
- Directx11教程(5) 画一个简单的三角形(1)
原文:Directx11教程(5) 画一个简单的三角形(1) 在本篇教程中,我们将通过D3D11画一个简单的三角形.在D3D11中,GPU的渲染主要通过shader来操作(当然还有一些操作 ...
随机推荐
- visual studio 2013 打开失败 ,报错:未能完成操作,不支持此接口
因为从新安装了.net 4.0版本,再打开visual studio 2013时,提示报错:未能完成此操作,不支持接口 解决办法:从microsoft官网下载了最新4.5版本进行安装后.即可成功打开.
- jeecms项目相关配置文件
1.application-context.xml 这个是Spring的标准配置文件,这里面配置jdbc.properties文件并初始化相应数据库连接参数到bean实例:定义数据库表映射文件*.hb ...
- Echarts在Vue中的使用
1.使用 cnpm 或 npm 安装 Echarts cnpm方式 cnpm install echarts -S 或者 npm方式 npm install echarts --save 2.在项目文 ...
- [转载] OpenCV2.4.3 CheatSheet学习(三)
四.图像处理(呵呵,重头戏来了) 1. 滤波 filter2D() 用核函数对图像做卷积. sepFilter2D() 用分解的核函数对图像做卷积. 首先,图像的每一行与一维的核kernelX做卷积: ...
- C#——找出实现某个接口的所有类 - Hello World - CSDN博客
原文:C#--找出实现某个接口的所有类 - Hello World - CSDN博客 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u0125260 ...
- Redis 核心
一.Redis单机多实例原理 每个实例对应不同的配置文件,配置文件对应不同的端口.数据库文件位置.日志位置. 二.Redis单实例多数据库 每个Redis实例都有16个数据库,下标从0-15,当 se ...
- MySQL 普通注册插入优化。
普通做法是: 用户通过手机号注册.默认是根据这个手机号去用户表里查询,看有没有这个手机号,有那么就提示已注册.否则就执行注册插入数据库操作.这里其实正常注册流程是两次数据库操作的(查询,插入): 优化 ...
- c++新特性实验(4)声明与定义:右值引用(C++11)
1.作用 c++11以前,临时对象.字面常量一般情况下不可以再次访问,也不可以修改.右值引用可以解决这个问题. 1.1 实验A #include <iostream> using name ...
- return语句必须要注意的地方
先看下面程序: function foo1() { return { /*返回对象{}他留有一个大括号跟return在同一行*/ bar: "hello" }; } functio ...
- invalid use of null value
给mysql的数据表的一个字段插入数据,不成功, 然后在数据表设计中,把不是null勾选上,又提示 invalid use of null value 这种情况比较尴尬 只能删掉这一个字段,然后新建一 ...