第九章子窗口 The Button Class

//---

注意 在创建子窗口时CreateWindow中的有个参数是用的  ((LPCREATESTRUCT) lParam)->hInstance, 

The instance handle parameter of the CreateWindow call looks a little strange, 
but we're taking advantage of the fact that during a WM_CREATE message lParam is 
actually a pointer to a structure of type CREATESTRUCT ("creation structure") 
that has a member hInstance. So we cast lParam into a pointer to a CREATESTRUCT structure and get hInstance out. 
  (Some Windows programs use a global variable named hInst to give window procedures access 
  to the instance handle available in WinMain. In WinMain, you need to simply set 
     hInst = hInstance ;   
before creating the main window. In the CHECKER3 program in Chapter 7, 
we used GetWindowLong to obtain this instance handle: 
GetWindowLong (hwnd, GWL_HINSTANCE)
  Any of these methods is fine.) 

在WM_CREATE消息中,lparam实际是 LPCREATESTRUCT指针.
该结构体的成员中就包含了应用程序的hInstance,以及常用的坐标(cy,cx,y,x)

  typedef struct tagCREATESTRUCTW {
  LPVOID      lpCreateParams;
   HINSTANCE   hInstance;
   HMENU       hMenu;
   HWND        hwndParent;
  int         cy;
  int         cx;
  int         y;
  int         x;
  LONG        style;
  LPCWSTR     lpszName;
  LPCWSTR     lpszClass;
  DWORD       dwExStyle;
  } CREATESTRUCTW, *LPCREATESTRUCTW;
  #ifdef UNICODE
  typedef CREATESTRUCTW CREATESTRUCT;
  typedef LPCREATESTRUCTW LPCREATESTRUCT;
  #else
  typedef CREATESTRUCTA CREATESTRUCT;
  typedef LPCREATESTRUCTA LPCREATESTRUCT;
  #endif // UNICODE
 */

//---


/*----------------------------------------
   BTNLOOK.C -- Button Look Program
                (c) Charles Petzold, 1998
  ----------------------------------------*/

#include <windows.h>

//button window styles and descriptive text strings for each of the 10 types of buttons. 
// After the CreateWindow call, we needn't do anything more with these child windows. 
//The button window procedure within Windows maintains the buttons for us and handles all repainting jobs. 
//(The exception is the button with the BS_OWNERDRAW style; as I'll discuss later, 
//this button style requires the program to draw the button.) 
struct
{
     int     iStyle ;
     TCHAR * szText ;
}
button[] =
{
     BS_PUSHBUTTON,      TEXT ("PUSHBUTTON"),
     BS_DEFPUSHBUTTON,   TEXT ("DEFPUSHBUTTON"),
     BS_CHECKBOX,        TEXT ("CHECKBOX"), 
     BS_AUTOCHECKBOX,    TEXT ("AUTOCHECKBOX"),
     BS_RADIOBUTTON,     TEXT ("RADIOBUTTON"),
     BS_3STATE,          TEXT ("3STATE"),
     BS_AUTO3STATE,      TEXT ("AUTO3STATE"),
     BS_GROUPBOX,        TEXT ("GROUPBOX"),
     BS_AUTORADIOBUTTON, TEXT ("AUTORADIOBUTTON"),
     BS_OWNERDRAW,       TEXT ("OWNERDRAW") // 这个button style 特别,它
} ;

