-
-
[旧帖] [原创]发一个罗云斌的control代码的详细解释附带资源解释,有不足和错误之处还望各位多多指教,多谢 0.00雪花
-
发表于: 2010-12-15 19:34 825
-
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Sample code for < Win32ASM Programming 2nd Edition>
; by 罗云彬, http://asm.yeah.net
;详细注释:by 塘鱼
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Control.asm
; 对话框资源中子窗口控件的使用方法
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 使用 nmake 或下列命令进行编译和链接:
; ml /c /coff Control.asm
; rc Control.rc
; Link /subsystem:windows Control.obj Control.res
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat, stdcall
option casemap :none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
include gdi32.inc
includelib gdi32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Equ 等值定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN equ 1000h
DLG_MAIN equ 1
IDB_1 equ 1
IDB_2 equ 2
IDC_ONTOP equ 101
IDC_SHOWBMP equ 102
IDC_ALOW equ 103
IDC_MODALFRAME equ 104
IDC_THICKFRAME equ 105
IDC_TITLETEXT equ 106
IDC_CUSTOMTEXT equ 107
IDC_BMP equ 108
IDC_SCROLL equ 109
IDC_VALUE equ 110
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hInstance dd ? ;对话框实例句柄
hBmp1 dd ? ;位图句柄
hBmp2 dd ? ;位图句柄2
dwPos dd ? ;定义一个
.const
szText1 db 'Hello, World!',0 ;下拉菜单文本定义
szText2 db '嘿,你看到标题栏变了吗?',0
szText3 db '自定义',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcDlgMain proc uses ebx edi esi hWnd,wMsg,wParam,lParam ;对话框过程处理函数
local @szBuffer[128]:byte ;定义一个128字节的缓冲区
mov eax,wMsg ;分支处理消息
.if eax == WM_CLOSE ;遇到关闭消息时候,泯灭掉窗口,并delete掉位图
invoke EndDialog,hWnd,NULL
invoke DeleteObject,hBmp1
invoke DeleteObject,hBmp2
.elseif eax == WM_INITDIALOG ;用户自己定义的要处理的一些消息
;********************************************************************
; 设置标题栏图标
;********************************************************************
invoke LoadIcon,hInstance,ICO_MAIN ;调用loadicon函数,获取窗口图标,其值又loadicon函数返回在了eax中
invoke SendMessage,hWnd,WM_SETICON,ICON_BIG,eax ;根据,eax中的返回值调用sendmessage函数发送WM_SETICON命令,创立图标
;********************************************************************
; 初始化组合框
;********************************************************************
invoke SendDlgItemMessage,hWnd,IDC_TITLETEXT,CB_ADDSTRING,0,addr szText1 ;调用senddlgitenmessage函数向对话框发送cb_addstring命令,载入了预定义的文本
invoke SendDlgItemMessage,hWnd,IDC_TITLETEXT,CB_ADDSTRING,0,addr szText2 ;调用senddlgitenmessage函数向对话框发送cb_addstring命令,载入了预定义的文本
invoke SendDlgItemMessage,hWnd,IDC_TITLETEXT,CB_ADDSTRING,0,addr szText3 ;调用senddlgitenmessage函数向对话框发送cb_addstring命令,载入了预定义的文本
invoke SendDlgItemMessage,hWnd,IDC_TITLETEXT,CB_SETCURSEL,0,0
invoke GetDlgItem,hWnd,IDC_CUSTOMTEXT ;获取用户自定义的文本的句柄
invoke EnableWindow,eax,FALSE ;由eax的返回值判断下面选框的状态,如果被选中则激活对话框
invoke LoadBitmap,hInstance,IDB_1 ;获取位图句柄,并保存到HBMP1
mov hBmp1,eax
invoke LoadBitmap,hInstance,IDB_2 ;获取位图句柄,并保存HBMP2
mov hBmp2,eax
;********************************************************************
; 初始化单选钮和复选框 ;程序运行的时候可以发现,显示图片,允许更换图片和可变边框是被选中的
;********************************************************************
invoke CheckDlgButton,hWnd,IDC_SHOWBMP,BST_CHECKED ;调用checkdlgbutton设置选中的状态,有checked,unchecked,indeterminate三种状态
invoke CheckDlgButton,hWnd,IDC_ALOW,BST_CHECKED
invoke CheckDlgButton,hWnd,IDC_THICKFRAME,BST_CHECKED ;单选框之所以也能这样设置,是由于我们在资源中定义的是自动单选框
;********************************************************************
; 初始化滚动条
;********************************************************************
invoke SendDlgItemMessage,hWnd,IDC_SCROLL,SBM_SETRANGE,0,100 ;调用senddlgitemmessage函数直接向对话框窗口发送创建滚动条的消息,sbm_setrange,0 ~100是滚动条范围
.elseif eax == WM_COMMAND ;用户自己处理的命令
mov eax,wParam
.if ax == IDCANCEL ;当遇到取消或键盘按下esP键的时候调用enddialog函数泯灭对话框,delete掉位图
invoke EndDialog,hWnd,NULL
invoke DeleteObject,hBmp1
invoke DeleteObject,hBmp2
;********************************************************************
; 更换图片
;********************************************************************
.elseif ax == IDOK ;当idok或者是键盘上enter按钮被选中时,我们把位图句柄hbmp1赋值到eax,交换HBMP2的值,现在eax中放入的就是hbmp2,然后交换
mov eax,hBmp1
xchg eax,hBmp2
mov hBmp1,eax
invoke SendDlgItemMessage,hWnd,IDC_BMP,STM_SETIMAGE,IMAGE_BITMAP,eax ;调用senddlgitemmessage函数,发送STM_SETIMAGE命令,使用eax中的句柄值设置图片格式为IMAGE_BITMAP位图,
;********************************************************************
; 设置是否“总在最前面”
;********************************************************************
.elseif ax == IDC_ONTOP
invoke IsDlgButtonChecked,hWnd,IDC_ONTOP ;调用isdlgbuttonchecked函数检测复选框总在前面按钮的状态
.if eax == BST_CHECKED
invoke SetWindowPos,hWnd,HWND_TOPMOST,0,0,0,0,\ ;调用setwindowpos函数,设置窗口大小啊,位置啊等等风格!如果选中,设置成总在前面的风格并且不移动和不改变大小(SWP_NOMOVE or SWP_NOSIZE)
SWP_NOMOVE or SWP_NOSIZE
.else
invoke SetWindowPos,hWnd,HWND_NOTOPMOST,0,0,0,0,\ ;其他时候,取消总在前面的风格
SWP_NOMOVE or SWP_NOSIZE
.endif
;********************************************************************
; 演示隐藏和显示图片控件
;********************************************************************
.elseif ax == IDC_SHOWBMP
invoke GetDlgItem,hWnd,IDC_BMP ;调用getdlgitem函数获取图片框控件的句柄,将值存放在ebx中
mov ebx,eax
invoke IsWindowVisible,ebx ;调用iswindowvisible函数返回位图句柄的状态
.if eax ;如果有返回值表示有图片显示则设定为隐藏
invoke ShowWindow,ebx,SW_HIDE
.else ;相反条件则显示
invoke ShowWindow,ebx,SW_SHOW
.endif
;********************************************************************
; 演示允许和灰化“更换图片”按钮
;********************************************************************
.elseif ax == IDC_ALOW ;分支判断IDC_ALOW命令,也就是允许更换图片复选框是否被选中
invoke IsDlgButtonChecked,hWnd,IDC_ALOW ;调用:isdlgbuttonchecked函数,检测复选框被选中的状态
.if eax == BST_CHECKED ;如果复选框被选中,返回布尔的TRUE值,表示处理完毕
mov ebx,TRUE
.else ;否则,使用异或指令:xor由于相同则0的原则,把ebx清0,返回了布尔值fault!表示未处理完毕
xor ebx,ebx
.endif
invoke GetDlgItem,hWnd,IDOK ;调用函数,getdlgitem函数可以专门获取控件ID,IDOK的窗口句柄,其返回值存放在:eax中,
invoke EnableWindow,eax,ebx ;调用enablewindow函数,设置更换图片按钮为,灰色。
;********************************************************************
;模态边框和非模态边框的选择
;********************************************************************
.elseif ax == IDC_MODALFRAME
invoke GetWindowLong,hWnd,GWL_STYLE ;调用getwindowslong函数返回窗口风格,返回值是32位的
and eax,not WS_THICKFRAME ;(and)与上not ws_thickframe风格,由于and指令全1为1,有0则0。那么,你在非模态下拉大了对话框,从新设置的时候,保留拉大,设定为模态
invoke SetWindowLong,hWnd,GWL_STYLE,eax
.elseif ax == IDC_THICKFRAME
invoke GetWindowLong,hWnd,GWL_STYLE ;设置非模态对话框原理同上,不做详解了;
or eax,WS_THICKFRAME
invoke SetWindowLong,hWnd,GWL_STYLE,eax
;********************************************************************
; 演示处理下拉式组合框
;********************************************************************
.elseif ax == IDC_TITLETEXT ;下拉组合框消息
shr eax,16 ;由于低16存放的是控件ID,使用逻辑右移指令,把通知码移向低16位方便操作
.if ax == CBN_SELENDOK ;CBN_SELENDOK表示用户完成了选择消息
invoke SendDlgItemMessage,hWnd,IDC_TITLETEXT,CB_GETCURSEL,0,0 ;发送CB_GETCURSEL获取当前位置索引
.if eax == 2 ;标号是2表示下拉菜单的第三项被选中
invoke GetDlgItem,hWnd,IDC_CUSTOMTEXT ;获取用户自定义的文本框
invoke EnableWindow,eax,TRUE ;激活此文本框,用户就可以输入了
.else
mov ebx,eax
invoke SendDlgItemMessage,hWnd,IDC_TITLETEXT,CB_GETLBTEXT,ebx,addr @szBuffer;获取当前位置字符串索引,缓冲区必须足够大
invoke SetWindowText,hWnd,addr @szBuffer ;设置为标题
invoke GetDlgItem,hWnd,IDC_CUSTOMTEXT ;获取用户自定义文本框的句柄
invoke EnableWindow,eax,FALSE ;将自定义的窗口灰化
.endif
.endif
;********************************************************************
; 在文本框中输入文字会显示在标题栏上
;********************************************************************
.elseif ax == IDC_CUSTOMTEXT ;分支判断,检测用户是否向文本输入信息COSTOMETEXT
invoke GetDlgItemText,hWnd,IDC_CUSTOMTEXT,addr @szBuffer,sizeof @szBuffer ;调用:getdlgitemtext函数获取文本,其值存放在缓冲区中
invoke SetWindowText,hWnd,addr @szBuffer ;调用setwindowtext函数设置为标题,
.endif
;********************************************************************
; 处理滚动条消息
;********************************************************************
.elseif eax == WM_HSCROLL ;分支判断,检测用户对滚动条的操作:WM_HSCOLL
mov eax,wParam ;需要注意的是:wparam中的低字节存放的是滚动条的动作码,高字节存放的检测是滚动条的位置,但只是在SB_THUMBPOSITION SB_THUMBTRACK的时候有值,其余的时候其值为零
.if ax == SB_LINELEFT ;一下4句实现的分别是:左右移动一行和一列
dec dwPos
.elseif ax == SB_LINERIGHT
inc dwPos
.elseif ax == SB_PAGELEFT
sub dwPos,10
.elseif ax == SB_PAGERIGHT
add dwPos,10
.elseif ax == SB_THUMBPOSITION || ax == SB_THUMBTRACK ;检测滚动条的当前位置
mov eax,wParam
shr eax,16 ;汇编指令SHR逻辑右移,将动作码清零,eax中只存放着滚动条的位置
mov dwPos,eax
.else ;处理完毕后返回布尔真值,表示处理完毕
mov eax,TRUE
ret
.endif
cmp dwPos,0 ;对越界进行操作,之所以不能使用if是由于if是用于无符号数的操纵
jge @F ;小于零则重置为零,大于零 调到最近标号继续判断是否小于100
mov dwPos,0
@@:
cmp dwPos,100
jle @F ;如果大于100则重置为100,如果小于100的跳掉标号处执行
mov dwPos,100
@@:
invoke SetDlgItemInt,hWnd,IDC_VALUE,dwPos,FALSE ;调用SETDLGITEMINT函数可以设置对话框控件文本,false表示的是无符号数
invoke SendDlgItemMessage,hWnd,IDC_SCROLL,SBM_SETPOS,dwPos,TRUE ;重绘滚动条调用senddlgitemmessage函数发送SBM_SETPOS命令给控件,设置滚动条到新的位置用户才能看到滚动条的移动,最后一个 参数是true表示重新绘画滚动条
;********************************************************************
.else
mov eax,FALSE ;如果用户没有操作滚动条,则将布尔值设为false,表示没有操作
ret
.endif
mov eax,TRUE ;整个对话框过程处理完毕,将布尔值设为true返回
ret
_ProcDlgMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start: ;程序从此开始
invoke GetModuleHandle,NULL ;调用getmodulehandle函数,获得对话框实例句柄
mov hInstance,eax
invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,NULL ;调用DIALOGBOXPARAM函数,使窗口出现,从对话框实例句柄hinstance中载入资源中的DLG_MAIN,并定义了对话框专门的过程处理函数:_ProcDlgMain!
invoke ExitProcess,NULL ;程序退出
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//资源文件详解:by 塘鱼
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#include <resource.h> ;脚本资源定义
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#define ICO_MAIN 0x1000 //图标 ;宏定义图标
#define DLG_MAIN 1 ;宏定义对话框
#define IDB_1 1 ;宏定义了两张位图
#define IDB_2 2
#define IDC_ONTOP 101
#define IDC_SHOWBMP 102
#define IDC_ALOW 103
#define IDC_MODALFRAME 104
#define IDC_THICKFRAME 105
#define IDC_TITLETEXT 106
#define IDC_CUSTOMTEXT 107
#define IDC_BMP 108
#define IDC_SCROLL 109
#define IDC_VALUE 110
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN ICON "Main.ico" ;关联了图标
IDB_1 BITMAP "Picture1.bmp" ;关联了两张位图
IDB_2 BITMAP "Picture2.bmp"
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
DLG_MAIN DIALOG 193, 180, 310, 134 ;对话框详细定义
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME ;风格定义
CAPTION "对话框子窗口控制示例" ;标题定义
FONT 9, "宋体" ;字体定义
{
GROUPBOX "选项", -1, 55, 5, 120, 100 ;画了一个框框,名字是选项,从65.20开始大小是:120*100,没有文本的groupbox其实就相当于一个边框
AUTOCHECKBOX "总在最前面", IDC_ONTOP, 65, 20, 100, 12 ;定义了三个自动复选框
AUTOCHECKBOX "显示图片", IDC_SHOWBMP, 65, 35, 100, 12
AUTOCHECKBOX "允许更换图片", IDC_ALOW, 65, 50, 100, 12
CONTROL "", -1, "Static", SS_ETCHEDHORZ | WS_CHILD | WS_VISIBLE, 60, 65, 110, 1 ;画了一条直线,由于没有简化定义,只有使用这种方法了
AUTORADIOBUTTON "模态边框(&Modal Frame)", IDC_MODALFRAME, 65, 70, 100, 12, WS_TABSTOP ;定义了两个自动单选框
AUTORADIOBUTTON "可变边框(&Thick Frame)", IDC_THICKFRAME, 65, 85, 100, 12, WS_TABSTOP
GROUPBOX "标题栏文字", -1, 180, 5, 125, 100, BS_GROUPBOX ;画了个框框,并把它们定义为一个组
COMBOBOX IDC_TITLETEXT, 190, 20, 105, 70, CBS_DROPDOWNLIST | WS_TABSTOP ;定义了一个组合框,也就是HELLO WORLD,风格定义了TAB
LTEXT "自定义文字:", -1, 190, 40, 105, 10 ;定义了一个左对齐文本框和一个文本编辑
EDITTEXT IDC_CUSTOMTEXT, 190, 55, 105, 12
LTEXT "请在此选择显示在标题栏上面的文字,或者选择“自定义”后自行输入", -1, 191, 73, 105, 26, WS_BORDER ;定义了一个左对齐文本
CONTROL "", -1, "Static", SS_ETCHEDHORZ | WS_CHILD | WS_VISIBLE, 5, 110, 300, 1 ;画了一条横线设置横线用的是:SS_ETCHEDHORZ设置竖线用的是:SS_ETCHEDVERT从5.100开始大小时;300*1
DEFPUSHBUTTON "更换图片(&C)", IDOK, 200, 115, 50, 14 ;定义了一个更换图片的按钮,并制定了IDOK命令,可以使用键盘上的ENTER键控制
PUSHBUTTON "退出(&X)", IDCANCEL, 255, 115, 50, 14 ;定义了一个退出的按钮,并制定了IDCANCLE命令,可以使用键盘上的ESP键控制
CONTROL IDB_1, IDC_BMP, "Static", SS_BITMAP | WS_CHILD | WS_VISIBLE, 5, 5, 40, 95 ;定义了图片框的位置和大小其中IDC_BMP就是图片框控件的ID,这是由于本程序中要改变图片,如果不需变化可以指定为:-1
SCROLLBAR IDC_SCROLL, 6, 118, 125, 10 ;定义了一个滑动条,默认状态下是水平风格,如果指定了:SBS_VERT则为垂直
LTEXT "0", IDC_VALUE, 138, 119, 50, 8 ;这是滑动条后面数
}
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Sample code for < Win32ASM Programming 2nd Edition>
; by 罗云彬, http://asm.yeah.net
;详细注释:by 塘鱼
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Control.asm
; 对话框资源中子窗口控件的使用方法
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 使用 nmake 或下列命令进行编译和链接:
; ml /c /coff Control.asm
; rc Control.rc
; Link /subsystem:windows Control.obj Control.res
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat, stdcall
option casemap :none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
include gdi32.inc
includelib gdi32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Equ 等值定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN equ 1000h
DLG_MAIN equ 1
IDB_1 equ 1
IDB_2 equ 2
IDC_ONTOP equ 101
IDC_SHOWBMP equ 102
IDC_ALOW equ 103
IDC_MODALFRAME equ 104
IDC_THICKFRAME equ 105
IDC_TITLETEXT equ 106
IDC_CUSTOMTEXT equ 107
IDC_BMP equ 108
IDC_SCROLL equ 109
IDC_VALUE equ 110
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hInstance dd ? ;对话框实例句柄
hBmp1 dd ? ;位图句柄
hBmp2 dd ? ;位图句柄2
dwPos dd ? ;定义一个
.const
szText1 db 'Hello, World!',0 ;下拉菜单文本定义
szText2 db '嘿,你看到标题栏变了吗?',0
szText3 db '自定义',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcDlgMain proc uses ebx edi esi hWnd,wMsg,wParam,lParam ;对话框过程处理函数
local @szBuffer[128]:byte ;定义一个128字节的缓冲区
mov eax,wMsg ;分支处理消息
.if eax == WM_CLOSE ;遇到关闭消息时候,泯灭掉窗口,并delete掉位图
invoke EndDialog,hWnd,NULL
invoke DeleteObject,hBmp1
invoke DeleteObject,hBmp2
.elseif eax == WM_INITDIALOG ;用户自己定义的要处理的一些消息
;********************************************************************
; 设置标题栏图标
;********************************************************************
invoke LoadIcon,hInstance,ICO_MAIN ;调用loadicon函数,获取窗口图标,其值又loadicon函数返回在了eax中
invoke SendMessage,hWnd,WM_SETICON,ICON_BIG,eax ;根据,eax中的返回值调用sendmessage函数发送WM_SETICON命令,创立图标
;********************************************************************
; 初始化组合框
;********************************************************************
invoke SendDlgItemMessage,hWnd,IDC_TITLETEXT,CB_ADDSTRING,0,addr szText1 ;调用senddlgitenmessage函数向对话框发送cb_addstring命令,载入了预定义的文本
invoke SendDlgItemMessage,hWnd,IDC_TITLETEXT,CB_ADDSTRING,0,addr szText2 ;调用senddlgitenmessage函数向对话框发送cb_addstring命令,载入了预定义的文本
invoke SendDlgItemMessage,hWnd,IDC_TITLETEXT,CB_ADDSTRING,0,addr szText3 ;调用senddlgitenmessage函数向对话框发送cb_addstring命令,载入了预定义的文本
invoke SendDlgItemMessage,hWnd,IDC_TITLETEXT,CB_SETCURSEL,0,0
invoke GetDlgItem,hWnd,IDC_CUSTOMTEXT ;获取用户自定义的文本的句柄
invoke EnableWindow,eax,FALSE ;由eax的返回值判断下面选框的状态,如果被选中则激活对话框
invoke LoadBitmap,hInstance,IDB_1 ;获取位图句柄,并保存到HBMP1
mov hBmp1,eax
invoke LoadBitmap,hInstance,IDB_2 ;获取位图句柄,并保存HBMP2
mov hBmp2,eax
;********************************************************************
; 初始化单选钮和复选框 ;程序运行的时候可以发现,显示图片,允许更换图片和可变边框是被选中的
;********************************************************************
invoke CheckDlgButton,hWnd,IDC_SHOWBMP,BST_CHECKED ;调用checkdlgbutton设置选中的状态,有checked,unchecked,indeterminate三种状态
invoke CheckDlgButton,hWnd,IDC_ALOW,BST_CHECKED
invoke CheckDlgButton,hWnd,IDC_THICKFRAME,BST_CHECKED ;单选框之所以也能这样设置,是由于我们在资源中定义的是自动单选框
;********************************************************************
; 初始化滚动条
;********************************************************************
invoke SendDlgItemMessage,hWnd,IDC_SCROLL,SBM_SETRANGE,0,100 ;调用senddlgitemmessage函数直接向对话框窗口发送创建滚动条的消息,sbm_setrange,0 ~100是滚动条范围
.elseif eax == WM_COMMAND ;用户自己处理的命令
mov eax,wParam
.if ax == IDCANCEL ;当遇到取消或键盘按下esP键的时候调用enddialog函数泯灭对话框,delete掉位图
invoke EndDialog,hWnd,NULL
invoke DeleteObject,hBmp1
invoke DeleteObject,hBmp2
;********************************************************************
; 更换图片
;********************************************************************
.elseif ax == IDOK ;当idok或者是键盘上enter按钮被选中时,我们把位图句柄hbmp1赋值到eax,交换HBMP2的值,现在eax中放入的就是hbmp2,然后交换
mov eax,hBmp1
xchg eax,hBmp2
mov hBmp1,eax
invoke SendDlgItemMessage,hWnd,IDC_BMP,STM_SETIMAGE,IMAGE_BITMAP,eax ;调用senddlgitemmessage函数,发送STM_SETIMAGE命令,使用eax中的句柄值设置图片格式为IMAGE_BITMAP位图,
;********************************************************************
; 设置是否“总在最前面”
;********************************************************************
.elseif ax == IDC_ONTOP
invoke IsDlgButtonChecked,hWnd,IDC_ONTOP ;调用isdlgbuttonchecked函数检测复选框总在前面按钮的状态
.if eax == BST_CHECKED
invoke SetWindowPos,hWnd,HWND_TOPMOST,0,0,0,0,\ ;调用setwindowpos函数,设置窗口大小啊,位置啊等等风格!如果选中,设置成总在前面的风格并且不移动和不改变大小(SWP_NOMOVE or SWP_NOSIZE)
SWP_NOMOVE or SWP_NOSIZE
.else
invoke SetWindowPos,hWnd,HWND_NOTOPMOST,0,0,0,0,\ ;其他时候,取消总在前面的风格
SWP_NOMOVE or SWP_NOSIZE
.endif
;********************************************************************
; 演示隐藏和显示图片控件
;********************************************************************
.elseif ax == IDC_SHOWBMP
invoke GetDlgItem,hWnd,IDC_BMP ;调用getdlgitem函数获取图片框控件的句柄,将值存放在ebx中
mov ebx,eax
invoke IsWindowVisible,ebx ;调用iswindowvisible函数返回位图句柄的状态
.if eax ;如果有返回值表示有图片显示则设定为隐藏
invoke ShowWindow,ebx,SW_HIDE
.else ;相反条件则显示
invoke ShowWindow,ebx,SW_SHOW
.endif
;********************************************************************
; 演示允许和灰化“更换图片”按钮
;********************************************************************
.elseif ax == IDC_ALOW ;分支判断IDC_ALOW命令,也就是允许更换图片复选框是否被选中
invoke IsDlgButtonChecked,hWnd,IDC_ALOW ;调用:isdlgbuttonchecked函数,检测复选框被选中的状态
.if eax == BST_CHECKED ;如果复选框被选中,返回布尔的TRUE值,表示处理完毕
mov ebx,TRUE
.else ;否则,使用异或指令:xor由于相同则0的原则,把ebx清0,返回了布尔值fault!表示未处理完毕
xor ebx,ebx
.endif
invoke GetDlgItem,hWnd,IDOK ;调用函数,getdlgitem函数可以专门获取控件ID,IDOK的窗口句柄,其返回值存放在:eax中,
invoke EnableWindow,eax,ebx ;调用enablewindow函数,设置更换图片按钮为,灰色。
;********************************************************************
;模态边框和非模态边框的选择
;********************************************************************
.elseif ax == IDC_MODALFRAME
invoke GetWindowLong,hWnd,GWL_STYLE ;调用getwindowslong函数返回窗口风格,返回值是32位的
and eax,not WS_THICKFRAME ;(and)与上not ws_thickframe风格,由于and指令全1为1,有0则0。那么,你在非模态下拉大了对话框,从新设置的时候,保留拉大,设定为模态
invoke SetWindowLong,hWnd,GWL_STYLE,eax
.elseif ax == IDC_THICKFRAME
invoke GetWindowLong,hWnd,GWL_STYLE ;设置非模态对话框原理同上,不做详解了;
or eax,WS_THICKFRAME
invoke SetWindowLong,hWnd,GWL_STYLE,eax
;********************************************************************
; 演示处理下拉式组合框
;********************************************************************
.elseif ax == IDC_TITLETEXT ;下拉组合框消息
shr eax,16 ;由于低16存放的是控件ID,使用逻辑右移指令,把通知码移向低16位方便操作
.if ax == CBN_SELENDOK ;CBN_SELENDOK表示用户完成了选择消息
invoke SendDlgItemMessage,hWnd,IDC_TITLETEXT,CB_GETCURSEL,0,0 ;发送CB_GETCURSEL获取当前位置索引
.if eax == 2 ;标号是2表示下拉菜单的第三项被选中
invoke GetDlgItem,hWnd,IDC_CUSTOMTEXT ;获取用户自定义的文本框
invoke EnableWindow,eax,TRUE ;激活此文本框,用户就可以输入了
.else
mov ebx,eax
invoke SendDlgItemMessage,hWnd,IDC_TITLETEXT,CB_GETLBTEXT,ebx,addr @szBuffer;获取当前位置字符串索引,缓冲区必须足够大
invoke SetWindowText,hWnd,addr @szBuffer ;设置为标题
invoke GetDlgItem,hWnd,IDC_CUSTOMTEXT ;获取用户自定义文本框的句柄
invoke EnableWindow,eax,FALSE ;将自定义的窗口灰化
.endif
.endif
;********************************************************************
; 在文本框中输入文字会显示在标题栏上
;********************************************************************
.elseif ax == IDC_CUSTOMTEXT ;分支判断,检测用户是否向文本输入信息COSTOMETEXT
invoke GetDlgItemText,hWnd,IDC_CUSTOMTEXT,addr @szBuffer,sizeof @szBuffer ;调用:getdlgitemtext函数获取文本,其值存放在缓冲区中
invoke SetWindowText,hWnd,addr @szBuffer ;调用setwindowtext函数设置为标题,
.endif
;********************************************************************
; 处理滚动条消息
;********************************************************************
.elseif eax == WM_HSCROLL ;分支判断,检测用户对滚动条的操作:WM_HSCOLL
mov eax,wParam ;需要注意的是:wparam中的低字节存放的是滚动条的动作码,高字节存放的检测是滚动条的位置,但只是在SB_THUMBPOSITION SB_THUMBTRACK的时候有值,其余的时候其值为零
.if ax == SB_LINELEFT ;一下4句实现的分别是:左右移动一行和一列
dec dwPos
.elseif ax == SB_LINERIGHT
inc dwPos
.elseif ax == SB_PAGELEFT
sub dwPos,10
.elseif ax == SB_PAGERIGHT
add dwPos,10
.elseif ax == SB_THUMBPOSITION || ax == SB_THUMBTRACK ;检测滚动条的当前位置
mov eax,wParam
shr eax,16 ;汇编指令SHR逻辑右移,将动作码清零,eax中只存放着滚动条的位置
mov dwPos,eax
.else ;处理完毕后返回布尔真值,表示处理完毕
mov eax,TRUE
ret
.endif
cmp dwPos,0 ;对越界进行操作,之所以不能使用if是由于if是用于无符号数的操纵
jge @F ;小于零则重置为零,大于零 调到最近标号继续判断是否小于100
mov dwPos,0
@@:
cmp dwPos,100
jle @F ;如果大于100则重置为100,如果小于100的跳掉标号处执行
mov dwPos,100
@@:
invoke SetDlgItemInt,hWnd,IDC_VALUE,dwPos,FALSE ;调用SETDLGITEMINT函数可以设置对话框控件文本,false表示的是无符号数
invoke SendDlgItemMessage,hWnd,IDC_SCROLL,SBM_SETPOS,dwPos,TRUE ;重绘滚动条调用senddlgitemmessage函数发送SBM_SETPOS命令给控件,设置滚动条到新的位置用户才能看到滚动条的移动,最后一个 参数是true表示重新绘画滚动条
;********************************************************************
.else
mov eax,FALSE ;如果用户没有操作滚动条,则将布尔值设为false,表示没有操作
ret
.endif
mov eax,TRUE ;整个对话框过程处理完毕,将布尔值设为true返回
ret
_ProcDlgMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start: ;程序从此开始
invoke GetModuleHandle,NULL ;调用getmodulehandle函数,获得对话框实例句柄
mov hInstance,eax
invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,NULL ;调用DIALOGBOXPARAM函数,使窗口出现,从对话框实例句柄hinstance中载入资源中的DLG_MAIN,并定义了对话框专门的过程处理函数:_ProcDlgMain!
invoke ExitProcess,NULL ;程序退出
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//资源文件详解:by 塘鱼
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#include <resource.h> ;脚本资源定义
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#define ICO_MAIN 0x1000 //图标 ;宏定义图标
#define DLG_MAIN 1 ;宏定义对话框
#define IDB_1 1 ;宏定义了两张位图
#define IDB_2 2
#define IDC_ONTOP 101
#define IDC_SHOWBMP 102
#define IDC_ALOW 103
#define IDC_MODALFRAME 104
#define IDC_THICKFRAME 105
#define IDC_TITLETEXT 106
#define IDC_CUSTOMTEXT 107
#define IDC_BMP 108
#define IDC_SCROLL 109
#define IDC_VALUE 110
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN ICON "Main.ico" ;关联了图标
IDB_1 BITMAP "Picture1.bmp" ;关联了两张位图
IDB_2 BITMAP "Picture2.bmp"
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
DLG_MAIN DIALOG 193, 180, 310, 134 ;对话框详细定义
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME ;风格定义
CAPTION "对话框子窗口控制示例" ;标题定义
FONT 9, "宋体" ;字体定义
{
GROUPBOX "选项", -1, 55, 5, 120, 100 ;画了一个框框,名字是选项,从65.20开始大小是:120*100,没有文本的groupbox其实就相当于一个边框
AUTOCHECKBOX "总在最前面", IDC_ONTOP, 65, 20, 100, 12 ;定义了三个自动复选框
AUTOCHECKBOX "显示图片", IDC_SHOWBMP, 65, 35, 100, 12
AUTOCHECKBOX "允许更换图片", IDC_ALOW, 65, 50, 100, 12
CONTROL "", -1, "Static", SS_ETCHEDHORZ | WS_CHILD | WS_VISIBLE, 60, 65, 110, 1 ;画了一条直线,由于没有简化定义,只有使用这种方法了
AUTORADIOBUTTON "模态边框(&Modal Frame)", IDC_MODALFRAME, 65, 70, 100, 12, WS_TABSTOP ;定义了两个自动单选框
AUTORADIOBUTTON "可变边框(&Thick Frame)", IDC_THICKFRAME, 65, 85, 100, 12, WS_TABSTOP
GROUPBOX "标题栏文字", -1, 180, 5, 125, 100, BS_GROUPBOX ;画了个框框,并把它们定义为一个组
COMBOBOX IDC_TITLETEXT, 190, 20, 105, 70, CBS_DROPDOWNLIST | WS_TABSTOP ;定义了一个组合框,也就是HELLO WORLD,风格定义了TAB
LTEXT "自定义文字:", -1, 190, 40, 105, 10 ;定义了一个左对齐文本框和一个文本编辑
EDITTEXT IDC_CUSTOMTEXT, 190, 55, 105, 12
LTEXT "请在此选择显示在标题栏上面的文字,或者选择“自定义”后自行输入", -1, 191, 73, 105, 26, WS_BORDER ;定义了一个左对齐文本
CONTROL "", -1, "Static", SS_ETCHEDHORZ | WS_CHILD | WS_VISIBLE, 5, 110, 300, 1 ;画了一条横线设置横线用的是:SS_ETCHEDHORZ设置竖线用的是:SS_ETCHEDVERT从5.100开始大小时;300*1
DEFPUSHBUTTON "更换图片(&C)", IDOK, 200, 115, 50, 14 ;定义了一个更换图片的按钮,并制定了IDOK命令,可以使用键盘上的ENTER键控制
PUSHBUTTON "退出(&X)", IDCANCEL, 255, 115, 50, 14 ;定义了一个退出的按钮,并制定了IDCANCLE命令,可以使用键盘上的ESP键控制
CONTROL IDB_1, IDC_BMP, "Static", SS_BITMAP | WS_CHILD | WS_VISIBLE, 5, 5, 40, 95 ;定义了图片框的位置和大小其中IDC_BMP就是图片框控件的ID,这是由于本程序中要改变图片,如果不需变化可以指定为:-1
SCROLLBAR IDC_SCROLL, 6, 118, 125, 10 ;定义了一个滑动条,默认状态下是水平风格,如果指定了:SBS_VERT则为垂直
LTEXT "0", IDC_VALUE, 138, 119, 50, 8 ;这是滑动条后面数
}
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
赞赏
看原图
赞赏
雪币:
留言: