为自己创作一个好的DirectX程序风格

 为自己创作一个好的DirectX程序风格
 一直以来,我都是模仿别人的程序,进行参数的修改,来达到自己的目的。但是久而久之,我发现这样不行,因为演示程序又很多很多缺陷,所以我不得不使用自己的程序,希望开创自己程序的风格。
 那么,下面就是我通过学习windows程序而得出的心得。可能写得不好,有疑问的请指正。
 在创建Windows程序的时候,我们必须要包含windows.h头文件,这是毋庸置疑的。
 首先是消息函数。消息函数是一种典型的回调函数。回调函数就是一种自己并不显示地使用,但是需要别的函数将此函数的地址传给它,用别的函数来使用。调用函数就是通过回调函数指针来进行传值调用的。在我以前的文章中,调用的Display()函数就是一种回调函数。而消息函数就是给应用程序实例进行调用的。让我们看看回调函数吧。

Code:
  1. HRESULT CALLBACK MsgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)   
  2. {   
  3.     switch(msg)   
  4.     {   
  5.     case WM_DESTROY:   
  6.         PostQuitMessage(0);   
  7.         return 0;   
  8.     }   
  9.     return (long) DefWindowProc(hwnd, msg, wParam, lParam);   
  10. }  

 其中HRESULT就是一个返回值类型,通过windows.h头文件一层又一层的typedef,我们找出了它的源泉:long。其实HRESULT就是long类型。而CALLBACK则是一个调用约定。它也是通过一层又一层的typedef语句进行规定的,它的原型其实是__stdcall。__stdcall又是什么?在百度百科中我们找到了答案:

1.参数从右向左压入堆栈
2.函数被调用者修改堆栈
3.函数名(在编译器这个层次)自动加前导的下划线,后面紧跟一个@符号,其后紧跟着参数的尺寸

 这样我们了解了什么是CALLBACK。总结一下,CALLBACK就是一个调用规定,它在汇编语言的层次规定了调用的方法。其实有很多的关键字:WINAPI、APIENTRY都是__stdcall的同义词。

 扩展:c/c++还有一种调用方式,那就是__cdecl。这种方式和__stdcall有些不同,它是c/c++缺省的调用方式。详见http://baike.baidu.com/view/1280676.htm

 再来看看,MsgProc()函数有这样几个参数:HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam。第一个是窗口的句柄,第二个是消息的结构体,第三个和第四个则是消息参数,其实这两个参数几乎完全相同。我们常常使用的是第一个参数wParam。函数体是对消息的处理。在一个switch语句结束后,我们就可以让操作系统来自动处理消息了。所以返回的是DefWindowProc(hwnd, msg, wParam, lParam)。

 消息回调函数介绍完了,我们接下来可以介绍我们的主函数WinMain()了。大家或多或少地接触WinMain()函数,因为在MFC、ATL、WTL框架上都要使用WinMain()函数。WinMain()函数的作用就相当于控制台的main()函数,但是它的参数比main()函数要多。而且不支持重载,也就是说,我们可以使用重载的main( void ),但是不能使用WinMain( void )。使用WinMain()函数的时候,我们也必须声明函数的调用方式。使用WINAPI,或者APIENTRY就可以解决问题。但是这必须要定义相关的宏。如果你对WinMain()函数相当地了解了,那么你可以使用__stdcall来代替这些值。WinMain()函数是这样声明的:

Code:
  1. int WinMain(   
  2.     HINSTANCE hInstance,   
  3.     HINSTANCE hPrevInstance,   
  4.     LPSTR lpCmdLine,   
  5.     int nCmdShow);  


第一个参数是当前程序的实例句柄,第二个参数是以前程序的实例句柄。通常为NULL。如果你限制程序一次只能打开一次,那么我们可以使用CreateMutex()函数来解决。这超出了我们的讨论范围。在这里略去。第三个参数是当前程序在命令行中的绝对路径。第四个参数是显示的方式,我们可以通过此值来确定程序的显示方式。通常要程序正常地显示,使用SW_SHOWNORMAL来标记nCmdShow即可。

 然后我们在WinMain()函数中编写代码了。但无论你怎么编写,我们都必须满足这样一个流程:
1、设置Window Class结构并且注册它
2、设置窗口并且显示窗口
3、进入消息循环
4、解除窗口注册

 首先设置windows class结构。我使用的是WNDCLASSEX结构,因为它提供了更多的功能。WNDCLASSEX结构如下所示:

Code:
  1. typedef struct {   
  2.     UINT cbSize;   
  3.     UINT style;   
  4.     WNDPROC lpfnWndProc;   
  5.     int cbClsExtra;   
  6.     int cbWndExtra;   
  7.     HINSTANCE hInstance;   
  8.     HICON hIcon;   
  9.     HCURSOR hCursor;   
  10.     HBRUSH hbrBackground;   
  11.     LPCTSTR lpszMenuName;   
  12.     LPCTSTR lpszClassName;   
  13.     HICON hIconSm;   
  14. } WNDCLASSEX, *PWNDCLASSEX;  

