C++Windows编程之回调机制

来源:互联网 发布:跨区域淘宝客服招聘 编辑:程序博客网 时间:2024/05/22 06:32
前面讲到:C++Windows编程之注册窗口类 
           C++Windows编程之创建窗口
           C++Windows编程之消息循环和消息结构 

        前面已经讲过,最基本的Windows应用由两部分组成:入口函数WinMain和窗口处理函数。窗口处理函数的函数名由程序员自己定义。不过,由于它是毁掉函数,因此它的参数和返回值是固定不变的。窗口处理函数作用是接收与该函数有关的消息,并编写相应的代码。
        回调机制:
        窗体处理函数是回调函数,所谓的“回调”函数,通俗的讲,就是非显示调用。一个回调函数不是在应用程序中显示地进行调用,而是由系统根据情况进行隐式调用。
        我们用Visual Studio创建一个win32项目上自动生成程序代码,在该程序框架中,有两个基本部分:入口函数WinMain和窗口处理函数WndProc。
       应用程序的执行顺序仍然按照WinMain函数中的代码次序,先定义窗口类并进行注册,接着创建 窗口并进行显示,最后进入消息循环,在消息队列中取到WM_QUIT消息退出主循环,结束应用程序。
       在主函数WinMain中,定义和注册窗口类的代码不全是“堆放”在主函数中,而是定义了一个函数MyRegisterClass。
       同样,创建和显示窗口的代码是自定义了一个InitInstance函数来实现这些功能。
       整个类的代码为:
