程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 深刻解析C++的WNDCLASS構造體及其在Windows中的運用

深刻解析C++的WNDCLASS構造體及其在Windows中的運用

編輯:關於C++

深刻解析C++的WNDCLASS構造體及其在Windows中的運用。本站提示廣大學習愛好者:(深刻解析C++的WNDCLASS構造體及其在Windows中的運用)文章只能為提供參考,不一定能成為您想要的結果。以下是深刻解析C++的WNDCLASS構造體及其在Windows中的運用正文


WNDCLASS是一個由體系支撐的構造,用來貯存某一類窗口的信息,如ClassStyle,新聞處置函數,Icon,Cursor,配景Brush等。也就是說,CreateWindow只是將某個WNDCLASS界說的窗體釀成實例。要獲得某一窗口的WNDCLASS數據,可以用GetClassLong();
  RegisterClass()就是在體系注冊某一類型的窗體。也就是將你供給的WNDCLASS數據注冊為一個窗口類,在WNDCLASS.lpszClassName中界說該WNDCLASS的標識,不管CreateWindow或CreateWindowEx創立的窗口都必需對應一個WNDCLASS,但一個WNDCLASS可以有多個窗口對象。
  有一些體系預界說的窗口類,如:ClassName=_T("BUTTON" or "COMBOBOX" or "EDIT" or "LISTBOX" or "MDICLIENT" or "SCOLLBAR" or "STATIC"),要用這些窗體,直接用CreateWindow創立響應對象就是了。要獲得某一窗口的窗口類,可以用GetClassName();
  WNDCLASS中的回調函數是窗體的新聞處置函數:CALLBACK WinProc(MESSAGE msg,LPARAM lparam,WPARAM wParam);
窗口類屬性界說
  構造WNDCLASS包括一個窗口類的全體信息,也是Windows編程中應用的根本數據構造之一,運用法式經由過程界說一個窗口類肯定窗口的屬性,界說以下:

typedef struct _WNDCLASS {
  UINT style;
  WNDPROC lpfnWndProc;
  int cbClsExtra;
  int cbWndExtra;
  HINSTANCE hInstance;
  HICON hIcon;
  HCURSOR hCursor;
  HBRUSH hbrBackground;
  LPCTSTR lpszMenuName;
  LPCTSTR lpszClassName;
  } WNDCLASS, *PWNDCLASS;

舉例解釋
例子:

long CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);//聲明
//WinMain函數是一切Windows運用法式的進口,相似c說話中的main函數其功效是完成//一系列的界說和初始化,並發生新聞輪回。函數解釋:
int WINAPI WinMain(HINSTANCE hInstance,    // handle to current instance
               HINSTANCE hPrevInstance, // handle to previous instance
               LPSTR lpCmdLine,       // command line
                int nCmdShow           // show state
)
{
    //初始化,初始化包含窗口類的界說、注冊、創立窗話柄例和顯示窗口四部門
  HWND hwnd;
  MSG Msg;
  WNDCLASS wndclass;
  char lpszClassName[]="窗口"; //窗口類名
  char lpszTitle[]="測試窗口"; //窗口題目名
  //窗口類界說,窗口類界說了窗口的情勢與功效,窗口類界說經由過程給窗口類數據構造WNDCLASS賦值完成
  //該數據構造中包括窗口類的各類屬性
  wndclass.style =0; // 窗口類型為缺省類型CS_   Class Style
  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; //窗口類名為“窗口”
  //以下是窗口類的注冊-----------Windows體系自己供給部門預界說的窗口類,法式員也能夠自界說窗口類,窗口類必需先注冊後應用。
  if(!RegisterClass(&wndclass)) //假如注冊掉敗 收回正告
     {MessageBeep(0); return FALSE;}
  //創立窗口創立一個窗口的實例由函數CreateWindow()完成
  hwnd=CreateWindow( lpszClassName, //窗口類名,創立窗口時必定要基於我們曾經注冊過的窗口類名,即"窗口"。
                    lpszTitle, //窗口題目名
                    WS_OVERLAPPEDWINDOW, //窗口的作風 WS_ Windows Style
                    CW_USEDEFAULT, //窗口左上角坐標值為缺省值 CW_ Create Wndow
                    CW_USEDEFAULT,
                    CW_USEDEFAULT, //窗口的高和寬為缺省值
                     CW_USEDEFAULT,
                    NULL, //此窗口無父窗口
                    NULL, //此窗口無子菜單
                    hInstance, //創立此窗口的運用法式確當前句柄
                    NULL //不應用該值
  );
  //顯示窗口
  ShowWindow(hwnd,nCmdShow);
  //繪制用戶區
  UpdateWindow(hwnd);
  //新聞輪回
  while(GetMessage(&Msg,NULL,0,0)) //GetMessage()函數是從挪用線程的新聞隊列中掏出一條新聞;關於每個運用法式窗口線程,操作體系都邑為其樹立一個新聞隊列,當我們的窗口有新聞時(即一切與這個窗口線程相干的新聞),把持體系會把這個新聞放到該線程的新聞隊列傍邊,我們的窗口法式就經由過程這個GetMessage()函數從本身的新聞隊列中掏出一條一條詳細的新聞並停止呼應操作。
  {
  TranslateMessage(&Msg);//對"新聞對"的轉化,如對鍵盤的WM_KEYDOWN和WM_KEYUP新聞對轉化為WM_CHAR新聞,而且將轉換後的新新聞送達到我們的新聞隊列中去,這個轉化操作不會影響本來的新聞,只會發生一個新的新聞。
  DispatchMessage(&Msg);//DispatchMessage()函數是將我們掏出的新聞傳到窗口的回調函數行止理;可以懂得為該函數將掏出的新聞路由給操作體系,然後操作體系去挪用我們的窗口回調函數對這個新聞停止處置。
    }
  return Msg.wParam; //新聞輪回停止 即法式停止時 將信息前往體系
 }
 
//窗口函數,窗口函數界說了運用法式對吸收到的分歧新聞的呼應,個中包括了運用法式對各類能夠接收到的新聞的處置進程,時新聞處置分支掌握語句的聚集
long CALLBACK WndProc(HWND hwnd,
                   UINT message,
                    WPARAM wParam,
                    LPARAM lParam)
{
  switch(message)
  {
    case WM_DESTROY:
      PostQuitMessage(0);
    default: //缺省時采取體系新聞缺省處置函數
      return DefWindowProc(hwnd,message,wParam,lParam);
  }
  return (0);
}

注:窗口回調函數的函數指針界說typedef LRESULT CALLBACK  (* WNDPROC)(HWND, UINT, WPARAM, LPARAM);

WNDPROC OldWndProc;
LRESULT CALLBACK NewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
    switch (Msg)
    {
      ......
    }
    return CallWindowProc(OldWndProc,g_Wnd,Msg,wParam,lParam);
}
OldWndProc = (WNDPROC)GetWindowLong(g_Wnd,GWL_WNDPROC);
SetWindowLong(hwnd, GWL_WNDPROC,(LPARAM)(WNDPROC)NewWndProc);

經由過程挪用SetWindowLong函數可以修正該窗體類的回調函數。
 
CallBack 函數中的wParam和lParam有甚麼差別:
  WPARAM   wParam,     界說成WORD型
  LPARAM   lParam         界說成LONG型
  在Win 3.x中,WPARAM是16位的,而LPARAM是32位的,二者有顯著的差別。
  在Win32 API中,WPARAM和LPARAM都是32位,所以沒有甚麼實質的差別。
  然則習氣上,我們情願應用LPARAM傳遞地址,而WPARAM傳遞其他參數。

 function MouseHookProc(nCode: Integer; wPar: WPARAM; lPar: LPARAM): lResult; stdcall;

  假如我要斷定鼠標左鍵能否按下,用wParam==WM_LBUTTONDOWN斷定.
  lParam 是 (tagMOUSEHOOKSTRUCT的指針)PMouseHookStruct類型,重要是取得發送窗口句柄,鼠標坐標 ,和其他一些信息 。
  lParam 用的時刻須要強迫轉換,轉換成PMouseHookStruct類型.

PMouseHookStruct = ^TMouseHookStruct; 
tagMOUSEHOOKSTRUCT = packed record 
 pt: TPoint; 
 hwnd: HWND; 
 wHitTestCode: UINT; 
 dwExtraInfo: DWORD; 
end; 
TMouseHookStruct = tagMOUSEHOOKSTRUCT; 

例如:
function GetMsgProc(nCode: Integer; wPara: WPARAM; lPara: LPARAM) 
 : lResult; stdcall; 
var 
 hGetMsgHook:HHOOK;  
 Msg: TMsg; 
