首页
社区
课程
招聘
[旧帖] [原创]发一个罗云斌的control代码的详细解释附带资源解释,有不足和错误之处还望各位多多指教,多谢 0.00雪花
发表于: 2010-12-15 19:34 825

[旧帖] [原创]发一个罗云斌的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                                                                                                ;这是滑动条后面数                                                                               
}
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


[课程]FART 脱壳王!加量不加价!FART作者讲授!

收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 216
活跃值: (144)
能力值: ( LV10,RANK:160 )
在线值:
发帖
回帖
粉丝
2
用vc做汇编的ide开发最方便不过了
2010-12-15 22:00
0
游客
登录 | 注册 方可回帖
返回
//