现在我来说明这些数据成员。
UINT cbSize;是该结构的大小(字节)
UINT style;是窗口的风格,有多种风格可以选择。参见MSDN。
WNDPROC lpfnWndProc;窗口消息循环函数的入口指针。
int cbClsExtra;需要附加在WNDCLASSEX结构体的字节数,通常设为零。
int cbWndExtra;为窗口实例附加的字节。通常是0。但是如果是对话框形式的,并且附加了资源,则需使用DLGWINDOWEXTRA。
HINSTANCE hInstance;为程序的实例句柄。
HICON hIcon;为图标的句柄,如果为NULL,程序则会在资源中寻找图标。
HCURSOR hCursor;为光标句柄,如果使用的是自定义的光标,则可以使用LoadCursor()函数来实现。
HBRUSH hbrBackground;为背景画板刷,暂时设为NULL,我还没有学会怎么使用。
LPCTSTR lpszMenuName;为菜单的指针。如果程序中有菜单,并且在资源中有菜单的编辑,那么可以不为空,但是如果不需要使用菜单,可以将其设为NULL。
LPCTSTR lpszClassName;为NDCLASSEX类的名字。
HICON hIconSm;16×16大小的小图标的句柄。

 然后调用CreateWindow()函数。这个函数可以为窗口指定样式。它是这样定义的:

Code:
  1. HWND CreateWindow(   
  2.     LPCTSTR lpClassName,   
  3.     LPCTSTR lpWindowName,   
  4.     DWORD dwStyle,   
  5.     int x,   
  6.     int y,   
  7.     int nWidth,   
  8.     int nHeight,   
  9.     HWND hWndParent,   
  10.     HMENU hMenu,   
  11.     HINSTANCE hInstance,   
  12.     LPVOID lpParam   
  13. );  

下面我来说说这个参数的用法:
LPCTSTR lpClassName,为windows class(WNDCLASSEX) 类的名字;
LPCTSTR lpWindowName,为窗口的名字,它会显示在窗口上。
DWORD dwStyle,窗口的样式,通过各种样式的组合,我们可以得出不同的窗口来。因为有太多的样式了,所以有什么疑问,参照MSDN;
int x,窗口起始横坐标;
int y,窗口起始纵坐标;
int nWidth,窗口的宽;
int nHeight,窗口的高;
HWND hWndParent,这个是窗口的父窗口句柄;
HMENU hMenu,菜单的句柄。
HINSTANCE hInstance,程序实例句柄
LPVOID lpParam绘制客户区的参数

 然后就调用ShowWindow()和UpdateWindow()函数来进行显示了。再进行消息循环,如果有什么消息传入的话,进入消息队列,否则进行窗口渲染。当然,我写的这个程序是非常简单的,以后我可能会使用这个程序的模板来写更多更多复杂的程序的。

 下面就是我的代码,它是我在模仿多个windows程序的源代码后自己写的代码。 

Code:
  1. /*---------------------------------------------------------------------------  
  2. 蒋轶民制作 E-mail:jiangcaiyang123@163.com  
  3. 文件名:MainFrame.cpp  
  4. 作用:设计自己优化的程序结构  
  5. ----------------------------------------------------------------------------*/  
  6. #include<windows.h>   
  7.   
  8. // 定义的宏   
  9. #define JCLASSNAME  "优化的程序"   
  10. #define JCAPTION  "程序演示"   
  11. #define WINDOW_WIDTH 320   
  12. #define WINDOW_HEIGHT 320   
  13.   
  14. HRESULT CALLBACK MyAppProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )   
  15. {   
  16.  switch ( msg )   
  17.  {   
  18.  case WM_DESTROY:   
  19.   PostQuitMessage( 0 );   
  20.   return 0;   
  21.  }   
  22.  return (HRESULT)DefWindowProc( hWnd, msg, wParam, lParam );   
  23. };   
  24.   
  25. int WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR cmd, int show )   
  26. {   
  27.  // 设置Window Class结构并且注册它   
  28.  WNDCLASSEX jWndCls = { sizeof( jWndCls ), CS_CLASSDC, MyAppProc, 0, 0, hInst,    
  29.   NULL, NULL, 0, NULL, JCLASSNAME, NULL };   
  30.  RegisterClassEx( &jWndCls );   
  31.   
  32.  // 设置窗口并且显示窗口   
  33.  HWND hWnd = CreateWindow( JCLASSNAME, JCAPTION, WS_CAPTION | WS_SYSMENU, 20, 20,   
  34.   WINDOW_WIDTH, WINDOW_HEIGHT, NULL, NULL, hInst, BUTTON);   
  35.  if ( hWnd == NULL )   
  36.   return FALSE;   
  37.  ShowWindow( hWnd, SW_SHOWNORMAL );   
  38.  UpdateWindow( hWnd );   
  39.   
  40.  // 进入消息循环   
  41.  MSG msg;   
  42.  ZeroMemory( &msg, sizeof( msg ) );   
  43.  while( msg.message != WM_QUIT )   
  44.  {   
  45.   if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )   
  46.   {   
  47.    TranslateMessage( &msg );   
  48.    DispatchMessage( &msg );   
  49.   }   
  50.   else  
  51.   {   
  52.    // 什么也不做   
  53.   }   
  54.  }   
  55.   
  56.  // 解除窗口注册   
  57.  UnregisterClass( JCLASSNAME, jWndCls.hInstance );   
  58.  return 0;   
  59. }   

 我更多的DirectX程序,请看:

设计DirectX游戏开头动画效

设计DirectX游戏开头画面淡淡出的效

我的游戏:走迷宫(DirectX版) 

今天就写到这里了,如果有时间的话,我会写更多有关DirectX和Windows应用程序的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值