⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 见招拆招《windows程序设计》(八) .txt

📁 会变语言实现的一些程序
💻 TXT
📖 第 1 页 / 共 5 页
字号:
见招拆招《Windows程序设计》(八) 
    作者:Zoologist 于2008-6-16上传   

--------------------------------------------------------------------------------
子窗口控件 
回忆前面介绍过的CHECKER程序。这些程序显示了矩形网格。当您在一个矩形中按下鼠标按键时,该程序就画一个x;如果您再按一次鼠标按键,那么x就消失。虽然这个程序的CHECKER1和CHECKER2版本只使用一个主窗口,但CHECKER3版本却为每个矩形使用一个子窗口。这些矩形由一个叫做ChildProc的独立窗口消息处理程序维护。

如果有必要,无论矩形是否被选中,都可以给ChildProc增加一种向其父窗口消息处理程序(WndProc)发送消息的手段。通过呼叫GetParent,子窗口消息处理程序能确定其父窗口的窗口句柄:

hwndParent = GetParent (hwnd) ;
        
其中,hwnd是子窗口的窗口句柄。它可以向其父窗口消息处理程序发送消息:

SendMessage (hwndParent, message, wParam, lParam) ;
        
那么message应该设定为什么呢?您可以随意地设定,数值大小可以与WM_USER相同或更大,这些数字代表和预先定义的WM_ 消息不冲突的消息。也许对这个消息,子窗口可以将wParam设定为它的子窗口ID。如果在该子窗口单击,那么lParam可以被设为1;如果未在该子窗口上单击,那么lParam将被设为0。这是处理方式的一种选择。

事实上,这是在建立一个「子窗口控件」。当子窗口的状态改变时,子窗口处理鼠标和键盘消息并通知父窗口。使用这种方法,子窗口就变成了其父窗口的高阶输入设备。它将与自己在屏幕上的图形外观相应的处理,对使用者输入的响应以及在发生重要的输入事件时通知另一个窗口的方法给封装起来。

虽然您可以建立自己的子窗口控件,但是也可以利用一些预先定义的窗口类别(和窗口消息处理程序)来建立标准的子窗口控件,您一定在别的Windows程序中看到过这些控件。这些控件采用的形式有:按钮、复选框、编辑方块、清单方块、下拉式清单方块、字符串卷标和卷动列。例如,如果想在您的电子表格程序的某个角落放置一个标有「Recalculate」的按钮,那么您可以通过呼叫CreateWindow来建立这个按钮。您不必担心鼠标操作、按钮显示操作或按下该按钮时的自动闪烁操作,这些是由Windows内部完成的。您所要做的只是拦截WM_COMMAND消息-当按钮被按下时,它通过这一消息通知您的窗口消息处理程序。真的这样简单吗?是的,一点也没错。

子窗口控件在对话框中最常用。在后面的一章中您将会看到,子窗口控件的位置和尺寸,是在范例程序的资源描述叙述中的对话框模板里定义的。但是,您也可以使用预先定义的,在普通窗口显示区域里的子窗口控件。您可以呼叫一次CreateWindow来建立一个子窗口,并通过呼叫MoveWindow来调整子窗口的位置和尺寸。父窗口消息处理程序向子窗口控件发送消息,子窗口控件向父窗口消息处理程序传回消息。

在建立普通窗口时,首先定义窗口类别,并使用RegisterClass将其注册到Windows中,然后用CreateWindow命令依据该窗口类别建立一个普通窗口,从一开始,我们就是这么做的。但是,当您使用预先定义的某个控件时,不必为子窗口注册窗口类别,窗口类别已经存在于Windows之中,并且有一个预先定义的名字。您只需在CreateWindow中把它们用作窗口类别参数。CreateWindow中的窗口样式参数准确地定义了子窗口控件的外形和功能。Windows内建了处理发送给依据这些窗口类别建立的子窗口消息的窗口消息处理程序。

直接在您的窗口上使用子窗口控件完成某些任务,这些任务的层次低于在对话框中使用子窗口控件所要求的层次。这里,对话框管理器在您的程序和控件之间增加一个隔离层。值得一提的,您可能会发现在您的窗口上建立的子窗口控件,没有利用Tab键或方向键将输入焦点从一个控件移动到另一个控件的内部功能。子窗口控件能够获得输入焦点,但是获得后,它将不能把输入焦点传回给父窗口。这就是本期要解决的问题。

Windows程序设计的文件在两个地方讨论了子窗口控件:首先是,简单的常用控件。这些子窗口包括按钮(其中包括复选框的单选按钮)、静态控件(例如文字卷标)、编辑方块(您可以在此编辑一行或多行文字)、卷动列、清单方块和下拉式清单方块。除下拉式清单方块以外,在Windows 1.0中就包括了这些控件。这部分的Windows文件还包括Rich Text文字编辑控件,它与编辑方块相似,但还允许编辑不同字体与样式的格式化文字,以及桌面应用工具列。

相对于「常用控件」,还有一些神秘的特殊控件。本章不讨论常用控件,但它们将出现在本系列文章的其它部分。在这部分的Windows文件中,很容易找到您想从别的Windows应用程序中应用到您自己的应用程序里头那些部分信息。

按钮类别


下面我们将通过叫做BTNLOOK(「button look」)的程序来开始介绍按钮窗口类别,如程序9-1所示。BTNLOOK建立10个子窗口按钮控件,每个控件对应一个标准的按钮样式,因此共有10种标准按钮样式。

程序9-1 BTNLOOK 

        
BTNLOOK.ASM
;MASMPlus 代码模板 - 普通的 Windows 程序代码

.386
.Model Flat, StdCall
Option Casemap :None

Include windows.inc
Include user32.inc
Include kernel32.inc
Include gdi32.inc

includelib gdi32.lib
IncludeLib user32.lib
IncludeLib kernel32.lib
include macro.asm
	
	WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
	WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
	NUM		equ	(buttonEnd - button) /4 /2
	
.DATA
	szAppName   db "BtnLook",0
	szBtn			db "button",0
	szDraw		db	"WM_DRAWITEM",0
	szCom			db	"WM_COMMAND",0
	
   szTop     db "message   wParam  lParam",0
	szUnd     db "_______   ______  ______",0
	szFormat  db "%-16s%04X-%04X   %04X-%04X",0
                                          
	szBtnStyle01		db	"PUSHBUTTON",0
	szBtnStyle02		db	"DEFPUSHBUTTON",0	
	szBtnStyle03		db	"CHECKBOX",0	
	szBtnStyle04		db	"AUTOCHECKBOX",0	
	szBtnStyle05		db	"RADIOBUTTON",0	
	szBtnStyle06		db	"3STATE",0	
	szBtnStyle07		db	"AUTO3STATE",0	
	szBtnStyle08		db	"GROUPBOX",0	
	szBtnStyle09		db	"AUTORADIO",0	
	szBtnStyle10		db	"OWNERDRAW",0	

button		dd		BS_PUSHBUTTON,			offset szBtnStyle01
				dd		BS_DEFPUSHBUTTON, 	offset szBtnStyle02
				dd		BS_CHECKBOX,			offset szBtnStyle03
				dd		BS_AUTOCHECKBOX,		offset szBtnStyle04		
				dd		BS_RADIOBUTTON,		offset szBtnStyle05				
				dd		BS_3STATE,				offset szBtnStyle06
				dd		BS_AUTO3STATE,			offset szBtnStyle07		
        		dd		BS_GROUPBOX,			offset szBtnStyle08
        		dd		BS_AUTORADIOBUTTON,	offset szBtnStyle09
        		dd		BS_OWNERDRAW,			offset szBtnStyle10
buttonEnd	label	DWORD

.DATA?
	hInstance	dd ?
	hwndButton	HWND NUM dup(?)
	rect		RECT	<?>
	cxChar		dd	?
	cyChar 		dd ?
.CODE
START:

	invoke GetModuleHandle,NULL
	mov hInstance,eax
	invoke WinMain,hInstance,NULL,NULL,SW_SHOWDEFAULT
	invoke ExitProcess,0

WinMain proc hInst:DWORD,hPrevInst:DWORD,CmdLine:DWORD,iCmdShow:DWORD
	LOCAL wndclass   :WNDCLASSEX
	LOCAL msg  :MSG
	local hWnd :HWND
	
	mov wndclass.cbSize,sizeof WNDCLASSEX	
	mov wndclass.style,CS_HREDRAW or CS_VREDRAW	
	mov wndclass.lpfnWndProc,offset WndProc

	mov wndclass.cbClsExtra,0
	mov wndclass.cbWndExtra,0
	
	push hInst
	pop wndclass.hInstance
	
	invoke LoadIcon,NULL,IDI_APPLICATION
	mov wndclass.hIcon,eax	
	
	invoke LoadCursor,NULL,IDC_ARROW
	mov wndclass.hCursor,eax	
	
	invoke GetStockObject,WHITE_BRUSH
	mov wndclass.hbrBackground,EAX
	
	mov wndclass.lpszMenuName,NULL
	mov wndclass.lpszClassName,offset szAppName

	mov wndclass.hIconSm,0
	
	invoke RegisterClassEx, ADDR wndclass
	.if (EAX==0)
		 invoke MessageBox,NULL,CTXT("This program requires Windows NT!"),addr szAppName,MB_ICONERROR 		
		 ret
	.endif
        
	invoke CreateWindowEx,
					NULL,
					ADDR szAppName, 	;window class name
					CTXT("Button Look"), 	;window caption
					WS_OVERLAPPEDWINDOW,	;window style
					CW_USEDEFAULT,		;initial x position
					CW_USEDEFAULT,		;initial y position
					CW_USEDEFAULT, 		;initial x size
					CW_USEDEFAULT,		;initial y size
					NULL,			;parent window handle
					NULL,			;window menu handle
					hInstance,		;program instance handle
					NULL										;creation parameters
	mov hWnd,eax
	
	invoke ShowWindow,hWnd,iCmdShow
	invoke UpdateWindow,hWnd
	
	StartLoop:
		invoke GetMessage,ADDR msg,NULL,0,0
			cmp eax, 0
			je ExitLoop
				invoke TranslateMessage, ADDR msg
				invoke DispatchMessage,  ADDR msg
			jmp StartLoop
	ExitLoop:
	
	mov eax,msg.wParam
	ret

