注冊窗口類


一、MFC應用程序與win32應用程序的區別

  Win32編程:是調用Win32SDK中的API函數進行編程,注冊窗口類,建立窗口,現實窗口,設置消息循環……等等的方式建立Windows程序,以前的Windows程序都這樣開發的,寫程序要寫大量代碼。

  MFC庫:后來微軟為了方便編程人員開發,將Win32SDK中的函數進行C/C++封裝,於是就是MFC庫(架構),開發程序比以往的Win32SDK方式更加簡便快捷。

  相同:調用的API都是Win32SDK的API

  不同:MFC的程序執行起來慢,而且用MFC寫程序不自由

   Win32SDK開發速度慢,而且要編寫的代碼多得驚人

1.win32應用程序注冊窗口類

  一般在Win32下編程,簡單的步驟是:
  (1)設計窗口類
  (2) 注冊窗口類
  (3)Create窗口
  (4)顯示窗口
  (5)更新窗口
  (6)消息循環(關鍵)

  我們用Visual Studio創建一個win32項目上會自動生成一個注冊窗口類。如下:

 1 ATOM MyRegisterClass(HINSTANCE hInstance)
 2 {
 3     WNDCLASSEX wcex;
 4 
 5     wcex.cbSize = sizeof(WNDCLASSEX);                    // UINT    cbSize   6 
 7     wcex.style          = CS_HREDRAW | CS_VREDRAW;       // UINT    style  8     wcex.lpfnWndProc    = WndProc;              // WNDPROC  lpfnWndProc  9     wcex.cbClsExtra     = 0;                  // int    cbClsExtra 10     wcex.cbWndExtra     = 0;                  // int    cbWndExtra 11     wcex.hInstance      = hInstance;             // HINSTANCE hInstance 12     wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32PROJECT5));  // HICON hIcon 13     wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);  // HCURSOR  hCursor 14     wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);    // HBRUSH   hbrBackground 15     wcex.lpszMenuName   = MAKEINTRESOURCE(IDC_WIN32PROJECT5); // LPCTSTR lpszMenuName 16     wcex.lpszClassName  = szWindowClass;          // LPCTSTR   lpszClassName 17     wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));     // HICON hIconSm 18 
19     return RegisterClassEx(&wcex);
20 }

WNDCLASSEX結構體中:
  cbSize:存儲表示該結構大小的字節數,通常以sizeof(WNDCLASSEX)的形式對該域進行設置

  style :存儲表示窗口類風格的整數,它決定了該窗口的外觀和內在特征。

  lpfnWndProc指向窗口處理函數(回調函數)。

  cbClsExtra為窗口類的額外信息做記錄,初始化為0

  cbWndExtra記錄窗口實例的額外信息,系統初始為0

  hIcon :存儲該類窗口的圖標的句柄

  hCursor:存貯表示窗口類光標的句柄,該域必須是一個光標資源的句柄。

  hbrBackground窗口類的背景刷,為背景刷句柄,也可以為系統顏色值,如果顏色值已給出,則必須轉化為以下的HBRUSH的值

  lpszMenuName:存儲以空結尾的指定類菜單資源名的字符串指針,類菜單資源名已經在資源文件中進行了定義。

  lpszClassName:存儲以空結尾的字符串的指針,或存儲一個原子元素(ATOM)。

  hIConSm:存儲該類窗口小圖標的句柄。

 

 2.MFC應用程序注冊窗口類

  MFC下編程,省去了窗口設計步驟,直接通過GetClassInfo()來獲取標准窗口的信息。

  MFC中,#32770 代表標准窗口類

BOOL CBBBApp::SetRegisterClass()
{
    WNDCLASS wndcls;
    ZeroMemory(&wndcls, sizeof(WNDCLASS));   // start with NULL

    HINSTANCE hInst;
    hInst = AfxGetInstanceHandle();
    ASSERT(hInst != 0);
GetClassInfo(hInst, _T("#32770"), &wndcls); wndcls.lpszClassName = _T("YourClassName"); if (FALSE == AfxRegisterClass(&wndcls)) { AfxThrowResourceException(); return FALSE; } return TRUE; }

1)AfxGetInstanceHandle

  作用獲取當前實例句柄

  原型HINSTANCE AFXAPI AfxGetInstanceHandle( );

  返回值返回應用程序當前實例的句柄。如果是從與MFC的USRDLL版本連接的DLL內調用的,則返回代表DLL的HINSTANCE值

 