[cpp] view plaincopy
  1. // Win32Project5.cpp : 定义应用程序的入口点。  
  2. //  
  3.   
  4. #include "stdafx.h"  
  5. #include "Win32Project5.h"  
  6.   
  7. #define MAX_LOADSTRING 100  
  8.   
  9. // 全局变量:  
  10. HINSTANCE hInst;                                // 当前实例  
  11. TCHAR szTitle[MAX_LOADSTRING];                  // 标题栏文本  
  12. TCHAR szWindowClass[MAX_LOADSTRING];            // 主窗口类名  
  13.   
  14. // 此代码模块中包含的函数的前向声明:  
  15. ATOM                MyRegisterClass(HINSTANCE hInstance);  
  16. BOOL                InitInstance(HINSTANCEint);  
  17. LRESULT CALLBACK    WndProc(HWNDUINTWPARAMLPARAM);  
  18. INT_PTR CALLBACK    About(HWNDUINTWPARAMLPARAM);  
  19.   
  20. int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,  
  21.                      _In_opt_ HINSTANCE hPrevInstance,  
  22.                      _In_ LPTSTR    lpCmdLine,  
  23.                      _In_ int       nCmdShow)  
  24. {  
  25.     UNREFERENCED_PARAMETER(hPrevInstance);  
  26.     UNREFERENCED_PARAMETER(lpCmdLine);  
  27.     MessageBox(0,(LPCWSTR)"ads",(LPCWSTR)"asd",MB_OK|MB_ICONINFORMATION);  
  28.     MSG msg;  
  29.     HACCEL hAccelTable;  
  30.   
  31.     // 初始化全局字符串  
  32.     LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);  
  33.     LoadString(hInstance, IDC_WIN32PROJECT5, szWindowClass, MAX_LOADSTRING);  
  34.     MyRegisterClass(hInstance);  
  35.   
  36.     // 执行应用程序初始化:  
  37.     if (!InitInstance (hInstance, nCmdShow))  
  38.     {  
  39.         return FALSE;  
  40.     }  
  41.   
  42.     hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WIN32PROJECT5));  
  43.   
  44.     // 主消息循环:  
  45.     while (GetMessage(&msg, NULL, 0, 0))  
  46.     {  
  47.         if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))  
  48.         {  
  49.             TranslateMessage(&msg);  
  50.             DispatchMessage(&msg);  
  51.         }  
  52.     }  
  53.   
  54.     return (int) msg.wParam;  
  55. }  
  56.   
  57.   
  58.   
  59. //  
  60. //  函数: MyRegisterClass()  
  61. //  
  62. //  目的: 注册窗口类。  
  63. //  
  64. ATOM MyRegisterClass(HINSTANCE hInstance)  
  65. {  
  66.     WNDCLASSEX wcex;  
  67.   
  68.     wcex.cbSize = sizeof(WNDCLASSEX);  
  69.   
  70.     wcex.style          = CS_HREDRAW | CS_VREDRAW;  
  71.     wcex.lpfnWndProc    = WndProc;  
  72.     wcex.cbClsExtra     = 0;  
  73.     wcex.cbWndExtra     = 0;  
  74.     wcex.hInstance      = hInstance;  
  75.     wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32PROJECT5));  
  76.     wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);  
  77.     wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);  
  78.     wcex.lpszMenuName   = MAKEINTRESOURCE(IDC_WIN32PROJECT5);  
  79.     wcex.lpszClassName  = szWindowClass;  
  80.     wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));  
  81.   
  82.     return RegisterClassEx(&wcex);  
  83. }  
  84.   
  85. //  
  86. //   函数: InitInstance(HINSTANCE, int)  
  87. //  
  88. //   目的: 保存实例句柄并创建主窗口  
  89. //  
  90. //   注释:  
  91. //  
  92. //        在此函数中,我们在全局变量中保存实例句柄并  
  93. //        创建和显示主程序窗口。  
  94. //  
  95. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow  
  96.                   )  
  97. {  
  98.    HWND hWnd;  
  99.   
  100.    hInst = hInstance; // 将实例句柄存储在全局变量中  
  101.   
  102.    hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,  
  103.       CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);  
  104.   
  105.    if (!hWnd)  
  106.    {  
  107.       return FALSE;  
  108.    }  
  109.   
  110.    ShowWindow(hWnd, nCmdShow);  
  111.    UpdateWindow(hWnd);  
  112.   
  113.    return TRUE;  
  114. }  
  115.   
  116. //  
  117. //  函数: WndProc(HWND, UINT, WPARAM, LPARAM)  
  118. //  
  119. //  目的: 处理主窗口的消息。  
  120. //  
  121. //  WM_COMMAND  - 处理应用程序菜单  
  122. //  WM_PAINT    - 绘制主窗口  
  123. //  WM_DESTROY  - 发送退出消息并返回  
  124. //  
  125. //  
  126. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)  
  127. {  
  128.     int wmId, wmEvent;  
  129.     PAINTSTRUCT ps;  
  130.     HDC hdc;  
  131.   
  132.     switch (message)  
  133.     {  
  134.     case WM_COMMAND:  
  135.         wmId    = LOWORD(wParam);  
  136.         wmEvent = HIWORD(wParam);  
  137.         // 分析菜单选择:  
  138.         switch (wmId)  
  139.         {  
  140.         case IDM_ABOUT:  
  141.             DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);  
  142.             break;  
  143.         case IDM_EXIT:  
  144.             DestroyWindow(hWnd);  
  145.             break;  
  146.         default:  
  147.             return DefWindowProc(hWnd, message, wParam, lParam);  
  148.         }  
  149.         break;  
  150.     case WM_PAINT:  
  151.         hdc = BeginPaint(hWnd, &ps);  
  152.         // TODO: 在此添加任意绘图代码...  
  153.         EndPaint(hWnd, &ps);  
  154.         break;  
  155.     case WM_DESTROY:  
  156.         PostQuitMessage(0);  
  157.         break;  
  158.     default:  
  159.         return DefWindowProc(hWnd, message, wParam, lParam);  
  160.     }  
  161.     return 0;  
  162. }  
  163.   
  164. // “关于”框的消息处理程序。  
  165. INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)  
  166. {  
  167.     UNREFERENCED_PARAMETER(lParam);  
  168.     switch (message)  
  169.     {  
  170.     case WM_INITDIALOG:  
  171.         return (INT_PTR)TRUE;  
  172.   
  173.     case WM_COMMAND:  
  174.         if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)  
  175.         {  
  176.             EndDialog(hDlg, LOWORD(wParam));  
  177.             return (INT_PTR)TRUE;  
  178.         }  
  179.         break;  
  180.     }  
  181.     return (INT_PTR)FALSE;  
  182. }  
在整个函数体中没有一条直接调用WndProc函数的语句,而Wndproc函数在用户的交互过程中又的确执行了,这就是所谓的回调。
0 0
原创粉丝点击