begin 
 if (nCode >= 0) then 
 begin 
  FillChar(pMsgData^, Sizeof(TMessageRecord), #0); 
  Msg := TMsg(Pointer(lPara)^); 
 end; 
 Result := CallNextHookEx(hGetMsgHook, nCode, wPara, lPara); 
end; 

 
數據構造原型

typedef struct _WNDCLASS{
          UINT style;
           WNDPROC lpfnWndProc;
           int cbClsExtra;
           int cbWndExtra;
           HANDLE hInstance;
           HICON hIcon;
           HCURSOR hCursor;
           HBRUSH hbrBackground;
           LPCTSTR lpszMenuName;
           LPCTSTR lpszClassName;
}WNDCLASS;

構造解釋
  WNDCLASS 構造包括了RegisterClass函數注冊的類屬性
重量簡介
style: 指定類作風。這些作風可經由過程按位或操作組合起來。作風以下:

  •   CS_BYTEALIGNCLIENT: 在字節界限上(在x偏向上)定位窗口的用戶區域的地位
  •   CS_BYTEALIGNWINDOW: 在字節界限上(在x偏向上)定位窗口的地位
  •   CS_CLASSDC: 該窗口類的一切窗話柄例都同享一個窗口類DC
  •   CS_DBLCLKS: 許可向窗口發送雙擊鼠標鍵的新聞
  •   CS_GLOBALCLASS: 當挪用CreateWindow 或 CreateWindowEx 函數來創立窗口時許可它的hInstance參數和注冊窗口類時傳遞給RegisterClass 的 hInstance參數分歧。假如不指定該作風,則這兩個 hInstance 必需雷同。
  •   CS_HREDRAW: 當程度長度轉變或挪動窗口時,重畫全部窗口
  •   CS_NOCLOSE: 制止體系菜單的封閉選項
  •   CS_OWNDC: 賜與每一個窗話柄例它自己的DC。留意,雖然如許是很便利,但它必需鄭重應用,由於每一個DC年夜約要占800個字節的內存。
  •   CS_PARENTDC: 將子窗口的裁剪區域設置到父窗口的DC中去,如許子窗口即可以在父窗口上繪制本身。留意,這是子窗口照樣從體系緩存中獲得DC,而不是應用父窗口的DC。應用該作風可以進步體系機能。
  •   CS_SAVEBITS: 以位圖情勢保留被該窗口遮擋的屏幕部門,如許當給窗口挪動今後,體系即可以用該保留的位圖恢復屏幕挪動的響應部門,從而體系不消向被該窗口遮擋的窗口發送 WM_PAINT 新聞。該特征關於菜單類型的窗口比擬適合,由於它平日是冗長的顯示一下以後便消逝。設置該特征將增長顯示該窗口的時光,由於它平日要先分派保留位圖的內存。
  •   CS_VREDRAW: 當垂直長度轉變或挪動窗口時,重畫全部窗口
  • lpfnWndProc: 指向窗口進程

cbClsExtra: 指定緊隨在 WNDCLASS 數據構造後分派的字節數。體系將其初始化為零。
cbWndExtra: 指定緊隨在窗話柄例以後分派的字節數,體系將其初始化為零。假如運用法式正在用WNDCLASS構造注冊一個在RC資本描寫文件頂用CLASS指令創立的對話框時,它必需設置這個字段為 DLGWINDOWEXTRA。
hInstance: 標識了該窗口類的窗口進程地點的模塊實例的句柄,不克不及為NULL。
hIcon: 標識了該窗口類的圖標。hIcon字段必需是一個圖標的句柄;若hIcon字段為NULL,則不管什麼時候用戶把運用法式縮至最小時,運用法式必需畫一個圖標。
hCursor: 標識該窗口類的光標,hCursor必需是一個光標資本的句柄。若hCursor字段為NULL,則不管什麼時候鼠標移到運用法式窗口時,運用法式必需顯式設置光標外形。
hbrBackground: 標識了該窗口類的配景畫筆。hbrBackground字段必需是用於繪制配景的物理刷子的句柄,或許是一個色彩的值。假如給出一個色彩的值,它必需是上面列出的尺度體系色彩之一(體系將對所選色彩加1)。假如給出了色彩值,它必需是轉換成以下的HBRUSH類型之一的色彩:

  •   COLOR_ACTIVEBORDER
  •   COLOR_ACTIVECAPTION
  •   COLOR_APPWORKSPACE
  •   COLOR_BACKGROUND
  •   COLOR_BTNFACE
  •   COLOR_BTHSHADOW
  •   COLOR_BTNTEXT
  •   COLOR_CAPTIONTEXT
  •   COLOR_GRAYTEXT
  •   COLOR_HIGHLIGHT
  •   COLOR_HIGHLIGHTTEXT
  •   COLOR_INACTIVEBORDER
  •   COLOR_INACTIVECAPTION
  •   COLOR_MENU
  •   COLOR_MENUTEXT
  •   COLOR_SCROLLBAR
  •   COLOR_WINDOW
  •   COLOR_WINDOWFRAME
  •   COLOR_WINDOWTEXT
  •   當hbrBackground字段為NULL時,每當須要繪制其用戶區域時,運用法式必需本身來繪制其配景。運用法式可以經由過程處置WM_ERASEBKGND 新聞或檢討由 BeginPaint 函數填寫的 PAINTSTRUCT 構造的fErase 字段來肯定配景甚麼時刻須要著色。

lpszMenuName:指向NULL停止的字符串,該字符串描寫菜單的資本名,好像在資本文件裡顯示的名字一樣。若應用一個整數標識菜單,可使用MAKEINTRESOURCE宏。假如lpszMenuName為NULL,
  那末該窗口類的窗口將沒有默許菜單。
lpszClassName:指向NULL停止的字符串,或許是一個原型(atom)。若該參數是一個原型,它必需是一個有先前挪用RegisterClass或許 RegisterClassEx函數發生的類原型。類原型必需作為lpszClassName的低字,高字必需為0.若lpszClassName是一個字符串,它描寫了窗口類名。這個類名可所以由RegisterClass或許RegisterClassEx注冊的名字,或許是任何預界說的控件類名。
  構造信息Header 在winuser.h聲明,包括windows.h

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved