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

📄 032.txt

📁 会变语言实现的一些程序
💻 TXT
📖 第 1 页 / 共 2 页
字号:
	push hInstance
	pop wc.hInstance 
	mov wc.hbrBackground,COLOR_APPWORKSPACE 
	mov wc.lpszMenuName,IDR_MAINMENU
	mov wc.lpszClassName,OFFSET ClassName
	invoke LoadIcon,NULL,IDI_APPLICATION 
	mov wc.hIcon,eax 
	mov wc.hIconSm,eax 
	invoke LoadCursor,NULL,IDC_ARROW 
	mov wc.hCursor,eax    
	invoke RegisterClassEx, addr wc 
	;================================================    
	; 注册MDI子窗口类 
	;================================================    
	mov wc.lpfnWndProc,offset ChildProc 
	mov wc.hbrBackground,COLOR_WINDOW+1 
	mov wc.lpszClassName,offset MDIChildClassName 
	invoke RegisterClassEx,addr wc 
	invoke CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\ 
			WS_OVERLAPPEDWINDOW or WS_CLIPCHILDREN,CW_USEDEFAULT,\    
			CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,0,\ 
			hInst,NULL 
	mov hwndFrame,eax    
	invoke LoadMenu,hInstance, IDR_CHILDMENU 
	mov hChildMenu,eax 
	invoke ShowWindow,hwndFrame,SW_SHOWNORMAL 
	invoke UpdateWindow, hwndFrame 
	.while TRUE 
		invoke GetMessage,ADDR msg,NULL,0,0 
		.break .if (!eax) 
		invoke TranslateMDISysAccel,hwndClient,addr msg 
		.if !eax 
			invoke TranslateMessage, ADDR msg 
			invoke DispatchMessage, ADDR msg 
		.endif 
	.endw 
	invoke DestroyMenu, hChildMenu 
	mov eax,msg.wParam 
	ret 
WinMain endp 

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM 
	LOCAL ClientStruct:CLIENTCREATESTRUCT    
	.if uMsg==WM_CREATE 
		invoke GetMenu,hWnd 
		mov hMainMenu,eax 
		invoke GetSubMenu,hMainMenu,1    
		mov ClientStruct.hWindowMenu,eax 
		mov ClientStruct.idFirstChild,100 
		INVOKE CreateWindowEx,NULL,ADDR MDIClientName,NULL,\ 
				WS_CHILD or WS_VISIBLE or WS_CLIPCHILDREN,CW_USEDEFAULT,\
				CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,hWnd,NULL,\ 
				hInstance,addr ClientStruct    
		mov hwndClient,eax 
		;======================================= 
		; 初始化MDICREATESTRUCT结构
		;======================================= 
		mov mdicreate.szClass,offset MDIChildClassName 
		mov mdicreate.szTitle,offset MDIChildTitle 
		push hInstance    
		pop mdicreate.hOwner 
		mov mdicreate.x,CW_USEDEFAULT 
		mov mdicreate.y,CW_USEDEFAULT    
		mov mdicreate.lx,CW_USEDEFAULT 
		mov mdicreate.ly,CW_USEDEFAULT 
	.elseif uMsg==WM_COMMAND    
		.if lParam==0 
			mov eax,wParam 
			.if ax==IDM_EXIT 
				invoke SendMessage,hWnd,WM_CLOSE,0,0    
			.elseif ax==IDM_TILEHORZ 
				invoke SendMessage,hwndClient,WM_MDITILE,MDITILE_HORIZONTAL,0 
			.elseif ax==IDM_TILEVERT 
				invoke SendMessage,hwndClient,WM_MDITILE,MDITILE_VERTICAL,0    
			.elseif ax==IDM_CASCADE 
				invoke SendMessage,hwndClient,WM_MDICASCADE,MDITILE_SKIPDISABLED,0	   
			.elseif ax==IDM_NEW 
				invoke SendMessage,hwndClient,WM_MDICREATE,0,addr mdicreate   
			.elseif ax==IDM_CLOSE 
				invoke SendMessage,hwndClient,WM_MDIGETACTIVE,0,0 
				invoke SendMessage,eax,WM_CLOSE,0,0 
			.else 
				invoke DefFrameProc,hWnd,hwndClient,uMsg,wParam,lParam	   
				ret
			.endif 
		.endif 
	.elseif uMsg==WM_DESTROY 
		invoke PostQuitMessage,NULL 
	.else 
		invoke DefFrameProc,hWnd,hwndClient,uMsg,wParam,lParam 
		ret 
	.endif 
	xor eax,eax 
	ret 
WndProc endp 

ChildProc proc hChild:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD 
	.if uMsg==WM_MDIACTIVATE    
		mov eax,lParam 
		.if eax==hChild 
			invoke GetSubMenu,hChildMenu,1 
			mov edx,eax 
			invoke SendMessage,hwndClient,WM_MDISETMENU,hChildMenu,edx 
		.else 
			invoke GetSubMenu,hMainMenu,1    
			mov edx,eax 
			invoke SendMessage,hwndClient,WM_MDISETMENU,hMainMenu,edx 
		.endif 
		invoke DrawMenuBar,hwndFrame 
	.elseif uMsg==WM_CLOSE   
		invoke MessageBox,hChild,addr ClosePromptMessage,addr AppName,MB_YESNO 
		.if eax==IDYES    
			invoke SendMessage,hwndClient,WM_MDIDESTROY,hChild,0 
		.endif 
	.else 
		invoke DefMDIChildProc,hChild,uMsg,wParam,lParam    
		ret 
	.endif 
	xor eax,eax 
	ret 
ChildProc endp 
end start 

分析:
程序所做的第一件事情就是注册框架窗口类和MDI子窗口类. 作完这个以后, 程序调用CreateWindowEx来创建框架窗口.用框架窗口的WM_CREATE句柄来创建客户窗口: 


	LOCAL ClientStruct:CLIENTCREATESTRUCT 
	.if uMsg==WM_CREATE 
		invoke GetMenu,hWnd    
		mov hMainMenu,eax 
		invoke GetSubMenu,hMainMenu,1 
		mov ClientStruct.hWindowMenu,eax    
		mov ClientStruct.idFirstChild,100 
		invoke CreateWindowEx,NULL,ADDR MDIClientName,NULL,\    
			WS_CHILD or WS_VISIBLE or WS_CLIPCHILDREN,CW_USEDEFAULT,\ 
			CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,hWnd,NULL,\    
			hInstance,addr ClientStruct 
		mov hwndClient,eax 

我们调用GetMenu来获得框架窗口的菜单的句柄, 这个句柄在调用GetSubMenu时将会被用到. 注意我们将1传递给 GetSubMenu ,因为我们希望显示窗口列表的子菜单是第二个子菜单. 然后我们给CLIENTCREATESTRUCT结构的成员赋值.
下一步我们初始化MDICLIENTSTRUCT 结构. 注意我们不需要在这里做.要初始化MDICLIENTSTRUCT结构的话,用WM_CREATE消息比较方便.

	mov mdicreate.szClass,offset MDIChildClassName 
	mov mdicreate.szTitle,offset MDIChildTitle 
	push hInstance 
	pop mdicreate.hOwner 
	mov mdicreate.x,CW_USEDEFAULT    
	mov mdicreate.y,CW_USEDEFAULT 
	mov mdicreate.lx,CW_USEDEFAULT 
	mov mdicreate.ly,CW_USEDEFAULT

在框架窗口创建之后(也包括客户窗口), 我们调用LoadMenu从资源中获取子窗口的菜单.我们需要获取这个菜单的句柄,这样当一个MDI子菜单出现时,我们就可以用这个句柄来取代框架窗口的菜单. 在这个应用程序退出到Windows之前不要忘记调用DestroyMenu来去掉这个句柄. 正常情况下当一个应用程序退出的时候,Windows将会自动释放和窗口相关的菜单. 但是在这种情况下, 子窗口的菜单没有和任何窗口相关联, 这样即使当应用程序退出后半部 子窗口的菜单仍然会占用宝贵的内存资源.

 

	invoke LoadMenu,hInstance, IDR_CHILDMENU 
	mov hChildMenu,eax 
	........
	invoke DestroyMenu, hChildMenu

在消息循环中我们调用TranslateMDISysAccel.

	.while TRUE 
		invoke GetMessage,ADDR msg,NULL,0,0 
		.break .if (!eax) 
		invoke TranslateMDISysAccel,hwndClient,addr msg 
		.if !eax 
			invoke TranslateMessage, ADDR msg 
			invoke DispatchMessage, ADDR msg 
		.endif 
	.endw 
假如TranslateMDISysAccel 返回一个非零值, 它以为着Windows已经在处理这条消息.这样你就不需要为这条消息做任何事情了.假如返回的值为零, 那么这条消息就不是MDI相关的消息, 因此就必须按照通常情况来处理.


WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM 
	.....
	.else 
		invoke DefFrameProc,hWnd,hwndClient,uMsg,wParam,lParam 
		ret 
	.endif
	xor eax,eax
	ret
WndProc endp
注意到在框架窗口的窗口过程中, 我们调用DefFrameProc来处理我们不感兴趣的消息.

窗口过程的重要之处在 WM_COMMAND句柄. 当用户从文件菜单中选择 "New"时, 我们就创建了一个MDI子窗口.

	.elseif ax==IDM_NEW 
		invoke SendMessage,hwndClient,WM_MDICREATE,0,addr mdicreate

在我们的例子中,我们通过发送WM_MDICREATE消息给客户窗口, 同时还要在lParam参数中传递MDICREATESTRUCT结构的地址来创建一个MDI子窗口.

ChildProc proc hChild:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD 
	.if uMsg==WM_MDIACTIVATE    
		mov eax,lParam 
		.if eax==hChild 
			invoke GetSubMenu,hChildMenu,1 
			mov edx,eax 
			invoke SendMessage,hwndClient,WM_MDISETMENU,hChildMenu,edx 
		.else 
			invoke GetSubMenu,hMainMenu,1    
			mov edx,eax 
			invoke SendMessage,hwndClient,WM_MDISETMENU,hMainMenu,edx 
		.endif    
		invoke DrawMenuBar,hwndFrame 
当MDI子窗口创建后, 我们可以监视 WM_MDIACTIVATE以察看它是不是一个活动窗口.具体的方法是比较将某一个MDI子窗口的句柄和参数lParam的值进行比较, 参数lParam中包含的是活动子窗口的句柄. 这样如果两者匹配的话, 证明这个MDI子窗口就是活动子窗口. 下一步就是将框架窗口的菜单替换成MDI子窗口自身的菜单. 因为最初的菜单将会被取代, 你比学赶帮超再一次告讼Windows窗口列表将显示在哪一个子菜单. 这就是我们必须再一次调用GetSubMenu 来检索子菜单的句柄的原因. 我们发送 WM_MDISETMENU消息给客户窗口来获得想要的结果. WM_MDISETMENU中的wParam参数包含了你希望取代最初的菜单的菜单句柄. lParam参数包含的是你希望用来显示窗口列表的子菜单的句柄.在发送了WM_MDISETMENU之后, 我们调用l DrawMenuBar 来刷新菜单, 否则的话你的菜单将会是一片混乱.

	.else 
		invoke DefMDIChildProc,hChild,uMsg,wParam,lParam 
		ret 
	.endif 
在MDI子窗口的窗口过程中, 你必须传送所有未处理的消息给DefMDIChildProc而不是DefWindowProc.
	.elseif ax==IDM_TILEHORZ 
		invoke SendMessage,hwndClient,WM_MDITILE,MDITILE_HORIZONTAL,0  
	.elseif ax==IDM_TILEVERT 
		invoke SendMessage,hwndClient,WM_MDITILE,MDITILE_VERTICAL,0  
	.elseif ax==IDM_CASCADE 
		invoke SendMessage,hwndClient,WM_MDICASCADE,MDITILE_SKIPDISABLED,0	 
当用户在窗口子菜单中选择一个菜单项时, 我们发送相应的消息给客户窗口. 假如用户选择平铺窗口, 我们发送 WM_MDITILE 给客户窗口, 在wParam参数中指定哪一种类型的平铺. 选择重叠的话是类似的, 相应的发送WM_MDICASCADE..

	.elseif ax==IDM_CLOSE 
		invoke SendMessage,hwndClient,WM_MDIGETACTIVE,0,0    
		invoke SendMessage,eax,WM_CLOSE,0,0 
假如用户选择 "Close" 菜单项, 我们首先必须通过发送WM_MDIGETACTIVE给客户窗口来获得当前活动的MDI子窗口的句柄, 返回的值保存在eax寄存器中, 这个值就是当前活动MDI子窗口的句柄. 获得句柄之后, 我们就可以发送WM_CLOSE给那个窗口了.

	.elseif uMsg==WM_CLOSE 
		invoke MessageBox,hChild,addr ClosePromptMessage,addr AppName,MB_YESNO 
		.if eax==IDYES 
			invoke SendMessage,hwndClient,WM_MDIDESTROY,hChild,0    
		.endif 
在MDI子窗口的窗口过程中, 当收到WM_CLOSE的消息时, 就会显示一个消息框询问用户是否确实想关闭着这个窗口.  假如回答是"是"的话, 我们发送WM_MDIDESTROY给客户窗口. WM_MDIDESTROY关闭MDI子窗口,然后恢复框架窗口的标题.


--------------------------------------------------------------------------------




--------------------------------------------------------------------------------

⌨️ 快捷键说明

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