windows窗口三要素---Win32

在構造窗口應用程序前,先準備好如下變量:
HINSTANCE _hInst;
HWND _hWnd;
TCHAR szClassName[] = TEXT("Test Class");
TCHAR szTitleName[] = TEXT("Test Window");

ATOM MyRegisterClass(HINSTANCE hInstance);    // 註冊窗口類別
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow); // 創建窗口
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); // 窗口消息處理程序


1. 註冊窗口類別
ATOM MyRegisterClass(HINSTANCE hInstance)
{
 WNDCLASSEX wcex;
 wcex.style = CS_HREDRAW | CS_VREDRAW;
 wcex.lpfnWndProc = WndProc;
 wcex.cbClsExtra = 0;
 wcex.cbWndExtra = 0;
 wcex.hInstance = hInstance;
 wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON));
 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
 wcex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
 wcex.lpszMenuName = MAKEINTRESOURCE(IDC_MENU);
 wcex.lpszClassName = szClassName;
 wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

 RegisterClass(&wcex);
}
說明
1) WNDCLASS結構(以UNICODE版本爲例)
typedef struct tagWNDCLASSW {
    UINT        style;   
    WNDPROC     lpfnWndProc;
    int         cbClsExtra;
    int         cbWndExtra;
    HINSTANCE   hInstance;
    HICON       hIcon;
    HCURSOR     hCursor;
    HBRUSH      hbrBackground;
    LPCWSTR     lpszMenuName;
    LPCWSTR     lpszClassName;
} WNDCLASSW, *PWNDCLASSW, NEAR *NPWNDCLASSW, FAR *LPWNDCLASSW;

a)style: 窗口樣式
 #define CS_VREDRAW          0x0001
 #define CS_HREDRAW          0x0002
 #define CS_DBLCLKS          0x0008
 #define CS_OWNDC            0x0020
 #define CS_CLASSDC          0x0040
 #define CS_PARENTDC         0x0080
 #define CS_NOCLOSE          0x0200
 #define CS_SAVEBITS         0x0800
 #define CS_BYTEALIGNCLIENT  0x1000
 #define CS_BYTEALIGNWINDOW  0x2000
 #define CS_GLOBALCLASS      0x4000

b)lpfnWndProc: 窗口類別的窗口消息處理程序,這是一個函數指針
typedef LRESULT (CALLBACK *lpfnWndProc)(HWND, UINT, WPARAM, LPARAM);

c)hInstance: 執行實體句柄

d)lpszMenuName: 指定窗口類別菜單

e)lpszClassName: 窗口類別名稱

f)處理RegisterClass()
if(!RegisterClass(wc))
{
 MessageBox(...);
 return 0;
}

2. 建立窗口
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
 HWND hWnd;
 _hInst = hInstance;
 hWnd = CreateWindow(
     szClassName,
     szTitleName,
     WS_OVERLAPPEDWINDOW,
     CW_USEDEFAULT,
     CW_USEDEFAULT,
     CW_USEDEFAULT,
     CW_USEDEFAULT,
     NULL,
     NULL,
     hInstance,
     NULL);
 if(hWnd==NULL)
  return FALSE;
 
 _hWnd = hWnd;

 ShowWindow(hWnd, nCmdShow);
 UpdateWindow(hWnd);
}

1) 說明
#define CreateWindowW(
   lpClassName,  // 窗口類名稱
   lpWindowName,  // 窗口標題名稱
   dwStyle,   // 窗口樣式
   x,     // x座標
   y,     // y座標
   nWidth,    // width
   nHeight,   // height
   hWndParent,   // 父窗口
   hMenu,    // 菜單
   hInstance,   // 執行實體句柄
   lpParam)   // lParam

dwStyle: 窗口樣式
 #define WS_OVERLAPPED       0x00000000L
 #define WS_POPUP            0x80000000L
 #define WS_CHILD            0x40000000L
 #define WS_MINIMIZE         0x20000000L
 #define WS_VISIBLE          0x10000000L
 #define WS_DISABLED         0x08000000L
 #define WS_CLIPSIBLINGS     0x04000000L
 #define WS_CLIPCHILDREN     0x02000000L
 #define WS_MAXIMIZE         0x01000000L
 #define WS_CAPTION          0x00C00000L     /* WS_BORDER | WS_DLGFRAME  */
 #define WS_BORDER           0x00800000L
 #define WS_DLGFRAME         0x00400000L
 #define WS_VSCROLL          0x00200000L
 #define WS_HSCROLL          0x00100000L
 #define WS_SYSMENU          0x00080000L
 #define WS_THICKFRAME       0x00040000L
 #define WS_GROUP            0x00020000L
 #define WS_TABSTOP          0x00010000L

 #define WS_MINIMIZEBOX      0x00020000L
 #define WS_MAXIMIZEBOX      0x00010000L


 #define WS_TILED            WS_OVERLAPPED
 #define WS_ICONIC           WS_MINIMIZE
 #define WS_SIZEBOX          WS_THICKFRAME
 #define WS_TILEDWINDOW      WS_OVERLAPPEDWINDOW

    /*
    * Common Window Styles
    */
 #define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED     | /
  WS_CAPTION        | /
  WS_SYSMENU        | /
  WS_THICKFRAME     | /
  WS_MINIMIZEBOX    | /
  WS_MAXIMIZEBOX)

 #define WS_POPUPWINDOW      (WS_POPUP          | /
  WS_BORDER         | /
  WS_SYSMENU)

 #define WS_CHILDWINDOW      (WS_CHILD)

3. 消息循環
MSG msg;
while(GetMessage(&msg, NULL, 0, 0))
{
 TranslateMessage(&msg);
 DispatchMessage(&msg);
}

1)MSG結構
typedef struct tagMSG {
 HWND        hwnd;  // 窗口句柄
 UINT        message; // message,以WM_開頭的一系列消息
 WPARAM      wParam;  // 消息參數
 LPARAM      lParam;  // 消息參數
 DWORD       time;  // 消息放入消息隊列時間
 POINT       pt;   // 消息放入消息隊列時的鼠標座標
#ifdef _MAC
 DWORD       lPrivate;
#endif
} MSG, *PMSG, NEAR *NPMSG, FAR *LPMSG;

Windows負責爲每個應用程序維護一個消息隊列,當用戶觸發窗口事件時,windows將該事件轉換成相應的消息,放入消息隊列中;
GetMessage()從消息隊列中取出消息,經過TranslateMessage();
DispatchMessage()再將消息傳遞給windows,由windows調用相應窗口的窗口處理程序

2)窗口消息處理程序
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 HDC hdc;
 PAINTSTRUCT ps;
 int wmId, wmEvetn;

 switch(message)
 {
 case WM_CREATE:
  ... ... ;
  break;

 case WM_SIZE:
  // TODO
  break;

 case WM_COMMAND:
  wmId    = LOWORD(wParam);
  wmEvent = HIWORD(wParam);
  // Parse the menu selections:
  switch (wmId)
  {
  case IDM_ABOUT:
   DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
   //DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
   break;
  case IDM_EXIT:
   DestroyWindow(hWnd);
   break;
  default:
   return DefWindowProc(hWnd, message, wParam, lParam);
  }
  break;

 case WM_PAINT:
  BeginPaint(hWnd, &ps);
  // TODO ...
  EndPaint(hWnd, &ps);
  break;

 case WM_DESTROY:
  PostQuitMessage(0);
  break;
 default:
  return DefWindowProc(hWnd, message, wParam, lParam);
 }
 return 0;
}
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章