|
楼主 |
发表于 2014-10-8 20:04:31
|
显示全部楼层
下面是代码<font size="1">;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; by zp 9/25
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat, stdcall ;flat平坦模式,stdcall windows调用方法的方式
option casemap :none ;区分大小写
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.INC ;包含windows定义的一些函数声明
include user32.INC
includelib user32.lib ;告诉程序要去哪里找这些函数,并不会包含进来
include kernel32.INC
includelib kernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Equ 等值定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_ZPTB equ 100h ;图标
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
IDM_ZCD equ 2000h ;主菜单id
IDA_JSJ equ 2000h ;加速键ID
IDM_WJ1 equ 2101h
IDM_WJ2 equ 2102h
IDM_WJ3 equ 2103h
IDM_WJ4 equ 2104h
IDM_WJ5 equ 2105h
IDM_WJ6 equ 2106h
IDM_WJ7 equ 2107h
IDM_WJ8 equ 2108h
; 下面都是文件查看子菜单id
IDM_CK1 equ 2201h
IDM_CK2 equ 2202h
IDM_CK3 equ 2203h
IDM_CK4 equ 2204h
IDM_CK5 equ 2205h
IDM_CK6 equ 2206h
IDM_CK7 equ 2207h
IDM_CK8 equ 2208h
; 下面都是文件关闭子菜单id
IDM_GB equ 2222
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段(全局变量一般定义在这里)
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data? ;表示可以不初始值,只是告诉程序我这里需要这些数据,到时候用到在分配空间
hInstance DD ? ;h表示这个数据是句柄,当然只是这个书上的数据一般都是这么定义的
hWinMain DD ?
hMenu DD ?
hSubMenu DD ?
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段(这里一般是一常量)
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.const
szClassName DB 'Menu Example',0 ;字符串用0结尾
szCaptionMain DB 'Menu',0
szMenuHelp DB '帮助主题(&H)',0
szMenuAbout DB '关于本程序(&A)...',0
szCaption DB '菜单选择',0
szFormat DB '您选择了菜单命令:%08x',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_DisplayMenuItem proc _dwCommandID
local @szBuffer[256]:BYTE
PUSHAD
invoke wsprintf,\
addr @szBuffer,\ ;输出缓冲区
addr szFormat,\ ;格式字符串
_dwCommandID ;需要输出的参数
invoke MessageBox,\
hWinMain,\ ;哪个窗口的消息框
addr @szBuffer,\ ;显示的内容
offset szCaption,\ ;消息框的标题
MB_OK ;消息框上面的按钮
POPAD
RET
_DisplayMenuItem endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_Quit proc
;发送WM_DESTROY 消息和 WM_NCDESTROY 销毁指定窗口,成功返回非0值,失败返回0
invoke DestroyWindow,hWinMain
;该函数向系统表明有个线程有终止请求。通常用来响应WM_DESTROY消息。
;参数指定应用程序退出代码。此值被用作消息WM_QUIT的wParam参数。
invoke PostQuitMessage,NULL
_Quit endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;uses EBX,EDI,ESI 保存这几个值,push pop
_ProcWinMain proc uses EBX EDI ESI hWnd,uMsg,wParam,lParam
local @stPos:POINT ;x 和 y 的坐标
local @hSysMenu
MOV EAX,uMsg
.IF EAX == WM_CREATE ;由CreateWindowEx 函数返回之前发送
;获得指定菜单已激活的子菜单句柄,参数1 指定菜单,参数2 子菜单的索引
INVOKE GetSubMenu,hMenu,1
MOV hSubMenu,EAX
;********************************************************************
; 在系统菜单中添加菜单项
;********************************************************************
;修改或者访问窗口菜单,参数2为 NULL 则获得窗口菜单的句柄
invoke GetSystemMenu,hWnd,FALSE
MOV @hSysMenu,EAX
invoke AppendMenu,@hSysMenu,MF_SEPARATOR,0,NULL
invoke AppendMenu,@hSysMenu,0,IDM_WJ3,offset szMenuHelp
;********************************************************************
;由子窗口或者快捷键产生则通知码为1,由菜单产生通知码为0。
.elseif EAX == WM_COMMAND
invoke _DisplayMenuItem,wParam
MOV EAX,wParam
MOVZX EAX,AX
PUSH EAX
.IF EAX == IDM_GB
CALL _Quit
.elseif EAX >= IDM_WJ1 && EAX <= IDM_WJ4
MOV EBX,EAX
;获得指定菜单里的某个菜单项的状态,ebx:菜单项,MF_BYCOMMAND定位的方法
;MF_CHECKED选中,MF_DISABLED禁用,MF_GRAYED灰化
invoke GetMenuState,hMenu,EBX,MF_BYCOMMAND
.IF EAX == MF_CHECKED ;是否选中
MOV EAX,MF_UNCHECKED
.else
MOV EAX,MF_CHECKED
.endif
;设置指定菜单的某个菜单项的状态,返回设置之前的状态
invoke CheckMenuItem,hMenu,EBX,EAX
.elseif EAX >= IDM_WJ5 && EAX <= IDM_WJ8
;设置指定菜单的某个菜单项的状态和标志,以及清除范围内所有菜单项的状态和标志
invoke CheckMenuRadioItem,hMenu,IDM_WJ5,IDM_WJ8,EAX,MF_BYCOMMAND
.endif
POP EAX
.IF EAX == IDM_WJ8 ;如果选择了小图标菜单项,就禁用
invoke EnableMenuItem,hMenu,IDM_WJ8,MF_DISABLED
.endif
;********************************************************************
.elseif EAX == WM_SYSCOMMAND ;处理系菜单
MOV EAX,wParam
MOVZX EAX,AX
.IF EAX == IDM_WJ3
invoke _DisplayMenuItem,wParam
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
.endif
;********************************************************************
.elseif EAX == WM_RBUTTONDOWN
invoke GetCursorPos,addr @stPos
invoke TrackPopupMenu,hSubMenu,TPM_LEFTALIGN,@stPos.x,@stPos.y,NULL,hWnd,NULL
;********************************************************************
.elseif eax == WM_CLOSE
call _Quit
;********************************************************************
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
;********************************************************************
xor eax,eax
ret
_ProcWinMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_WinMain proc ;proc 自定义子程序的开始标志
local @stWndClass:WNDCLASSEX ;WNDCLASSEX窗口类的数据结构
local @stMsg:MSG ;消息类的数据结构
local @hAccelerator
invoke GetModuleHandle,NULL ;返回指定模块的句柄,参数NULL返回本模块句柄,句柄存放在EAX
MOV hInstance,EAX
invoke LoadMenu,hInstance,IDM_ZCD ;为指定模块加载指定菜单资源,可以用指定菜单名的指针作为参数,也可以使用菜单id,成功则返回,菜单句柄
MOV hMenu,EAX
invoke LoadAccelerators,hInstance,IDA_JSJ ;加载加速键
MOV @hAccelerator,EAX
;********************************************************************
; 注册窗口类
;********************************************************************
;填充一块内存区域,参数1:首地址 ,参数2:填充的大小
invoke RtlZeroMemory,addr @stWndClass,sizeof @stWndClass
invoke LoadIcon,hInstance,ICO_ZPTB ;加载图标,返回图标句柄
MOV @stWndClass.hIcon,EAX ;图标句柄
MOV @stWndClass.hIconSm,EAX ;设置小图标
invoke LoadCursor,0,IDC_ARROW ;加载光标资源,返回光标句柄
MOV @stWndClass.hCursor,EAX
PUSH hInstance
POP @stWndClass.hInstance
MOV @stWndClass.cbSize,sizeof WNDCLASSEX;设置WNDCLASSEX的大小
MOV @stWndClass.style,CS_HREDRAW OR CS_VREDRAW ;设置窗口的风格
MOV @stWndClass.lpfnWndProc,offset _ProcWinMain ;指该类对应的窗口过程
MOV @stWndClass.hbrBackground,COLOR_WINDOW + 1 ;背面画刷
MOV @stWndClass.lpszClassName,offset szClassName;指定类名叫什么
invoke RegisterClassEx,addr @stWndClass ;开始注册
;********************************************************************
; 建立并显示窗口
;********************************************************************
invoke CreateWindowEx, \
WS_EX_CLIENTEDGE,\ ;窗口的扩展风格
offset szClassName,\ ;指向注册类名的指针
offset szCaptionMain,\ ;指向窗口名称的指针
WS_OVERLAPPEDWINDOW,\ ;窗口风格
100,100,400,300,NULL,hMenu,hInstance,NULL ;指向窗口的创建数据
MOV hWinMain,EAX ;注册成功返回窗口句柄,否则返回NULL
;显示窗口,参数1,要显示窗口的句柄,参数2:还原窗口的位置
invoke ShowWindow,hWinMain,SW_SHOWNORMAL
;如果更新的区域不为空,函数则发送WM_PAINT 消息到该窗口的窗口过程
invoke UpdateWindow,hWinMain
;********************************************************************
; 消息循环
;********************************************************************
.while TRUE
;如果函数取得WM_QUIT之外的其他消息,返回非零值。
;如果函数取得WM_QUIT消息,返回值是零。如果出现了错误,返回值是-1。
invoke GetMessage,\
addr @stMsg,\ ;该结构从线程的消息队列里接收消息信息
NULL,\ ;;取得其消息的窗口的句柄
0,\ ;指定被检索的最小消息值的整数。
0 ;指定被检索的最大消息值的整数。
.break .IF EAX == 0 ;0消息就代表退出
;该函数将一个WM-DEYDOUN或WM-SYSDEYDOWN消息翻译或一个WM-COMMAND或
;WM-SYSCOMMAND消息(如果在给定的加速键表中有该键的入口),
;然后将WM-COMMAND或WM-SYSCOMMAND消息直接送到相应的窗口处理过程。
invoke TranslateAccelerator,hWinMain,@hAccelerator,addr @stMsg
.IF EAX == 0
;当消息是键盘消息,则转换成对应的ASCII码,然后插入WM_CHAR
;WM_SYSCHAR到消息队列,如果不是键盘消息则不处理
invoke TranslateMessage,addr @stMsg
;将消息发送给操作系统,由操作系统来调用我们指定的窗口过程
invoke DispatchMessage,addr @stMsg
.endif
.endw
RET
_WinMain endp
start:
CALL _WinMain ;带下划线的函数是指自己写的
invoke ExitProcess,NULL ;关闭进程,参数NULL是代表 关闭当前进程
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start</font>
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#include <resource.h> //resource 这个应该是一些菜单和光标等的定义
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#define ICO_ZPTB 0x100 //图标
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#define IDM_ZCD 0x2000 //菜单
#define IDA_JSJ 0x2000 //加速键
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//下面都是文件子菜单id
#define IDM_WJ1 0x2101
#define IDM_WJ2 0x2102
#define IDM_WJ3 0x2103
#define IDM_WJ4 0x2104
#define IDM_WJ5 0x2105
#define IDM_WJ6 0x2106
#define IDM_WJ7 0x2107
#define IDM_WJ8 0x2108
//下面都是文件查看子菜单id
#define IDM_CK1 0x2201
#define IDM_CK2 0x2202
#define IDM_CK3 0x2203
#define IDM_CK4 0x2204
#define IDM_CK5 0x2205
#define IDM_CK6 0x2206
#define IDM_CK7 0x2207
#define IDM_CK8 0x2208
//下面都是文件关闭子菜单id
#define IDM_GB 0x2222
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_ZPTB ICON "Main.ico" //定义图标
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
IDM_ZCD menu discardable //定义菜单
BEGIN
POPUP "WJ(&Q)" //&是为了给F加个下划线
BEGIN
MENUITEM "WJ1", IDM_WJ1
MENUITEM "WJ2", IDM_WJ2
MENUITEM "WJ3", IDM_WJ3
MENUITEM "WJ4", IDM_WJ4
MENUITEM SEPARATOR //这个菜单是个 分割线
MENUITEM "WJ5", IDM_WJ5
MENUITEM "WJ6", IDM_WJ6
MENUITEM "WJ7", IDM_WJ7
MENUITEM "WJ8", IDM_WJ8
END
POPUP "CK(&W)"
BEGIN
MENUITEM "CK1", IDM_CK1, INACTIVE //禁用的菜单
MENUITEM "CK2", IDM_CK2, GRAYED //灰化的菜单
MENUITEM "CK3", IDM_CK3
MENUITEM "CK4", IDM_CK4
MENUITEM SEPARATOR //这个菜单是个 分割线
POPUP "CK5"
BEGIN
MENUITEM "CK6", IDM_CK6
MENUITEM "CK7", IDM_CK7
MENUITEM "CK8", IDM_CK8
END
END
MENUITEM "GB", IDM_GB
END
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
IDA_JSJ ACCELERATORS
BEGIN
VK_F1, IDM_WJ1,VIRTKEY //VIRTKEY这个表示这个加速键一个键码
"^p", IDM_WJ1 //ctrl+p
"O", IDM_WJ2 //shift+o 因为键盘上的o是小写的,等下又测试
"o", IDM_WJ3,ALT //lat+o
98, IDM_WJ4,ASCII //b(字符c的Ascii码为98)
66, IDM_WJ5,ASCII //shift+b(字符c的Ascii码为98)
END
|
|