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

    技术2022-05-11  102

    -------------------------------------------------------------------------------- 有关工具栏和状态栏 工具栏和状态栏也是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://asm.yeah.net ; 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 来处理。

    最新回复(0)