您的位置:首页 > 其它

Win32汇编教程6-工具栏和状态栏的使用

2010-07-29 21:36 471 查看
有关工具栏和状态栏

工具栏和状态栏也是Windows标准界面的组成部分,工具栏一般位于菜单栏的下方,上面是一些系统定义的或自己定义的图片,可以通俗地显示这个按钮的作
用。状态栏一般位于窗口的最下方,用来显示程序运行中的一些信息。工具栏和状态栏是Windows系统的两个通用的控件,你可以通过两个专用的 API
或者利用 CreateWindowEx 再使用制定的已经由系统定义的类来创建它们。这两个 API 分别是 CreateToolbarEx 和
CreateStatusWindow。下面将一下它们的用法。

CreateToolbarEx 的声明为:

HWND CreateToolbarEx(

HWND hwnd,

DWORD ws,

UINT wID,

int nBitmaps,

HINSTANCE hBMInst,

UINT wBMID,

LPCTBBUTTON lpButtons,

int iNumButtons,

int dxButton,

int dyButton,

int dxBitmap,

int dyBitmap,

UINT uStructSize}

它的参数中 hwnd 是父窗口(也就是我们的主窗口)的句柄,ws 是工具栏的风格,可以由几项合成,如 WS_VISIBLE
是创建是可见,TBSTYLE_FLAT表示平面按钮,WS_BORDER表示有边线等,具体可以见手册。wID 是工具栏的标识,nBitmaps
是定义按钮的图片个数,因为如果你要使用自己的图片,所有图片是要放在同一行中的,然后就由你自己指定中间的个数, hBMInst
是包含已定义系统图片的资源句柄,在你不想自己画图,使用内定的标准图片时使用,一般包含这些图片的 hInstance 已经在
Widnows.inc 中定义为 HINST_COMMCTRL,同样 wBMID 一般是
IDB_STD_SMALL_COLOR,表示使用大图片还是小图片等等。接下来是定义按钮的数据结构,中间定义了各个按钮的命令号,图片号及其他属性,
结构如下:

TBBUTTON STRUCT

iBitmap DWORD ?

idCommand DWORD ?

fsState BYTE ?

fsStyle BYTE ?

bReserved BYTE 2 dup(?)

dwData DWORD ?

iString DWORD ?

TBBUTTON ENDS

其中,每个结构定义一个按钮,数据结构中iBitmap 是图片ID,idCommand 是按钮的命令号,这个命令号当你按下按钮的时候会出现在
WM_COMMAND 消息的 wParam 中,你就可以知道哪个按钮被按下了。fsState 是按钮的初始状态,如
TBSTATE_PRESSED 是已经按下的,详细见手册,fsStyle 是风格。

而建立状态栏的 CreateStatusWindow 的声明如下:

HWND CreateStatusWindow(

LONG style,

LPCTSTR lpszText,

HWND hwndParent,

UINT wID

);

style 是状态栏的风格,lpszText 指向初始化是要显示在状态栏的文本,你可以指向 NULL。hwndParent
是父窗口的句柄。wID 是窗口 ID。

使用工具栏和状态栏的源程序

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

;	是否包括调试代码

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

DEBUG		=	1

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

;	Programmed by 罗云彬, bigluo@telekbird.com.cn

;	Website: http://www.win32asm.com.cn 
;	LuoYunBin's Win32 ASM page (罗云彬的编程乐园)

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

;	版本信息

;	工具栏和状态栏演示程序 Ver 1.0

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

.386

.model flat, stdcall

option casemap :none   ; case sensitive

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

;	Include 数据

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

include		windows.inc

include		user32.inc

include		kernel32.inc

include		comctl32.inc

include		comdlg32.inc

include		gdi32.inc

includelib	user32.lib

includelib	kernel32.lib

includelib	comctl32.lib

includelib	comdlg32.lib

includelib	gdi32.lib

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

;	Equ 数据

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

IDI_MAIN	equ		1000		;icon

IDM_MAIN	equ		4000		;menu

IDM_TOOLBAR	equ		4001

IDM_STATUSBAR	equ		4002

IDM_EXIT	equ		4003

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

;	数据段

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

.data?

hInstance	dd		?

hWinMain	dd		?

hMenu		dd		?

hIcon		dd		?

hToolbar	dd		?

hStatusbar	dd		?

szBuffer	db	256 dup	(?)

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

;	数据段

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

.data

szClassName	db	"Toolbar Template",0

szCaptionMain	db	'工具栏和状态栏演示程序 - 罗云彬',0

dwFlag		dd	F_TOOLBAR or F_STATUSBAR

;********************************************************************

;	标志位定义

F_TOOLBAR	equ	00000001b

F_STATUSBAR	equ	00000010b

stToolbar	TBBUTTON	< STD_FILENEW,1,TBSTATE_ENABLED,TBSTYLE_BUTTON,2 dup(0),-1>

TBBUTTON	<0,0,TBSTATE_ENABLED,TBSTYLE_SEP,2 dup(0),-1>

TBBUTTON	< STD_FILEOPEN,2,TBSTATE_ENABLED,TBSTYLE_BUTTON,2 dup(0),-1>

TBBUTTON	< STD_FILESAVE,3,TBSTATE_ENABLED,TBSTYLE_BUTTON,2 dup(0),-1>

TBBUTTON	<0,0,TBSTATE_ENABLED,TBSTYLE_SEP,2 dup(0),-1>

TBBUTTON	< STD_PRINT,4,TBSTATE_ENABLED,TBSTYLE_BUTTON,2 dup(0),-1>

TBBUTTON	< STD_PRINTPRE,0,TBSTATE_ENABLED,TBSTYLE_SEP,2 dup(0),-1>

NUM_BUTTONS	EQU	7

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

;	代码段

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

.code

if		DEBUG

include		Debug.asm

endif

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

;	程序开始

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

start:

call	_WinMain

invoke	ExitProcess,NULL

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

;	主窗口程序

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

_WinMain	proc

local	@stWcMain:WNDCLASSEX

local	@stMsg:MSG

;********************************************************************

;	如果已经在运行,则激活已运行的进程

;********************************************************************

invoke	FindWindow,offset szClassName,NULL

.if	eax != NULL

invoke	ShowWindow,eax,SW_SHOWNORMAL

invoke	ExitProcess,NULL

.endif

invoke	InitCommonControls

invoke	GetModuleHandle,NULL

mov	hInstance,eax

invoke	LoadIcon,hInstance,IDI_MAIN

mov	hIcon,eax

invoke	LoadMenu,hInstance,IDM_MAIN

mov	hMenu,eax

;*************** 注册窗口类 *****************************************

invoke	LoadCursor,0,IDC_ARROW

mov	@stWcMain.hCursor,eax

mov	@stWcMain.cbSize,sizeof WNDCLASSEX

mov	@stWcMain.hIconSm,0

mov	@stWcMain.style,CS_HREDRAW or CS_VREDRAW

mov	@stWcMain.lpfnWndProc,offset WndMainProc

mov	@stWcMain.cbClsExtra,0

mov	@stWcMain.cbWndExtra,0

mov	eax,hInstance

mov	@stWcMain.hInstance,eax

mov	@stWcMain.hIcon,0

mov	@stWcMain.hbrBackground,COLOR_BTNFACE+1

mov	@stWcMain.lpszClassName,offset szClassName

mov	@stWcMain.lpszMenuName,0

invoke	RegisterClassEx,addr @stWcMain

;*************** 建立输出窗口 ***************************************

invoke	CreateWindowEx,NULL,/	;WS_EX_CLIENTEDGE,/

offset szClassName,offset szCaptionMain,/

WS_OVERLAPPEDWINDOW,/	; OR WS_VSCROLL OR WS_HSCROLL,/

50,50,550,350,/

NULL,hMenu,hInstance,NULL

invoke	ShowWindow,hWinMain,SW_SHOWNORMAL

invoke	UpdateWindow,hWinMain

;*************** 消息循环 *******************************************

.while	TRUE

invoke	GetMessage,addr @stMsg,NULL,0,0

.break	.if eax	== 0

invoke	TranslateMessage,addr @stMsg

invoke	DispatchMessage,addr @stMsg

.endw

ret

_WinMain	endp

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

WndMainProc	proc	uses ebx edi esi, /

hWnd:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD

mov	eax,uMsg

.if	eax ==	WM_CREATE

mov	eax,hWnd

mov	hWinMain,eax

call	_Init

;********************************************************************

.elseif	eax ==	WM_SIZE

invoke	SendMessage,hStatusbar,uMsg,wParam,lParam

invoke	SendMessage,hToolbar,uMsg,wParam,lParam

;********************************************************************

.elseif	eax ==	WM_COMMAND

mov	eax,wParam

movzx	eax,ax

.if	eax ==	IDM_EXIT

call	_Quit

.elseif	eax ==	IDM_TOOLBAR

xor	dwFlag,F_TOOLBAR

call	_ArrangeWindow

.elseif	eax ==	IDM_STATUSBAR

xor	dwFlag,F_STATUSBAR

call	_ArrangeWindow

.else

_Debug	"菜单和工具栏命令","命令ID",eax

.endif

;********************************************************************

.elseif	eax ==	WM_CLOSE

call	_Quit

;********************************************************************

.else

invoke	DefWindowProc,hWnd,uMsg,wParam,lParam

ret

.endif

;********************************************************************

;	注意:WndProc 处理 Windows 消息后,必须在 Eax 中返回 0

;	但是由 DefWindowProc 处理后的返回值不能改变,否则窗口

;	将无法显示!

;********************************************************************

xor	eax,eax

ret

WndMainProc	endp

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

;	主窗口控制子程序

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

_Init		proc

invoke	SendMessage,hWinMain,WM_SETICON,ICON_SMALL,hIcon

invoke	CreateToolbarEx,hWinMain,/

WS_VISIBLE or WS_CHILD or TBSTYLE_FLAT or WS_BORDER,/

1,0,HINST_COMMCTRL,IDB_STD_SMALL_COLOR,offset stToolbar,/

NUM_BUTTONS,0,0,0,0,sizeof TBBUTTON

mov	hToolbar,eax

invoke	CreateStatusWindow,WS_CHILD or WS_VISIBLE,NULL,hWinMain,2

mov	hStatusbar,eax

call	_ArrangeWindow

ret

_Init		endp

;********************************************************************

_Quit		proc

invoke	DestroyWindow,hWinMain

invoke	PostQuitMessage,NULL

ret

_Quit		endp

;********************************************************************

_ArrangeWindow	proc

local	@stRect:RECT

local	@stRectTemp:RECT

local	@dwWidth:DWORD

test	dwFlag,F_TOOLBAR

.if	ZERO?

invoke	ShowWindow,hToolbar,SW_HIDE

invoke	CheckMenuItem,hMenu,IDM_TOOLBAR,MF_UNCHECKED

.else

invoke	ShowWindow,hToolbar,SW_SHOW

invoke	CheckMenuItem,hMenu,IDM_TOOLBAR,MF_CHECKED

.endif

test	dwFlag,F_STATUSBAR

.if	ZERO?

invoke	ShowWindow,hStatusbar,SW_HIDE

invoke	CheckMenuItem,hMenu,IDM_STATUSBAR,MF_UNCHECKED

.else

invoke	ShowWindow,hStatusbar,SW_SHOW

invoke	CheckMenuItem,hMenu,IDM_STATUSBAR,MF_CHECKED

.endif

ret

_ArrangeWindow	endp

;********************************************************************

end	start


程序的分析和要点

在工具栏和状态栏编程中,要注意的就是工具栏和状态栏并不会随父窗口的大小变化自己调整位置和大小,所以要在父窗口的 WM_SIZE
消息中来移动和调整它们,这可以简单的把 WM_SIZE 消息传给它们就行了。不必自己再去计算。

.elseif eax == WM_SIZE

invoke SendMessage,hStatusbar,uMsg,wParam,lParam

invoke SendMessage,hToolbar,uMsg,wParam,lParam

另外,工具栏和状态栏也是一种子窗口,所以如果想把它们隐藏或显示的话,可以用标准的 ShowWindow 来处理。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: