子窗口控件——按钮类别

本文介绍了Windows编程中的按钮控件,包括按键、复选框和单选按钮的类型与用法。讲解了如何设置和获取选中状态,以及如何通过SendMessage函数操作按钮。同时探讨了按钮的可见性和启用状态,以及输入焦点的处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

每个子窗口控件都具有一个在其兄弟中唯一的窗口代号和ID值。
id = GetWindowLong (hwndChild, GWL_ID) ;
id = GetDlgCtrlID (hwndChild) ;
 hwndChild = GetDlgItem (hwndParent, id) ;


    当按钮的高度为文字字符高度的7/4倍时,按钮的外观看起来最好,其中文字字符由BTNLOOK使用;而按钮的宽度至少调节到文字的宽度再加上两个字符的宽度。

   

按键: 按键控件主要用来触发一个立即响应的动作,而不保留任何形式的开/关指示。

          eg:BS_PUSHBUTTON和BS_DEFPUSHBUTTON,BS_DEFPUSHBUTTON中的“DEF”代表“内定”。

复选框:  复选框是一个文字方块,文字通常出现在复选框的右边(如果您在建立按钮时指定了BS_LEFTTEXT样式,                 那么文字会出现在左边;您也许将用BS_RIGHT直接调整文字来组合此样式)。复选框通常用于允许使用者               对选项进行选择的应用程序中。复选框的常用功能如同一个开关:单击框一次将显示勾选标记,再次单击清               除勾选标记.(机长时间记录一个状态!)

              e.g.: BS_CHECKBOX和BS_AUTOCHECKBOX。

单选按钮: 在对话框中,单选按钮组常常用来表示相互排斥的选项。与复选框不同,单选按钮的工作与开关不一样,                 也就是说,当第二次按单选按钮时,它的状态会保持不变。

              e.g: 单选按钮有窗口样式BS_RADIOBUTTON或BS_AUTORADIOBUTTON两种,但是后者只用于对话框。


SendMessage (hwndButton, BM_SETCHECK, 1, 0) ;  表示选中。Auto的会自动选中。

SendMessage (hwndButton, BM_SETCHECK, 0, 0) ;  未选中。



改变按钮文字:

    SetWindowText (hwnd, pszString) ;对于一般的窗口来说,这个文字是标题列的文字;对于按钮控件来说,它是随       着该按钮显示的文字。

 取得窗口目前的文字:    iLength = GetWindowText (hwnd, pszBuffer, iMaxLength) ;

                                         iLength = GetWindowTextLength (hwnd) ;


Windows的字符串函数

正如前面谈到的,Microsoft C包括宽字符和需要字符串参数的C语言运行时期链接库函数的所有普通版本。不过,Windows复制了其中一部分。例如,下面是Windows定义的一组字符串函数,这些函数用来计算字符串长度、复制字符串、连接字符串和比较字符串:

ILength = lstrlen (pString) ;
pString = lstrcpy (pString1, pString2) ;
pString = lstrcpyn (pString1, pString2, iCount) ;
pString = lstrcat (pString1, pString2) ;
iComp = lstrcmp (pString1, pString2) ;
iComp = lstrcmpi (pString1, pString2) ;

理解父亲向子 和 子向父传递消息的形式~!!!

子窗口向父窗口发消息:

当您运行BTNLOOK时,将看到在显示区域的左边会显示出不同的按钮型态。我在前面已经提到过,用鼠标单击按钮时,子窗口控件就向其父窗口发送一个WM_COMMAND消息。BTNLOOK拦截WM_COMMAND消息并显示wParam和lParam的值,它们的含义如下:

LOWORD (wParam)

HIWORD (wParam)

lParam

子窗口ID

通知码

子窗口代号


父窗口向子窗口发送消息

 父窗口消息处理程序也能向子窗口控件发送消息。这些消息包括以前缀WM开头的许多消息。另外,在WINUSER.H中还定义了8个按钮说明消息;前缀BM表示“按钮消息”。这些按钮消息如下表所示:

表9-2
按钮消息
BM_GETCHECK0x00F0
BM_SETCHECK0x00F1
BM_GETSTATE0x00F2
BM_SETSTATE0x00F3
BM_SETSTYLE0x00F4
BM_CLICK0x00F5
BM_GETIMAGE0x00F6
BM_SETIMAGE0x00F7

BM_GETCHECK和BM_SETCHECK消息由父窗口发送给子窗口控件,以取得或者设定复选框和单选按钮的选中标记。

SendMessage (hwndButton, BM_SETCHECK, 1, 0) ;  表示选中。Auto的会自动选中。

SendMessage (hwndButton, BM_SETCHECK, 0, 0) ;  未选中。

BM_GETSTATE和BM_SETSTATE消息表示 按钮处于正常状态还是(鼠标或Spacebar键按下时的)“按下”状态。我们将在讨论按钮的每种型态时,看到这些消息是如何起作用的。BM_SETSTYLE消息允许您在按钮建立之后改变按钮样式。

可是试验后发现都可以通用!!!不知道有什么区别?http://msdn.microsoft.com/zh-cn/magazine/bb775943(en-us,VS.85).aspx  这个说的明白!


可见的和启用的按钮:

当窗口是可见的而未被启用时,那么窗口将以灰色而非黑色显示文字。

                           for(i = 0; i<NUM; i++)
   if(IsWindowVisible(hwndButton[i])) ShowWindow(hwndButton[i], SW_HIDE);
    else  ShowWindow(hwndButton[i], SW_SHOWNORMAL);
          for(i = 0; i<NUM; i++)
if(IsWindowEnabled(hwndButton[i])) EnableWindow(hwndButton[i],FALSE);
else EnableWindow(hwndButton[i],TRUE);


按钮和输入焦点

我在本章前面已经提到过,当用鼠标单击按钮、复选框、单选框和拥有者绘制按钮时,它们接收到输入焦点。这些控件使用文字周围的虚线来表示它拥有了输入焦点。当子窗口控件得到输入焦点时,其父窗口就失去了输入焦点;所有的键盘输入都进入子窗口控件,而不会进入父窗口中。但是,子窗口控件只对Spacebar键作出回应,此时Spacebar键的作用就如同鼠标按键一样。这种情形导致了一个明显的问题:您的程序失去了对键盘处理的控件。!!!


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

#include <windows.h>
#include<windowsx.h>
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 ("AUTORADIO"),
     	BS_OWNERDRAW,            TEXT ("OWNERDRAW")
} ;

#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 ;
		int maxlength;


     	switch (message)
     	{
     	case 	WM_CREATE :
          		cxChar = LOWORD (GetDialogBaseUnits ()) ;
          		cyChar = HIWORD (GetDialogBaseUnits ()) ;

          		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,
                                                  ((LPCREATESTRUCT) lParam)->hInstance, NULL) ;
          		return 0 ;

     	case 	WM_SIZE :
          		rect.left   		= 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_KEYDOWN:
			switch(wParam)
			{
			case VK_UP:
				//SendMessage(hwndButton[2],BM_SETCHECK, 1,  0 );
				SendMessage(hwndButton[3],BM_SETCHECK, 1,  0 );//复选,单选按钮
				SendMessage(hwndButton[5],BM_SETSTATE, 1, 0);  //按钮
				break;
			case VK_DOWN:
				SendMessage(hwndButton[3],BM_SETCHECK, 0, 0);//父向子发送消息
				SendMessage(hwndButton[4],BM_SETSTATE,0,0);
				break;
			case VK_RIGHT:
				SendMessage(hwndButton[3],BM_SETCHECK, 
					       (WPARAM)!SendMessage(hwndButton[3],BM_GETCHECK,0,0), 0);
				break;
			case VK_HOME:
				
				//for(i = 0; i<NUM; i++)
					//if(IsWindowVisible(hwndButton[i])) ShowWindow(hwndButton[i], SW_HIDE);
				    //else  ShowWindow(hwndButton[i], SW_SHOWNORMAL);
				for(i = 0; i<NUM; i++)
					if(IsWindowEnabled(hwndButton[i])) EnableWindow(hwndButton[i],FALSE);
					else EnableWindow(hwndButton[i],TRUE);

				break;
			}
			hdc = GetDC(hwnd);
			if(SendMessage(hwndButton[3],BM_GETCHECK,0,0))
				TextOut(hdc,0,0,TEXT("TRUE"),4);
			else 
				TextOut(hdc,0,0,TEXT("FALSE"),5);
			DeleteObject(hdc);
			//InvalidateRect(hwnd, &rect, TRUE);
			return 0; 

     	case 	WM_DRAWITEM :
     	case 	WM_COMMAND :
          		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) ;

				if((HWND)lParam == hwndButton[0]){//子向父发送消息
					for(i =1; i < NUM; i++){
						maxlength = GetWindowText(hwndButton[i], szBuffer, 40);
					    SetWindowText(hwndButton[i],lstrcat(szBuffer,L"+"));   
					}
				}

				
          		ValidateRect (hwnd, &rect) ;
          		break ;
		/*case WM_KILLFOCUS://系统给正在失去输入焦点的窗口发送一个WM_KILLFOCUS消息
			              //wParam参数是接收输入焦点的窗口的代号。
			  if(hwnd == GetParent((HWND)wParam))
				  SetFocus(hwnd);

			  /*等价于
			        for(i = 0; i<NUM; i++){ 
					    if(hwndButton[i] == (HWND) wParam){
						    SetFocus(hwnd);
							break;
						}
					}
			  */
				
			  return 0;
     	case 	WM_DESTROY :
          		PostQuitMessage (0) ;
          		return 0 ;
     }
     	return DefWindowProc (hwnd, message, wParam, lParam) ;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值