2)GetClassInfo

  作用:獲得窗體類信息

  原型

  BOOL GetClassInfo(      
      HINSTANCE hInstance,
      LPCTSTR lpClassName,
      LPWNDCLASS lpWndClass
  );

  參數hInstance,創建類的應用程序實例

          lpClassName,類名

       lpWndClass,指向WNDCLASS結構體的指針

  返回值:返回非零成功,返回零不成功

 

3)AfxRegisterClass

  作用:注冊類

  原型:BOOL AFXAPI AfxRegisterClass( WNDCLASS* lpWndClass );

  參數:指向WNDCLASS結構體的指針

  返回值:若類成功注冊則返回零,否則非零。

 

4)AfxThrowResourceException

  這個函數拋出一個資源異常。通常在不能載入Windows資源的時候調用這個函數。

 

3.注冊窗口類的目的

  

  1)注冊窗口類以后同一類窗口都用一套WindowProc。有統一的行為

  在我們構造一個窗口類結構后,我們需要將這個類結構指針加入到system atom table 即SAT中,這樣系統就可以通過查找這張表來找到用戶自定義的窗口類

  2)注冊好窗口類之后就可以用FindWindow函數來找到這個窗口類並獲得其句柄,然后即可以向該窗口發送消息。

    HWND hComm = ::FindWindow(_T("YourClassName"), NULL);
    if (NULL == hComm)  return FALSE;
if (hComm && ::IsWindow(hComm)) { DWORD dwResult = 0; LRESULT lResult = ::SendMessageTimeout(hComm, WM_NULL, 0, 0, SMTO_ABORTIFHUNG, 500, &dwResult); }

1)FindWindow
  作用:該函數獲得一個頂層窗口的句柄,該窗口的類名和窗口名與給定的字符串相匹配。

  原型

  HWND FindWindow(
    LPCSTR lpClassName,      // {即窗口的類名}
    LPCSTR lpWindowName   // {即窗口的標題} 如果此參數為NULL,則匹配所有窗口名。
  );
   返回值
    如果函數執行成功,則返回值是擁有指定窗口類名或窗口名的窗口的句柄。
    如果函數執行失敗,則返回值為 NULL
 
2)FindWindowEX
  //FindWindowEx 比 FindWindow 多出兩個句柄參數:
  FindWindowEx(
    Parent: HWND;     {要查找子窗口的父窗口句柄}
    Child: HWND;        {子窗口句柄}
    ClassName: PChar; {}
    WindowName: PChar {}
  ): HWND;
  {
  如果 Parent 是 0, 則函數以桌面窗口為父窗口, 查找桌面窗口的所有子窗口;
  如果  是 HWND_MESSAGE, 函數僅查找所有消息窗口;
  子窗口必須是 Parent 窗口的直接子窗口;
  如果 Child 是 0, 查找從 Parent 的第一個子窗口開始;
  如果 Parent 和 Child 同時是 0, 則函數查找所有的頂層窗口及消息窗口.
  }
 

2)SendMessageTimeout

  作用:該函數將指定的消息發送到一個或多個窗口。

  原型

  LRESULT SendMessageTimeout(
    HWND hwnd,        // 其窗口程序將接收消息的窗口的句柄。
                // 如果此參數為HWND_BROADCAST,則消息將被發送到系統中所有頂層窗口,包括無效或不可見的非自身擁有的窗口。
    UINT Msg,            // 指定被發送的消息
    WPARAM wParam,// 指定附加的消息指定信息。
    LPARAM IParam,  // 指定附加的消息指定信息。
    UINT fuFlags,  // 指定如何發送消息。
              // SMTO_ABORTIFHUNG:如果接收進程處於“hung”狀態,不等待超時周期結束就返回。
              // SMTO_BLOCK:阻止調用線程處理其他任何請求,直到函數返回。
  
              // SMTO_NORMAL:調用線程等待函數返回時,不被阻止處理其他請求。
              // SMTO_NOTIMEOUTIFNOTHUNG:Windows 95及更高版本:如果接收線程沒被掛起,當超時周期結束時不返回。
    UIUT uTimeout,  // 為超時周期指定以毫秒為單位的持續時間。如果GetLastError返回零,表明函數超時
    LPDWORD lpdwResultult // 指定消息處理的結果,依賴於所發送的消息
  );

  返回值:若函數調用成功則返回非零值,若失敗或超時返回零。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM