Windows程序内部运行机制

  1. Windows程序设计是种事件驱动方式的程序设计,主要基于消息的。当用户需要完成某种功能时,需要调用OS某种支持,然后OS将用户的需要包装成消息,并投入到消息队列中,最后应用程序从消息队列中取走消息并进行响应。
  2. 消息结构:
    typedef struct tagMSG {     // msg
        HWND   hwnd;     //接收消息的窗口句柄。和哪个窗口相关联。
        UINT   message;  //消息标识。消息本身是什么。
        WPARAM wParam;   //消息的附加信息。具体取决于消息本身。 
        LPARAM lParam;
        DWORD  time;     //消息投递时间。
        POINT  pt;       //消息投递时,光标在屏幕上的位置。
    } MSG;
  3. 消息队列:
    对于每个应用程序,OS都为它建立一个消息队列,消息队列是个先进先出的缓冲区,其中每个元素都是一个消息,OS将生成的每个消息按先后顺序放进消息队列中,应用程序总是取走当前消息队列中的第一条消息,应用程序取走消息后便知道用户的操作和程序的状态,然后对其处理即消息响应,消息响应通过编码实现。
  4. 使用VC编程除了良好的C基础外还需要掌握两方面:
    (1)消息本身。不同消息所代表的用户操作和应用程序的状态。
    (2)对于某个特定的消息来说,要让OS执行某个特定的功能去响应消息。
  5. Window程序入口:
    int WINAPI WinMain(
      HINSTANCE hInstance,  // 当前事例句柄。
      HINSTANCE hPrevInstance,  // 先前事例句柄。
      LPSTR lpCmdLine,      // 命令行指针
      int nCmdShow          // (窗口)显示的状态
    );
    说明:WinMain函数是Windows程序入口点函数,由OS调用,当OS启动应用程序的时候,winmain函数的参数由OS传递的。
  6. 创建一个完整的窗口需要经过下面四个操作步骤:
    (1)设计一个窗口类;如:WNDCLASS wndcls;
    (2)注册窗口类;    如:RegisterClass(&wndcls);
    (3)创建窗口;      如:CreateWindow(),CreateWindowEX();
    (4)显示及更新窗口;如:ShowWindow(),UpdateWindow();
  7. Windows提供的窗口类:
    typedef struct _WNDCLASS {
        UINT    style;        //窗口的类型
        WNDPROC lpfnWndProc;  //窗口过程函数指针(回调函数)
        int     cbClsExtra; //窗口类附加字节,为该类窗口所共享。通常0。
        int     cbWndExtra; //窗口附加字节。通常设为0。
        HANDLE  hInstance;  //当前应用程序事例句柄。
        HICON   hIcon;      //图标句柄 LoadIcon();
        HCURSOR hCursor;    //光标句柄 LoadCursor();
        HBRUSH  hbrBackground; //画刷句柄 (HBRUSH)GetStockObject();
        LPCTSTR lpszMenuName;  //菜单名字
        LPCTSTR lpszClassName; //类的名字
    } WNDCLASS;
  8. 窗口类注册:
    ATOM RegisterClass(
      CONST WNDCLASS *lpWndClass   // address of structure with class
                                   // data
    );
  9. 创建窗口:
    HWND CreateWindow(
      LPCTSTR lpClassName,  // pointer to registered class name
      LPCTSTR lpWindowName, // pointer to 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,          // handle to menu or child-window identifier
      HANDLE hInstance,     // handle to application instance
      LPVOID lpParam        // pointer to window-creation data
    );
  10. 显示和更新窗口窗口:
    BOOL ShowWindow(
      HWND hWnd,     // handle to window
      int nCmdShow   // show state of window
    );
    BOOL UpdateWindow(
      HWND hWnd   // handle of window
    );
  11. 消息循环:
    MSG msg;
    while(GetMessage(&msg,...))    //从消息队列中取出一条消息
    {
     TranslateMessage(&msg); //进行消息(如键盘消息)转换
     DispatchMessage(&msg); //分派消息到窗口的回调函数处理,(OS调用窗口回调函数进行处理)。
    }
    其中:
    The GetMessage function retrieves a message from the calling thread's message queue and places it in the specified structure.
    If the function retrieves a message other than WM_QUIT, the return value is nonzero.If the function retrieves the WM_QUIT message, the return value is zero. If there is an error, the return value is -1.
  12. 窗口过程函数(回调函数)原型:
    The WindowProc function is an application-defined function that processes messages sent to a window. The WNDPROC type defines a pointer to this callback function. WindowProc is a placeholder(占位符) for the application-defined function name.

   LRESULT CALLBACK WindowProc(  //这里WindowProc是个代号名字。
     HWND hwnd,      // handle to window
     UINT uMsg,      // message identifier
     WPARAM wParam,  // first message parameter
     LPARAM lParam   // second message parameter
   );

   说明:两种函数调用约定(__stdcall 和 __cdecl):
   #define CALLBACK    __stdcall
   //__stdcall 标准调用预定,是PASCAL 调用约定,象DELPHI使用的就是标准调用约定
   #define WINAPIV     __cdecl 
   // __cdecl 是C 语言形式的调用约定。


  主要区别:函数参数传递顺序 和 对堆栈的清除上。
  问题:除了那些可变参数的函数调用外,其余的一般都是__stdcall约定。但 C/C++编译默然的是__cdecl约  定。所以如果在VC等环境中调用__stdcall约定的函数,必须要在函数声明的时加上 __stdcall 修饰符,以便对这个函数的调用是使用__stdcall约定(如使用DELPHI编写的DLL时候)。
(VC中可通过这途径修改:project|settings..|c/c++|...)


  在窗口过程函数中通过一组switch语句来对消息进行处理:
  如:
  LRESULT CALLBACK WindowProc( 
    HWND hwnd,
    UINT uMsg,
    WPARAM wParam,
    LPARAM lParam  
  )
  {
       switch(uMsg)
       {
       case WM_PAINT:
        ...
         break;
       case ...
         break;
       case WM_CLOSE:
         //DestroyWindow(hwnd);
               //销毁窗口,并发送WM_DESTROY消息。
         break;
       case WM_DESTROY:
         //PostQuitMessage(0);
              //发送WM_QUIT消息到消息队列中,请求终止。
              //GetMessage()取到WM_QUIT消息后,返回0,退出消息循                //   环,从而终止应用程序。
         break;
       default:
         return DefWindowProc(hwnd,uMsg,wParam,lParam);
             //用缺省的窗口过程处理我们不感兴趣的消息(其它消息)。
             //这是必须的。
       }//switch
   return 0;
  }//WindowProc

 13.  DestroyWindow()函数和PostQuitMessage()函数原型:
            //**The DestroyWindow function destroys the specified window. The function sends WM_DESTROY and  WM_NCDESTROY messages。

  BOOL DestroyWindow(
    HWND hWnd   // handle to window to destroy
  );

  VOID PostQuitMessage(
    int nExitCode   // exit code
  );

 14. 关于DC句柄获取:
  a)使用BeginPaint(),EndPaint()对。注意只能在响应WM_PAINT消息时使用。
  b)使用GetDc(),ReleaseDC()对。注意他们不能在响应WM_PAINT中使用。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值