现在的位置: 首页 > 综合 > 正文

Win32汇编之模式对话框(实例+详解)

2018年02月09日 ⁄ 综合 ⁄ 共 3681字 ⁄ 字号 评论关闭

.asm文件如下:


.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
 
 
IDM_MAIN equ 2000h
IDM_SUBMENU1 equ 4101h
IDM_SUBMENU2 equ 4102h
IDM_EXIT equ 4103h
IDA_ACCELERATOR equ 3004h
 
 
.data
ClassName db "Menuandacccelerator",0
AppName db "使用菜单和加速例子程序",0
szAcce db "这个消息由加速键产生",0
szMenu db "这个消息由菜单产生",0
szSM1 db "子菜单1",0
szSM11 db "子菜单111",0
szSM2 db "子菜单2",0
;MenuName db "MyMenu",0     ;方法一 无需此步。方法二 第二步:数据段中声明资源文件中表示菜单的字符串
 
.data?
hInstance HINSTANCE ?
hMenu dd ?
hSubMenu dd ?
hAccelerator dd ?
 
 
.code
WndProc proc hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
            ;wParam参数高16位是通知码,低16位是命令ID  lParam是发送WM_COMMAND消息的子窗口句柄
            ;菜单消息的通知码是0,加速键消息的通知码是1
            ;对于菜单和加速键引发的WM_COMMAND消息,lParam的值为0
    LOCAL stPos:POINT
    .if uMsg==WM_CREATE
        invoke GetSubMenu,hMenu,0
        mov hSubMenu,eax
    .elseif uMsg==WM_RBUTTONDOWN  ;获取右键在窗口中点下的坐标
        invoke GetCursorPos,addr stPos
        invoke TrackPopupMenu,hSubMenu,TPM_LEFTALIGN,stPos.x,stPos.y,NULL,hWnd,NULL
    .elseif uMsg==WM_COMMAND
        mov eax,wParam
        mov ebx,eax
        rol ebx,16
        .if ax==IDM_SUBMENU1
            .if bx  ;如果是加速键
                invoke MessageBox,NULL,addr szSM11,addr szAcce,MB_OK
            .else   ;如果是菜单键
                invoke MessageBox,NULL,addr szSM1,addr szAcce,MB_OK             
            .endif
        .elseif ax==IDM_SUBMENU2
            .if bx
                invoke MessageBox,NULL,addr szSM2,addr szAcce,MB_OK
            .else
                invoke MessageBox,NULL,addr szSM2,addr szAcce,MB_OK             
            .endif
        .elseif ax==IDM_EXIT
            invoke DestroyWindow,hWnd
        .endif
    .elseif uMsg==WM_DESTROY
        invoke PostQuitMessage,NULL
    .else
        invoke DefWindowProc,hWnd,uMsg,wParam,lParam
        ret
    .endif
     
    xor eax,eax
    ret
 
WndProc endp
 
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
         
        LOCAL wc:WNDCLASSEX    ;wc是一个窗口类的结构体变量
        LOCAL msg: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  ;指定在WNDCLASSEX结构体后面申请多少个字节的空间
        mov wc.cbWndExtra,NULL  ;指定在窗口实例后面申请空间的字节数   
        push hInst 
        pop wc.hInstance ;保存窗口实例句柄
        mov wc.hbrBackground,COLOR_WINDOW+1 ;指定窗口背景颜色
         
        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 ;指定在该窗口上显示的光标样式
         
         
        ;mov wc.lpszMenuName,OFFSET MenuName ; 方法一:无需此步  方法二 第三步:(菜单名为字符串时使用此方法)
        invoke RegisterClassEx,addr wc  
        ;——————————————————————
        ;创建窗口对象
        ;——————————————————————
        invoke CreateWindowEx,NULL,\
        ADDR ClassName,\
        ADDR AppName,\
        WS_OVERLAPPEDWINDOW,\
        CW_USEDEFAULT,\
        CW_USEDEFAULT,\
        CW_USEDEFAULT,\
        CW_USEDEFAULT,\
        NULL,\
        hMenu,\ ;NULL,\         ; 方法一 第四步:hMenu (覆盖WNDCLASSEX结构体中指定的菜单) 。  方法二:使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==0
            invoke TranslateAccelerator,hwnd,hAccelerator,addr msg  
            ;TranslateAccelerator是实现加速键功能的关键,
            ;该函数检查消息结构中的消息,如果WM_KEYDOWN或WM_SYSKEYDOWN有效
            ;则Windows再检查加速键资源,查看按键是否符合某个加速键
            ;若符合,则windows向目标窗口发送WM_COMMAND或WM_SYSCOMMAND
            ;消息,并返回true 若不符合则不做任何处理,并返回FALSE
            .if eax==0
            invoke TranslateMessage,addr msg
            invoke DispatchMessage,addr msg
            .endif
             
        .endw
        mov eax,msg.wParam
        ret
 
    WinMain endp
     
    start:
       invoke GetModuleHandle,NULL    ;创建窗口第一步:得到应用程序的句柄
       mov hInstance,eax
       
       invoke LoadAccelerators,hInstance,IDA_ACCELERATOR   ;要先LoadAccelerators???
       mov hAccelerator,eax
     
       invoke LoadMenu,hInstance,IDM_MAIN    ;第二步:使用LoadMenu和LoadAccelerator函数加载菜单和加速键
       mov hMenu,eax
     
        
        
       invoke WinMain,hInstance,NULL,NULL,SW_SHOWDEFAULT
       invoke ExitProcess,eax
        
       end start


.rc资源文件如下:


#include<resource.h>
#define IDD_Caption 129
#define IDCANCEL 2
#define IDOK 1
#define IDC_Caption 1000
#define IDC_STATIC -1
 
IDD_Caption DIALOG DISCARDABLE 100,100,173,60
STYLE DS_MODALFRAME|WS_VISIBLE|WS_CAPTION|WS_SYSMENU
CAPTION "标题栏文字"
FONT 10,"System"
BEGIN
      DEFPUSHBUTTON "取消(&c)",IDCANCEL,106,39,37,13,WS_GROUP
      EDITTEXT  IDC_Caption,12,21,146,12,ES_AUTOHSCROLL
      LTEXT "请在此输入文字",IDC_STATIC,11,11,105,9
      DEFPUSHBUTTON "确定(&k)",IDOK,53,39,37,13,WS_GROUP
END


     
    

抱歉!评论已关闭.