win32 最基本编程和应用程序框架

来源:互联网 发布:flash8.0软件下载 编辑:程序博客网 时间:2024/05/13 13:27


现在市场上出现了很多应用程序框架,比如窗体程序,如MFC,.net framwork , VB , delphi,举不胜数。

其实,这些并不是开发windows应用程序必需的东西,windows在底层是为我们开放了一套API函数库,使用这套函数库,其实我们也能构建出一套功能强健的windows应用程序。

下面,我重点说明一下windows的窗口应用程序,其实,windows窗口程序的核心就是窗口,一个windows窗口应用程序是由无数的窗口构成。

比如MFC里面,一个按钮或者一个列表,一个文本框控件,其实就是主窗口的一个子窗口,子窗口和主窗口一样,有消息处理和可以拥有其子窗口。

我们用C++,调用win32 API,用vs 6.0去编译,写一个最基本的win32应用程序,转到用例中,说明一个最基本的windows窗口程序的基本原理。


      #include <windows.h>
      #include <windowsx.h>
      //函数声明
      BOOL InitWindow( HINSTANCE hInstance, int nCmdShow );
      LRESULT CALLBACK WinProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM
      lParam );
      //*******************************************************************
      //函数:WinMain()
      //功能:Win32应用程序入口函数。创建主窗口,处理消息循环
      //*******************************************************************
      int PASCAL WinMain( HINSTANCE hInstance, //当前实例句柄
      HINSTANCE hPrevInstance, //前一个实例句柄
      LPSTR lpCmdLine, //命令行字符
      int nCmdShow) //窗口显示方式
      {
      MSG msg;
      //创建主窗口
      if ( !InitWindow( hInstance, nCmdShow ) )
      return FALSE;
      //进入消息循环:
      //从该应用程序的消息队列中检取消息,送到消息处理过程,
      //当检取到WM_QUIT消息时,退出消息循环。
      while (GetMessage(&msg, NULL, 0, 0))
      {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
      }
      //程序结束
      return msg.wParam;
      }
      //******************************************************************
      //函数:InitWindow()
      //功能:创建窗口。
      //******************************************************************
      static BOOL InitWindow( HINSTANCE hInstance, int nCmdShow )
      {
      HWND hwnd; //窗口句柄
      WNDCLASS wc; //窗口类结构
      //填充窗口类结构
      wc.style = CS_VREDRAW | CS_HREDRAW;
      wc.lpfnWndProc = (WNDPROC)WinProc;
      wc.cbClsExtra = 0;
      wc.cbWndExtra = 0;
      wc.hInstance = hInstance;
      wc.hIcon = LoadIcon( hInstance, IDI_APPLICATION );
      wc.hCursor = LoadCursor( NULL, IDC_ARROW );
      wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
      wc.lpszMenuName = NULL;
      wc.lpszClassName = "EasyWin";
      //注册窗口类
      RegisterClass( &wc );
      //创建主窗口
      hwnd = CreateWindow(
      "EasyWin", //窗口类名称
      "一个基本的Win32程序", //窗口标题
      WS_OVERLAPPEDWINDOW, //窗口风格,定义为普通型
      100, //窗口位置的x坐标
      100, //窗口位置的y坐标
      400, //窗口的宽度
      300, //窗口的高度
      NULL, //父窗口句柄
      NULL, //菜单句柄
      hInstance, //应用程序实例句柄
      NULL ); //窗口创建数据指针
      if( !hwnd ) return FALSE;
      //显示并更新窗口
      ShowWindow( hwnd, nCmdShow );
      UpdateWindow( hwnd );
      return TRUE;
      }
      //******************************************************************
      //函数:WinProc()
      //功能:处理主窗口消息
      //******************************************************************
      LRESULT CALLBACK WinProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM
      lParam )
      {
      switch( message )
      {
      case WM_KEYDOWN://击键消息
      switch( wParam )
      {
      case VK_ESCAPE:
      MessageBox(hWnd,"ESC键按下了!","Keyboard",MB_OK);
      break;
      }
      break;
      case WM_RBUTTONDOWN://鼠标消息
      {
      MessageBox(hWnd,"鼠标右键按下了!","Mouse",MB_OK);
      break;
      }
      case WM_PAINT://窗口重画消息
      {
      char hello[]="你好,hello world !";
      HDC hdc;
      PAINTSTRUCT ps;
      hdc=BeginPaint( hWnd,&ps ); //取得设备环境句柄
      SetTextColor(hdc, RGB(0,0,255)); //设置文字颜色
      TextOut( hdc, 20, 10, hello, strlen(hello) );//输出文字
  
      EndPaint( hWnd, &ps ); //释放资源
      break;
      }
      case WM_DESTROY://退出消息
      PostQuitMessage( 0 );//调用退出函数
      break;
      }
      //调用缺省消息处理过程
      return DefWindowProc(hWnd, message, wParam, lParam);
      }

 

这个程序有三个最基本的函数,一个是WinMain,一个是WinProc,一个是InitWindow。

WinMain是函数的主入口函数,hInstance是本进程的句柄,它主要用来以后作参数传递给需要调用的函数,不知道的朋友可以先不管它。
lpCmdLine是别人打开使应用程序的时候,传进来的参数,一般双击运行的程序,使参数为空指针。
但假如是像在命令行里输入一个ping 61.144.56.101这样打开ping应用程序,61.144.56.101就是作为参数传递的。
nCmdShow为窗体显示方式,在这里可以先不管。


再来看看InitWindow,InitWindow是我们自己定义的函数,并不是windows自有的函数,在main函数里,我们调用了InitWindow这个函数。
首先我们来看看,InitWindow这个函数将前面的两个参数hInstance和nCmdShow传了进来,这两个参数是注册窗体时所必需的。
WNDCLASS wc,其实就是创建一个窗口类,这是windows创建窗口程序最基本的类,他有的参数假如大家不知道,可以去查msdn,这里不再讨论。

接着我们使用RegisterClass( &wc )注册这个窗口类,然后调用CreateWindow创建一个窗口,它的原型如下:

HWND CreateWindow(
  LPCTSTR lpClassName,
  LPCTSTR lpWindowName,
  DWORD dwStyle,
  int x,
  int y,
  int nWidth,
  int nHeight,
  HWND hWndParent,
  HMENU hMenu,
  HANDLE hInstance,
  PVOID lpParam
);

其中,hWndParent为父窗口的句柄,假如 hWndParent不为空,代表为某一个父窗口创建一个子窗口。
其函数的参数我不一一说明了,其中我们最关心的就是他的返回值,是一个HWND类型的句柄,保存好这个返回后的句柄,以作以后调用。

我们再来回过头来看看窗口类WNDCLASS 的lpfnWndProc属性,其实它是一个回调函数指针,指向一个自定义函数,当windows窗口消息产生后,windows内核会自动调用此函数。
注意WM_PAINT消息是我们必需处理的消息,在这个消息里面,我们要用windows自带的绘图方法,将需要显示的内容绘制出来,这个消息在你们改变窗口大小,最大化,最小化的很多时候都会触发,假如不在这个消息里面写东西,那么创建的窗口将会空白一片。
lpfnWndProc指向的回调函数一个非常重要的函数,比如我们创建了一个用于作按钮的子窗口,那么WM_LBUTTONDOWN左键点击消息就很重要的,用于响应其点击事件。又比如制作一个文本框输入窗口,那么WM_KEYDOWN和WM_PAINT消息是很重要的,我们可以在用户按下键盘的时候,用绘图方法将用户的输入绘制出来。

我们的WinProc函数,里面有一些消息的处理例子,当然,这个的消息类型还有很多,那里只是极少的一部分。


最后,我们看到main函数里面有个死循环,那是要让主线程处于等待状态,让它永远地执行下去,不结束其生命周期,直到收到退出消息后,此循环才结束。


这样,我们已经创建了一个windows最简单的窗口程序,但是,这是远远不够的,真正的应用中,我们还必须去处理unicode,多字节字符,多线程,线程同步,IO模型,完成端口这些东西。有兴趣的朋友可以看看windows核心编程这本书,的确是一本好书。


大的开发框架,大如mfc,其实也是基于这些最基本的程序开发出来的。假如你不想打包庞大的mfc或者.net framwork框架,假如你有能力,不想依赖于框架,想更加灵活的写程序,假如你想做绿化版,那么纯净的win 32程序就是首选。窗口、子控件它们其实就是都由CreateWindow,WinProc构成,在WinProc的WM_PAINT规划你的显示,在其他消息里处理你的逻辑。

原创粉丝点击