sdk筆記3

第十章

hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_ICON)) ;

取得圖示的句柄。使用敘述

cxIcon = GetSystemMetrics (SM_CXICON) ;     

cyIcon = GetSystemMetrics (SM_CYICON) ;      

取得圖示的大小。然後,程序通過多次呼叫

DrawIcon (hdc, x, y, hIcon) ;

#define MAKEINTRESOURCE(i)  (LPTSTR) ((DWORD) ((WORD) (i)))

       

hMenu = LoadMenu (hInstance, TEXT ("MyMenu")) ;    

如果使用了數值,那麼LoadMenu呼叫採用如下的形式:

hMenu = LoadMenu (hInstance, MAKEINTRESOURCE (ID_MENU)) ;

然後,您可以將這個菜單句柄作爲CreateWindow的第九個參數:

hwnd=CreateWindow(TEXT("MyClass"),TEXT("WindowCaption"),WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT,NULL, hMenu, hInstance, NULL) ;

您也可以在窗口類別中指定NULL菜單,並且在CreateWindow呼叫中也指定NULL菜單,然後在窗口被建立後再給窗口指定一個菜單:

SetMenu (hwnd, hMenu) ;

第十一章

與窗口消息處理程序類似,對話框程序都必須定義爲一個CALLBACKcallback)函數。儘管我使用了hDlg作爲對話框窗口的句柄,但是您也可以按照您自己的意思使用hwnd。首先,讓我們來看一下這個函數與窗口消息處理程序的區別:

· 窗口消息處理程序傳回一個LRESULT。對話框傳回一個BOOL,它在Windows表頭文件中定義爲int型態。
 

· 如果窗口消息處理程序不處理某個特定的消息,那麼它將呼叫DefWindowProc。如果對話框程序處理一個消息,那麼它傳回TRUE(非0),如果不處理,則傳回FALSE0)。
 

· 對話框程序不需要處理WM_PAINTWM_DESTROY消息。對話框程序不接收WM_CREAT消息,而是在特殊的WM_INITDIALOG消息處理期間,對話框程序執行初始化操作。
 

WM_INITDIALOG消息是對話框接收到的第一個消息,這個消息只發送給對話框程序。如果對話框程序傳回TRUE,那麼Windows將輸入焦點設定給對話框中第一個具有WS_TABSTOP樣式(我們將在ABOUT2的討論中加以解釋)的子窗口控件。在這個對話框中,第一個具有WS_TABSTOP樣式的子窗口控件是按鍵。另外,對話框程序也可以在處理WM_INITDIALOG時使用SetFocus來將輸入焦點設定爲對話框中的某個子窗口控件,然後傳回FALSE

此外,對話框程序只處理WM_COMMAND消息。這是當按鍵被鼠標點中,或者在按鈕具有輸入焦點的情況下按下空格鍵時,按鍵控件發送給其父窗口的消息。這個控件的ID(我們在對話框模板中將其設定爲IDOK)在wParam的低字組中。對於這個消息,對話框過程調用EndDialog,它告訴Windows清除對話框。對於所有其它消息,對話框程序傳回FALSE,並告訴Windows內部的對話框窗口消息處理程序:我們的對話框程序不處理這些消息。

模態對話框的消息不通過您程序的消息隊列,所以不必擔心對話框中鍵盤快捷鍵的影響。

即使在顯示對話框時,WndProc也可以繼續接收消息。實際上,您可以從對話框程序內部給WndProc發送消息。ABOUT1的主窗口是彈出式對話框窗口的父窗口,所以AboutDlgProc中的SendMessage呼叫可以使用如下敘述來開始:

SendMessage (GetParent (hDlg),  . . . ) ;

也許您希望受益於Windows對話框管理器,但不希望(或者能夠)在資源描述中定義對話框模板,也可能您希望程序在執行時可以動態地建立對話框。這時可以完成這種功能的函數是DialogBoxIndirect,此函數用數據結構來定義模板。

非模態對話框
您已經看到,模態對話框是用DialogBox來建立的。只有在清除對話框之後,函數纔會傳回值。在對話框程序內使用EndDialog呼叫來終止對話框,DialogBox傳回的是該呼叫的第二個參數的值。非模態對話框是使用CreateDialog來建立的,該函數所使用的參數與DialogBox相同。

hDlgModeless = CreateDialog (      hInstance, szTemplate,hwndParent, DialogProc) ;

區別是CreateDialog函數立即傳回對話框的窗口句柄,並通常將這個窗口句柄存放到整體變量中。

使用非模態對話框與使用模態對話框相似,但是也有一些重要的區別:

首先,非模態對話框通常包含一個標題列和一個系統菜單按鈕。當您在Developer Studio中建立對話框時,這些是內定選項。用於非模態對話框的對話框模板中的STYLE敘述形如:

STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE

如果省略了WS_VISIBLE,那麼您必須在CreateDialog呼叫之後呼叫ShowWindow

與模態對話框和消息框的消息不同,非模態對話框的消息要經過程序式的消息隊列。要將這些消息傳送給對話框窗口消息處理程序,則必須改變消息隊列。方法如下:當您使用CreateDialog建立非模態對話框時,應該將從呼叫中傳回的對話框句柄儲存在一個整體變量(如hDlgModeless)中,並將消息循環改變爲:

while (GetMessage (&msg, NULL, 0, 0))         

{                     

if (hDlgModeless == 0 || !IsDialogMessage (hDlgModeless, &msg))              

{                            

TranslateMessage (&msg) ;                           

DispatchMessage  (&msg) ;              

}         

}

如果消息是發送給非模態對話框的,那麼IsDialogMessage將它發送給對話框中窗口消息處理程序,並傳回TRUE(非0);否則,它將傳回FALSE0)。只有hDlgModeless0或者消息不是該對話框的消息時,才必須呼叫TranslateMessageDispatchMessage函數。如果您將鍵盤快捷鍵用於您的程序窗口,那麼消息循環將如下所示:

while (GetMessage (&msg, NULL, 0, 0))         

{                     

if (hDlgModeless == 0 || !IsDialogMessage (hDlgModeless, &msg))                     

{                            

if (!TranslateAccelerator (hwnd, hAccel, &msg))                           

{                                                   

TranslateMessage(&msg);                                                    DispatchMessage  (&msg) ;                            

}              

}         

}

一個非模態對話框的例子

/*------------------------------------------------

   COLORS2.C -- Version using Modeless Dialog Box

                (c) Charles Petzold, 1998

  ------------------------------------------------*/

#include <windows.h>

#include "resource.h"

LRESULT CALLBACK WndProc     (HWND, UINT, WPARAM, LPARAM) ;

BOOL    CALLBACK ColorScrDlg (HWND, UINT, WPARAM, LPARAM) ;

HWND hDlgModeless ;

HINSTANCE hinst;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

                    PSTR szCmdLine, int iCmdShow)

{

     static TCHAR szAppName[] = TEXT ("Colors2") ;

     HWND         hwnd ;

     MSG          msg ;

     WNDCLASS     wndclass ;

     

     wndclass.style         = CS_HREDRAW | CS_VREDRAW ;

     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 = CreateSolidBrush (0L) ;

     wndclass.lpszMenuName  = (LPCSTR)IDR_MENU1;

//  wndclass.lpszMenuName  = NULL;

     wndclass.lpszClassName = szAppName ;

     hinst=hInstance;

     if (!RegisterClass (&wndclass))

     {

          MessageBox (NULL, TEXT ("This program requires Windows NT!"),

                      szAppName, MB_ICONERROR) ;

          return 0 ;

     }

     

     hwnd = CreateWindow (szAppName, TEXT ("Color Scroll"),

                          WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,

                          CW_USEDEFAULT, CW_USEDEFAULT,

                          CW_USEDEFAULT, CW_USEDEFAULT,

                          NULL, NULL, hInstance, NULL) ;

     

     ShowWindow (hwnd, iCmdShow) ;

     UpdateWindow (hwnd) ;

     

     hDlgModeless = CreateDialog (hInstance, dialog1, 

                                  hwnd, ColorScrDlg) ;

 ShowWindow (hDlgModeless, SW_HIDE) ;

    

     while (GetMessage (&msg, NULL, 0, 0))

     {

          if (hDlgModeless == 0 || !IsDialogMessage (hDlgModeless, &msg))

          {

               TranslateMessage (&msg) ;

               DispatchMessage  (&msg) ;

          }

     }

     return msg.wParam ;

}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

{

     switch (message)

     {

 case WM_COMMAND:

 if (LOWORD(wParam) == ID_MENUITEM40001)

 {

 ShowWindow(hDlgModeless,SW_SHOWNORMAL);

 }

 return 0;

  

case WM_DESTROY :

          DeleteObject ((HGDIOBJ) SetClassLong (hwnd, GCL_HBRBACKGROUND,

                              (LONG) GetStockObject (WHITE_BRUSH))) ;

          PostQuitMessage (0) ;

          return 0 ;

     }

     return DefWindowProc (hwnd, message, wParam, lParam) ;

}

BOOL CALLBACK ColorScrDlg (HWND hDlg, UINT message, 

                           WPARAM wParam, LPARAM lParam)

{

     static int iColor[3] ;

     HWND       hwndParent, hCtrl ;

     int        iCtrlID, iIndex ;

     

     switch (message)

     {

     case WM_INITDIALOG :

          for (iCtrlID = 10 ; iCtrlID < 13 ; iCtrlID++)

          {

               hCtrl = GetDlgItem (hDlg, iCtrlID) ;

               SetScrollRange (hCtrl, SB_CTL, 0, 255, FALSE) ;

               SetScrollPos   (hCtrl, SB_CTL, 0, FALSE) ;

          }

          return TRUE ;

          

     case WM_VSCROLL :

          hCtrl   = (HWND) lParam ;

          iCtrlID = GetWindowLong (hCtrl, GWL_ID) ;

          iIndex  = iCtrlID - 10 ;

          hwndParent = GetParent (hDlg) ;

          

          switch (LOWORD (wParam))

          {

          case SB_PAGEDOWN :

               iColor[iIndex] += 15 ;        // fall through

          case SB_LINEDOWN :

               iColor[iIndex] = min (255, iColor[iIndex] + 1) ;

               break ;

          case SB_PAGEUP :

               iColor[iIndex] -= 15 ;        // fall through

          case SB_LINEUP :

               iColor[iIndex] = max (0, iColor[iIndex] - 1) ;

               break ;

          case SB_TOP :

               iColor[iIndex] = 0 ;

               break ;

          case SB_BOTTOM :

               iColor[iIndex] = 255 ;

               break ;

          case SB_THUMBPOSITION :

          case SB_THUMBTRACK :

               iColor[iIndex] = HIWORD (wParam) ;

               break ;

          default :

               return FALSE ;

          }

          SetScrollPos  (hCtrl, SB_CTL,      iColor[iIndex], TRUE) ;

          SetDlgItemInt (hDlg,  iCtrlID + 3, iColor[iIndex], FALSE) ;

          

          DeleteObject ((HGDIOBJ) SetClassLong (hwndParent, GCL_HBRBACKGROUND,

                              (LONG) CreateSolidBrush (

                                   RGB (iColor[0], iColor[1], iColor[2])))) ;

          

          InvalidateRect (hwndParent, NULL, TRUE) ;

          return TRUE ;

     }

     return FALSE ;

}

以對話框爲主體的程序,注意這點

wndclass.cbWndExtra    = DLGWINDOWEXTRA ;    // Note!

分配給窗口實例的額外字節數,初始化爲0,如果程序用WNDCLASS註冊由資源文件裏的CLASS指令創建的對話框時,它的值必須設置爲DLGWINDOWEXTRA.

/*----------------------------------------

   HEXCALC.C -- Hexadecimal Calculator

                (c) Charles Petzold, 1998

  ----------------------------------------*/

#include <windows.h>

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

                    PSTR szCmdLine, int iCmdShow)

{

     static TCHAR szAppName[] = TEXT ("HexCalc") ;

     HWND         hwnd ;

     MSG          msg ;

     WNDCLASS     wndclass ;

    

     wndclass.cbWndExtra    = DLGWINDOWEXTRA ;    // Note!

     

     if (!RegisterClass (&wndclass))

     {

     }

     

     hwnd = CreateDialog (hInstance, szAppName, 0, NULL) ;

     

     ShowWindow (hwnd, iCmdShow) ;

     

     while (GetMessage (&msg, NULL, 0, 0))

     {

          TranslateMessage (&msg) ;

          DispatchMessage (&msg) ;

     }

     return msg.wParam ;

}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

{

     static BOOL  bNewNumber = TRUE ;

     static int   iOperation = '=' ;

     static UINT  iNumber, iFirstNum ;

     HWND         hButton ;

     

     switch (message)

     {

     case WM_KEYDOWN:                   // left arrow --> backspace

          if (wParam != VK_LEFT)

               break ;

          wParam = VK_BACK ;

    

                                     

     case WM_COMMAND:

          SetFocus (hwnd) ;

          

          if (LOWORD (wParam) == VK_BACK)         // backspace

               ShowNumber (hwnd, iNumber /= 16) ;

          

       

          

     case WM_DESTROY:

          PostQuitMessage (0) ;

          return 0 ;

     }

     return DefWindowProc (hwnd, message, wParam, lParam) ;

}


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