WinMain endp

WndProc proc hwnd:DWORD,uMsg:DWORD,wParam :DWORD,lParam :DWORD
	LOCAL szBuffer[100]	:BYTE
   	LOCAL hdc:HDC
   	LOCAL ps:PAINTSTRUCT
   	LOCAL i :DWORD

	.if uMsg==WM_CREATE
		invoke GetDialogBaseUnits ;cxChar = LOWORD (GetDialogBaseUnits ())
    		and	eax,0FFFFh
     		mov	cxChar,eax
      		
		invoke GetDialogBaseUnits
      		shr	eax,16
      		mov	cyChar,eax	;cyChar = HIWORD (GetDialogBaseUnits ())
        
;LPCREATESTRUCT不是结构,只是一个指向结构CREATESTRUCT的指针.以下是该结构的信息:
;The CREATESTRUCT structure defines the initialization parameters passed to the window procedure of an application.
;typedef struct tagCREATESTRUCT { // cs
;    LPVOID    lpCreateParams;
;    HINSTANCE hInstance;
;    HMENU     hMenu;
;    HWND      hwndParent;
;    int       cy;
;    int       cx;
;    int       y;
;    int       x;
;    LONG      style;
;    LPCTSTR   lpszName;
;    LPCTSTR   lpszClass;
;    DWORD     dwExStyle;
;} CREATESTRUCT;
;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) ;

			
        	mov	i,0
     	nexti:
     		push	NULL
     	  	mov	esi,lParam
     	  	mov	eax,[esi+4]
     	  	push	eax
     	  	push	i
	     	push	hwnd
	     	mov	eax,cyChar
	     	mov	ecx,7
	     	mul	ecx
	     	shr	eax,2
	     	push	eax
	     	mov	eax,cxChar
	     	mov	ecx,20
	     	mul	ecx
	     	push	eax
	 	mov	eax,i
		shl	eax,1
		inc	eax
		mov	ecx,cyChar
		mul	ecx
		push	eax
	  	push	cxChar
		lea	esi,button
		mov	eax,i
		shl	eax,3
		mov	ebx,eax
		mov	eax,button[ebx]
		or	eax,WS_CHILD
		or	eax,WS_VISIBLE
		push	eax
	  	mov	eax,button[ebx+4]
		push	eax
		lea	eax,szBtn
		push	eax
	  	push	NULL
		call	CreateWindowEx
		  
		lea	esi,button
		mov	ebx,i
		shl	ebx,2
		mov	hwndButton[ebx],eax
		  
     	  	inc		i
     	  	mov		eax,i
     	  	cmp		eax,NUM
     	  	jl		nexti
		xor	eax,eax
		ret
		
	.elseif uMsg ==  WM_SIZE
		 mov		eax,cxChar
		 mov		ecx,24
		 mul		ecx
		 mov		rect.left,eax
		 
		 mov		eax,cyChar
		 shl		eax,1
		 mov		rect.top,eax
		 
		 mov		eax,lParam
		 and		eax,0FFFFh
		 mov		rect.right,eax
		 
		 mov		eax,lParam
		 shr		eax,16
		 mov		rect.bottom,eax
		 
		 xor		eax,eax
       		 ret
 	.elseif uMsg ==  WM_PAINT
	        invoke		InvalidateRect,hwnd,addr rect, TRUE
	        invoke		BeginPaint,hwnd,addr ps
	        invoke		GetStockObject,SYSTEM_FIXED_FONT
	        invoke		SelectObject,hdc,eax
		invoke		SetBkMode,hdc, TRANSPARENT
	
	        ;TextOut (hdc, 24 * cxChar, cyChar, szTop, lstrlen (szTop)) ;        
	        invoke		lstrlen,addr szTop
	        push		eax
	        lea		eax,szTop

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -