第一章 Direct3D学习之简单的WIN32程序

一个最简单的win32程序有以下几个重点函数。

程序的入口winmian!!

函数原型
  int WINAPI WinMain   (   
     HINSTANCE hInstance,   
     HINSTANCE hPrevInstance,   
     LPSTR lpCmdLine,   
     int nCmdShow   );   
(在Visual Studio 2005下则为int APIENTRY WinMain...)
编辑本段参数
  hInstance:应用程序当前实例的句柄。   
  hPrevlnstance:应用程序的先前实例的句柄。对于同一个程序打开两次,出现两个窗口第一次打开的窗口就是先前实例的窗口。
      对于一个32位程序,该参数总为NULL。   
      如果需要检测另外一个实例是否已经存在,
      则使用CreateMutex函数创建一个独一无二的名字。
      即使互斥名已经存在,CreateMutex函数也是成功的,
      但是GetLastError函数将返回 ERROR_ALREADY_EXISTS,
      这就表明应用程序有另外一个实例存在,因为它首先创建了互斥名。   
  lpCmdLine:指向应用程序命令行的字符串的指针,不包括执行文件名。获得整个命令行,参看GetCommandLine。   
      第三个参数lpCmdLine是一个以空终止的字符串,指定传递给应用程序的命令行参数。
      例如:在D盘下有一个sunxin.txt文件,当我们用鼠标双击这个文件时将启动记事本程序(notepad.exe),
      此时系统会将D:\sunxin.txt作为命令行参数传递给记事本程序的WinMain函数,
      记事本程序在得到这个文件的全路径名后,
      就在窗口中显示该文件的内容。
      要在VC++开发环境中向应用程序传递参数,
      可以单击菜单【Project】→【Settings】,选择“Debug”选项卡,
      在“Program arguments”编辑框中输入你想传递给应用程序的参数。   
  nCmdShow:指明窗口如何显示。该参数可以是下列值之一:   
      SW_HIDE:隐藏窗口并且激活另外一个窗口。   
      SW_MINIMIZE:最小化指定的窗口,并且激活在系统表中的顶层窗口。   
      SW_RESTORE:激活并显示窗口。如果窗口已经最小化或最大化,系统将以恢复到原来的尺寸和位置显示窗口(与SW_SHOWNORMAL相同)。   
      SW_SHOW:激活一个窗口并以原来的尺寸和位置显示窗口。   
      SW_SHOWMAXIMIZED:激活窗口并且将其最大化。   
      SW_SHOWMINIMIZED:激活窗口并将其最小化(以图标显示)。   
      SW_SHOWMINNOACTIVE:将一个窗口显示为图标。激活窗口维持活动状态。   
      SW_SHOWNA:以窗口的当前状态显示窗口。激活窗口保持活动状态。   
      SW_SHOWNOACTIVATE:以窗口的最近一次的尺寸和位置显示窗口。激活窗口维持激活状态。   
      SW_SHOWNORMAL:激活并显示窗口。如果窗口最大化或最小化,系统将其恢复到原来的尺寸和位置(与SW_RESTORE相同)。
编辑本段返回值
  如果函数成功,当它接收到一个WM_QUIT消息时就中止,函数应该返回在该消息的wParam参数的退出值。如果函数在进入消息循环时退出,应该返回零。
编辑本段备注
  当接收到一个WM_QUIT消息时,程序就中止。这时,WinMain函数应退出应用程序,并且返回传递给WM_QUIT消息的wParam参数的值。
  如果由于调用PostQuitMessage函数而接收到WM_QUIT消息,wParam的值是PostQuiMessage函数的nExitCode的值。请参看“创建一个窗口循环”。   
  ANSI应用程序可以使用WinMain函数的lpCmdLine参数进入命令行字符串(除了程序名之外)。
  WinMain不能返回Unicode字符串的原因是IpCmdLine使用的是LPSTR数据类型,而不是LPTSTR类型。
  GetCommandLine函数可以用于进入命令行的Unicode字符串,因为它使用的是LPTSTR类型。   
  Windows CE:
  Windows CE不支持下列 nCmdLine参数值:   
  SW_MINIMIZE;
  SW_RESTORE;
  SW_RESTORE;
  SW_SHOWMAXMIZED   
  SW_SHOWMINIMIZED;
  SW_SHOWMINNOACTIVE
  
  
创建窗口
  WNDCLASS wndclass;
  //该数据结构中包含窗口类的各种属性   
  wndclass.style =0; // 窗口类型为缺省类型   
  wndclass.lpfnWndProc=WndProc; //定义窗口处理函数(即窗口的消息回调函数,稍后讲解回调函数的工作原理)
  wndclass.cbClsExtra=0; //窗口类无扩展   
  wndclass.cbWndExtra=0; //窗口实例无扩展   
  wndclass.hInstance=hInstance; //当前实例句柄   
  wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);//窗口的最小化图标为缺省图标   
  wndclass.hCursor=LoadCursor(NULL,IDC_ARROW); // 窗口采用箭头光标   
  wndclass.hbrBackground=(HBRUSH)(GetStockObject(WHITE_BRUSH)); //窗口背景为白色   
  wndclass.lpszMenuName=NULL; //窗口无菜单   
  wndclass.lpszClassName=lpszClassName; //窗口类名 (当创建窗口时要与此名称一致)
  定义完结构体后就可以创建窗口,使用下述方法
  HWND CreateWindow(
    LPCTSTR lpClassName,  // registered class name
    LPCTSTR lpWindowName, // window name
    DWORD dwStyle,        // window style
    int x,                // horizontal position of window
    int y,                // vertical position of window
    int nWidth,           // window width
    int nHeight,          // window height
    HWND hWndParent,      // handle to parent or owner window
    HMENU hMenu,          // menu handle or child identifier
    HINSTANCE hInstance,  // handle to application instance
    LPVOID lpParam        // window-creation data
  );
  该方法返回了被创建的窗口句柄
  HWND hwnd = ::CreateWindow(
  lpszClassName,       //注册的窗口类名 (要与wndclass.lpszClassName的值一致)
  lpszClassName,       //窗口标题栏显示的名称
  WS_OVERLAPPEDWINDOW,   //窗口类型,详见msdn
  100, 100, width, height, //窗口左上角的坐标和窗口的长宽
  0 /*父窗口句柄*/, 0 /* 菜单 */, hInstance/*程序实例*/, 0 /*窗口创建标识*/);
  
消息回调函数

  //框架窗口消息回调方法  必须为全局函数,函数的名字为wndclass.lpfnWndProc的值;
  //消息回调函数的返回值类型和函数标识固定为LRESULT CALLBACK,
  //参数固定为HWND hwnd窗口句柄, UINT msg消息类型, WPARAM wParam消息详细信息, LPARAM lParam消息的另一些详细信息
  //例如:
  LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  {
   switch( msg ) //利用msg来区分哪些消息
   {
   case WM_DESTROY:  //窗口销毁
    ::PostQuitMessage(0); 
    break;
    
   case WM_KEYDOWN:  //键盘按下
    if( wParam == VK_ESCAPE )
     ::DestroyWindow(hwnd); //如果按下为esc键则发送一个WM_DESTROY消息
    if(wParam  == 'W'){ //按下的键为w
     
    }
    
    break;
   case WM_KEYUP:  //键盘弹起
    if(wParam  == 'W'){ //弹起的键为w
     
    }
   
    break;
  
   }
  
   return ::DefWindowProc(hwnd, msg, wParam, lParam);
  }
  
消息循环

  WPARAM EnterMsgLoop()
  {
   MSG msg;
   ::ZeroMemory(&msg, sizeof(MSG));
  
   while(msg.message != WM_QUIT)
   {
    if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) //该函数为一个消息检查线程消息队列,并将该消息(如果存在)放于指定的结构
    {
    /*
    *此处是消息机制的关键代码
    *windows会将用户的操作暂存到消息队列里,
    *win32通过PeekMessage函数从消息队列里获得用户消息
    *通过下面两个函数,消息会被发送到窗口创建时注册的消息回调函数
    *比如上面定义的LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
    */
     ::TranslateMessage(&msg);  //翻译消息
     ::DispatchMessage(&msg);  //发送消息
    }
    else
    { 
     //在这里添加程序运行代码
  
    }
   }
   return msg.wParam;
  }
  
总结:
  要创建一个单窗口win32程序要遵循以下步骤
  1.实现winmian
  2.实现一个全局的消息回调函数LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  3.实现一个全局的消息循环函数WPARAM EnterMsgLoop()
  4.在winmian函数中定义一个窗口结构体并创建,显示窗口
  5.执行消息循环
  例:
  int WINAPI WinMain(HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       LPSTR     lpCmdLine,
                       int       nCmdShow)
  {
   //创建窗口
    WNDCLASS wc;

   wc.style         = CS_HREDRAW | CS_VREDRAW;
   wc.lpfnWndProc   = (WNDPROC)WndProc;
   wc.cbClsExtra    = 0;
   wc.cbWndExtra    = 0;
   wc.hInstance     = hInstance;
   wc.hIcon         = LoadIcon(0, IDI_APPLICATION);
   wc.hCursor       = LoadCursor(0, IDC_ARROW);
   wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
   wc.lpszMenuName  = 0;
   wc.lpszClassName = "窗口类的名字";
  
   if( !RegisterClass(&wc) )
   {
    ::MessageBox(0, "RegisterClass() - FAILED", 0, 0);
    return false;
   }
  
   HWND hwnd = ::CreateWindow("窗口类的名字", "窗口标题的名字",
    WS_OVERLAPPEDWINDOW,
    100, 100, width, height,
    0 /*parent hwnd*/, 0 /* menu */, hInstance, 0 /*extra*/);
  
   if( !hwnd )
   {
    ::MessageBox(0, "CreateWindow() - FAILED", 0, 0);
    return false;
   }
   ::ShowWindow(m_hWnd, SW_SHOW);
   ::UpdateWindow(m_hWnd);
  
   //消息循环
   EnterMsgLoop();
  
   return 0;
  }

转载于:https://www.cnblogs.com/leexuzhi/archive/2011/10/10/2205391.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值