#define NUM (sizeof button / sizeof button[0])

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

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
     static TCHAR szAppName[] = TEXT ("BtnLook") ;
     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 = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
     wndclass.lpszMenuName  = NULL ;
     wndclass.lpszClassName = szAppName ;
     
     if (!RegisterClass (&wndclass))
     {
          MessageBox (NULL, TEXT ("This program requires Windows NT!"),
                      szAppName, MB_ICONERROR) ;
          return 0 ;
     }
     
     hwnd = CreateWindow (szAppName, TEXT ("Button Look"),
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, iCmdShow) ;
     UpdateWindow (hwnd) ;
     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 HWND  hwndButton[NUM] ;
     static RECT  rect ;
     static TCHAR szTop[]    = TEXT ("message            wParam       lParam"),
                  szUnd[]    = TEXT ("_______            ______       ______"),
                  szFormat[] = TEXT ("%-16s%04X-%04X    %04X-%04X"),
                  szBuffer[50] ;
     static int   cxChar, cyChar ;
     HDC          hdc ;
     PAINTSTRUCT  ps ;
     int          i ;
     
     switch (message)
     {
     case WM_CREATE :
	//	 a function named GetDialogBaseUnits to obtain the width and height of the characters in the default font. 
    //The function returns a 32-bit value comprising a width in the low word and a height in the high word. 
   // GetTextMetrics function 也可以.
          cxChar = LOWORD (GetDialogBaseUnits ()) ; // width 
          cyChar = HIWORD (GetDialogBaseUnits ()) ; // height
          
          for (i = 0 ; i < NUM ; i++)
               hwndButton[i] = CreateWindow ( TEXT("button"), 
                                   button[i].szText,
                                   WS_CHILD | WS_VISIBLE | button[i].iStyle,
                                   cxChar, cyChar * (1 + 2 * i),
                                   20 * cxChar, 7 * cyChar / 4,
                                   hwnd, 
				  (HMENU) i, // 强制转换为菜单ID
                                   ((LPCREATESTRUCT) lParam)->hInstance, 
								   NULL
								   ) ;
          return 0 ;

     case WM_SIZE :
          rect.left   = 24 * cxChar ; // 24个cxChar的宽度的位置
          rect.top    =  2 * cyChar ; // 高
          rect.right  = LOWORD (lParam) ;
          rect.bottom = HIWORD (lParam) ;
          return 0 ;

     case WM_PAINT :
          InvalidateRect (hwnd, &rect, TRUE) ;
          
          hdc = BeginPaint (hwnd, &ps) ;
          SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
          SetBkMode (hdc, TRANSPARENT) ;
          
          TextOut (hdc, 24 * cxChar, cyChar, szTop, lstrlen (szTop)) ;
          TextOut (hdc, 24 * cxChar, cyChar, szUnd, lstrlen (szUnd)) ;
          
          EndPaint (hwnd, &ps) ;
          return 0 ;
          
     case WM_DRAWITEM :
     case WM_COMMAND :
		 /*
		   在WM_COMMAND消息中, wParam,lParam中包含的数据如下
		   LOWORD (wParam) : Child window ID 
		   HIWORD (wParam): Notification code 
		   lParam: Child window handle 
		   
			 
			   Button Notification Code Identifier ----  Value 
			   BN_CLICKED: 0 
			   BN_PAINT: 1 
			   BN_HILITE or BN_PUSHED: 2 
			   BN_UNHILITE or BN_UNPUSHED: 3 
			   BN_DISABLE:4 
			   BN_DOUBLECLICKED or BN_DBLCLK: 5 
			   BN_SETFOCUS: 6 
			   BN_KILLFOCUS: 7 			   

		  */
			// 滚动窗口
          ScrollWindow (hwnd, 0, -cyChar, &rect, &rect) ;
          
          hdc = GetDC (hwnd) ;
          SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
          
          TextOut (hdc, 24 * cxChar, cyChar * (rect.bottom / cyChar - 1),
                   szBuffer,
                   wsprintf (szBuffer, szFormat,
                         message == WM_DRAWITEM ? TEXT ("WM_DRAWITEM") : 
                                                  TEXT ("WM_COMMAND"),
                         HIWORD (wParam), LOWORD (wParam),
                         HIWORD (lParam), LOWORD (lParam))) ;
          
          ReleaseDC (hwnd, hdc) ;
          ValidateRect (hwnd, &rect) ;
          break ;
          
     case WM_DESTROY :
          PostQuitMessage (0) ;
          return 0 ;
     }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值