;运行效果
;win32汇编环境,窗口程序中状态栏的应用示例
;一般放在窗口最下面的栏目,可用来显示一些状态
;直接抄进RadAsm可编译运行。重要部分加备注。
;下面为asm文件
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
include kernel32.inc
include Comctl32.inc ;加入所需头文件
includelib user32.lib
includelib kernel32.lib
includelib Comctl32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD
;Equ 等值定义
IDM_011 equ 11 ;某项的标识符
IDM_012 equ 12
IDM_021 equ 21
IDM_022 equ 22
IDM_023 equ 23
IDM_024 equ 24
IDM_025 equ 25
IDM_026 equ 26
IDM_0261 equ 261
IDM_0262 equ 262
IDM_031 equ 31
IDM_032 equ 32
ID_STATUSBAR equ 1
IDM_MENUHELP equ 1300
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.DATA
ClassName db "SimpleWinClass",0
AppName db "窗口程序的模版",0
szMen1 db "文件(&F)",0
szMen1_1 db "开始",0
szMen1_2 db "退出",0
szMen2 db "命令(&C)",0
szMen2_1 db "功能01",0
szMen2_2 db "被禁用的菜单项",0
szMen2_3 db "被灰化的菜单项",0
szMen2_4 db "使上面的禁用有效",0
szMen2_5 db "使上面的灰化有效",0
szMen2_6 db "工具栏",0
szMen2_6_1 db "功能05",0
szMen2_6_2 db "功能06",0
szMen3 db "帮助(&H)",0
szMen3_1 db "帮助主题(&H)",0
szMen3_2 db "关于本程序(&A)..",0
szFu01 db "帮助主题(&H)",0
szFu02 db "关于本程序(&A)...",0
sz1 db '我在左边',0
sz2 db '我在中间',0
sz3 db '点一下我试试',0
sz4 db '我被点击了',0
dwStatusWidth dd 100,250,-1 ;这是整数数组的定义,数值是像素值,最后的-1是把剩下的像素长度都给第3个栏,在定义常量或变量时,紧挨着的值在内存里的分布也是紧挨着的,而 dwStatusWidth 则是指针
dwMenuHelp dd 0,IDM_MENUHELP,0,0
.DATA?
hInstance HINSTANCE ?
CommandLine LPSTR ?
hRootMenu HMENU ?
hPopupMenu1 HMENU ?
hPopupMenu2 HMENU ?
hPopupMenu21 HMENU ?
hPopupMenu3 HMENU ?
hWinStatus dd ? ;状态栏的句柄
lpsz1 dd ?
lpsz2 dd ?
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.CODE
start:
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke GetCommandLine
mov CommandLine,eax
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
invoke ExitProcess, eax
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL hwnd:HWND
mov wc.cbSize,SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
push hInstance
pop wc.hInstance
mov wc.hbrBackground,COLOR_WINDOW
mov wc.lpszMenuName,NULL
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
invoke CreateWindowEx,NULL, ADDR ClassName,ADDR AppName,WS_OVERLAPPEDWINDOW,100,100,400,300, NULL,NULL,hInst, NULL
mov hwnd,eax
invoke ShowWindow, hwnd,CmdShow
invoke UpdateWindow, hwnd
.while TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.break .if (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.endw
mov eax,msg.wParam
ret
WinMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL @hSysMenu
LOCAL @stPoint:POINT,@stRect:RECT
LOCAL @szBuffer[256]:byte
.if uMsg == WM_CREATE
invoke CreateMenu ;创建根菜单
mov hRootMenu,eax
invoke CreatePopupMenu ;创建下拉式菜单,竖立的弹出菜单,通常作为另一个菜单的子菜单或右键菜单的顶级菜单
mov hPopupMenu1,eax
invoke AppendMenu,hRootMenu,MF_POPUP,hPopupMenu1,addr szMen1 ;把下拉式菜单添加到根菜单里去
invoke AppendMenu,hPopupMenu1,MF_STRING,IDM_011,addr szMen1_1 ;给下拉式菜单加上第1项
invoke AppendMenu,hPopupMenu1,MF_SEPARATOR,0,0 ;加条沉底分隔线
invoke AppendMenu,hPopupMenu1,MF_STRING,IDM_012,addr szMen1_2 ;给下拉式菜单加上第2项
invoke CreatePopupMenu
mov hPopupMenu2,eax
invoke AppendMenu,hRootMenu,MF_POPUP,hPopupMenu2,addr szMen2
invoke AppendMenu,hPopupMenu2,MF_STRING,IDM_021,addr szMen2_1
invoke AppendMenu,hPopupMenu2,MF_STRING + MF_DISABLED,IDM_022,addr szMen2_2 ;MF_DISABLED 是禁用风格
invoke AppendMenu,hPopupMenu2,MF_STRING + MF_GRAYED,IDM_023,addr szMen2_3 ;MF_GRAYED 是禁用且灰显状态
invoke AppendMenu,hPopupMenu2,MF_STRING,IDM_024,addr szMen2_4
invoke AppendMenu,hPopupMenu2,MF_STRING,IDM_025,addr szMen2_5
invoke CreatePopupMenu ;创建工具栏项要弹出的右侧的菜单项
mov hPopupMenu21,eax
invoke AppendMenu,hPopupMenu2,MF_POPUP,hPopupMenu21,addr szMen2_6 ;把弹出右侧的菜单添加到上一层菜单去
invoke AppendMenu,hPopupMenu21,MF_STRING,IDM_0261,addr szMen2_6_1
invoke AppendMenu,hPopupMenu21,MF_STRING,IDM_0262,addr szMen2_6_2
invoke CreatePopupMenu
mov hPopupMenu3,eax
invoke AppendMenu,hRootMenu,MF_POPUP,hPopupMenu3,addr szMen3
invoke AppendMenu,hPopupMenu3,MF_STRING,IDM_031,addr szMen3_1
invoke AppendMenu,hPopupMenu3,MF_STRING,IDM_032,addr szMen3_2
invoke SetMenu,hWnd,hRootMenu
invoke GetSystemMenu,hWnd,FALSE ;在系统菜单中添加菜单项,就是左上角的图标那儿
mov @hSysMenu,eax
invoke AppendMenu,@hSysMenu,MF_SEPARATOR,0,NULL
invoke AppendMenu,@hSysMenu,0,IDM_031,offset szFu01
invoke AppendMenu,@hSysMenu,0,IDM_032,offset szFu02
invoke CreateStatusWindow,WS_CHILD + WS_VISIBLE + SBS_SIZEGRIP,NULL,hWnd,ID_STATUSBAR ;创建状态栏
mov hWinStatus,eax
invoke SendMessage,hWinStatus,SB_SETPARTS,3,offset dwStatusWidth ;根据 dwStatusWidth 的值把状态栏分成3块,dwStatusWidth是个整数数组
mov lpsz1,offset sz3 ;把字符串的地址值保存下来,后面交换字符串时需要地址值
mov lpsz2,offset sz4
invoke SendMessage,hWinStatus,SB_SETTEXT,0,addr sz1 ;显示在第1栏的字符串。也可以显示其它内容,比如想放个当前时间,则设个定时器,取得本地时间,然后每秒更新显示。
invoke SendMessage,hWinStatus,SB_SETTEXT,1,addr sz2
invoke SendMessage,hWinStatus,SB_SETTEXT,2,addr sz3
.elseif uMsg == WM_MENUSELECT ;WM_MENUSELECT 消息是当选项菜单的某项时产生的
invoke MenuHelp,WM_MENUSELECT,wParam,lParam,lParam,hInstance,hWinStatus,offset dwMenuHelp
.elseif uMsg == WM_NOTIFY ;WM_NOTIFY消息为扩展后的控件消息,早期的WINDOWS没那么多功能,后来版本升级了,有更多的功能了,这些功能就在WM_NOTIFY消息里
.if wParam == ID_STATUSBAR ;如果是状态栏的消息,则
mov eax,lParam ;lParam指向消息结构,即当你点击状态栏时,系统把这个消息放在一个结构里,但只能把指向这个结构的指针发送过来,就是lParam
mov eax,[eax + NMHDR.code] ;所以我们需要取得lParam指针所指向的结构中的NMHDR结构的成员 code 的值,注意,这时指的是结构中的结构的成员,
.if eax == NM_CLICK ;如果是这个点击的通知码,则下面判断点的坐标,通过坐标判断是点了状态栏中的哪部分
invoke GetCursorPos,addr @stPoint ;得到你的鼠标点的坐标
invoke GetWindowRect,hWinStatus,addr @stRect ;得到状态栏的坐标
mov eax,@stRect.left
mov ecx,eax
add eax,250 ;250是dwStatusWidth整数数组的第2个值
mov ebx,@stRect.right
.if (@stPoint.x >= eax) && (@stPoint.x <= ebx)
mov eax,lpsz1
xchg eax,lpsz2
mov lpsz1,eax
invoke SendMessage,hWinStatus,SB_SETTEXT,2,lpsz1
.endif
.endif
.endif
.elseif uMsg == WM_DESTROY
invoke PostQuitMessage,NULL
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
xor eax,eax
ret
WndProc endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start
;以下是Rc资源文件内容
//找不到MenuHelp函数最后一个参数的类型说明,只能通过传资源加载的方式在状态栏中使用帮助文本
#define IDM_011 11
#define IDM_012 12
#define IDM_021 21
#define IDM_022 22
#define IDM_023 23
#define IDM_024 24
#define IDM_025 25
#define IDM_026 26
#define IDM_031 31
#define IDM_032 32
#define IDM_MENUHELP 1300
stringtable discardable
BEGIN
IDM_MENUHELP "包含文件操作的命令"
IDM_MENUHELP+1 "包含操作视图的命令"
IDM_011 "指向开始菜单项"
IDM_012 "指向退出菜单项"
IDM_031 "指向帮助主题"
END