组装中的InputBox函数

问题描述 投票:0回答:1

我必须编写一个小程序,允许用户通过MASM中的InputBox函数输入文本。我正在使用Visual Studio 2010专业版。当前,如果我想调用MessageBox函数,则包括以下行:

extrn  _MessageBoxW@16 : near

但是我如何包含InputBox?根据我的阅读,它是Visual Basic函数,对吗?很抱歉遇到这么愚蠢的问题,但是我现在只学习汇编语言大约一个月,我对整个“混合”编程交易感到满意。

winapi assembly x86 masm
1个回答
0
投票

WinApi不提供InputBox函数。您必须在对话框中自行构建它:

InputBox.asm

.386
.model flat,stdcall
option casemap:none

;include windows.inc
HWND                typedef DWORD
UINT                typedef DWORD
WPARAM              typedef DWORD
LPARAM              typedef DWORD
WM_SETTEXT          equ 0Ch
WM_GETTEXT          equ 0Dh
WM_GETTEXTLENGTH    equ 0Eh
WM_CLOSE            equ 10h
WM_INITDIALOG       equ 110h
WM_COMMAND          equ 111h
EM_LIMITTEXT        equ 0C5h
BN_CLICKED          equ 0
IDOK                equ 1
TRUE                equ 1

;include kernel32.inc
GetModuleHandleA        PROTO STDCALL :DWORD

;include user32.inc
DialogBoxIndirectParamA PROTO STDCALL :DWORD,:DWORD,:DWORD,:DWORD,:DWORD
GetDlgItem              PROTO STDCALL :DWORD,:DWORD
SendMessageA            PROTO STDCALL :DWORD,:DWORD,:DWORD,:DWORD
GetDlgItem              PROTO STDCALL :DWORD,:DWORD
EndDialog               PROTO STDCALL :DWORD,:DWORD

DlgProc PROTO hWnd:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD   ; Forward declaration

IDC_STATIC  equ 4001
IDC_EDIT    equ 4002
IDB_OK      equ 4003
IDB_CANCEL  equ 4004

.data

; DlgTemplateEx
ALIGN 4
DlgTemplateEx   dw 1, 0FFFFh    ; dlgVer, Signature
                dd 0, 0         ; helpID, exStyle
                dd 90C800CCh    ; style
                dw 4            ; cDlgItems
DlgBoxCoord     dw 300          ; x
                dw 250          ; y
                dw 120          ; cx
                dw 80           ; cy
                dw 0            ; menu
                dw 0            ; windowClass
                dw 0            ; title
                dw 12           ; pointsize
                dw 0            ; weight
                db 0            ; italic
                db 1            ; charset
                dw 'O','l','d',' ','E','n','g','l','i','s','h',' ','T','e','x','t',' ','M','T',0

ALIGN 4
        dd 0,0          ; helpID, exStyle
        dd 50020000h    ; style
        dw 10           ; x
        dw 5            ; y
        dw 150          ; cx
        dw 20           ; cy
        dd IDC_STATIC   ; id
        dw 0FFFFh, 82h  ; windowClass, Static
        dw 0            ; title
        dw 0            ; extraCount

ALIGN 4
        dd 0,0          ; helpID, exStyle
        dd 50810080h    ; style
        dw 10           ; x
        dw 25           ; y
        dw 100          ; cx
        dw 12           ; cy
        dd IDC_EDIT     ; id
        dw 0FFFFh, 81h  ; windowClass, Edit
        dw 0            ; title
        dw 0            ; extraCount

ALIGN 4
        dd 0,0          ; helpID, exStyle
        dd 50010000h    ; style
        dw 10           ; x
        dw 50           ; y
        dw 45           ; cx
        dw 15           ; cy
        dd IDB_OK       ; id
        dw 0FFFFh, 80h  ; windowClass, Button
        dw  'O','K',0   ; title: OK
        dw 0            ; extraCount

ALIGN 4
        dd 0,0          ; helpID, exStyle
        dd 50010000h    ; style
        dw 65           ; x
        dw 50           ; y
        dw 45           ; cx
        dw 15           ; cy
        dd IDB_CANCEL   ; id
        dw 0FFFFh, 80h  ; windowClass, Button
        dw 'C','a','n','c','e','l',0    ; title: Cancel
        dw 0            ; extraCount


.code

InputBox PROC pText:DWORD,\     ; address of text to displayed in the static control
            pCaption:DWORD,\    ; address of title of input box
            pBuffer:DWORD,\     ; address of buffer receiving the input text
            buffersize:DWORD,\
            xpos:DWORD,\        ; x-coordinate of input box
            ypos:DWORD,\        ; y-coordinate of input box
            pStringLen:DWORD    ; pointer to number of characters received to the input box

; Return values :

;           If the user clicks the OK button, the return value is 1
;           If the user clicks the cancel button, the return value is 0
;           The number of characters received to the input box

    mov   eax, ypos
    shl   eax, 16
    or    eax, xpos
    mov   DWORD PTR [DlgBoxCoord], eax ; set the coordinates of the input box

    invoke  GetModuleHandleA, 0
    lea   edx,[pText]                       ; get the stack address pointing the parameters of InputBox

    invoke  DialogBoxIndirectParamA,\       ;int DialogBoxIndirectParam(
                eax,\                       ;   HINSTANCE hInstance,  // handle to application instance
                ADDR DlgTemplateEx,\        ;   LPCDLGTEMPLATE hDialogTemplate, // identifies dialog box template
                0,\                         ;   HWND hWndParent,      // handle to owner window
                ADDR DlgProc,\              ;   DLGPROC lpDialogFunc, // pointer to dialog box procedure
                edx                         ;   LPARAM dwInitParam    // initialization value
    ret

InputBox ENDP


.data?

IBparams    dd ?
hEditBoxIB  dd ?
StringLenIB dd ?

.code

DlgProc PROC USES esi hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM

    .IF uMsg==WM_INITDIALOG

        mov     esi, lParam
        mov     IBparams, esi
        invoke  GetDlgItem, hWnd, IDC_STATIC
        invoke  SendMessageA, eax, WM_SETTEXT, 0, DWORD PTR [esi]       ; pText
        invoke  SendMessageA, hWnd, WM_SETTEXT, 0, DWORD PTR [esi+4]    ; pCaption
        invoke  GetDlgItem, hWnd, IDC_EDIT
        mov     hEditBoxIB, eax
        mov     edx, [esi+12]               ; buffersize
        dec edx
        invoke  SendMessageA, eax, EM_LIMITTEXT, edx, 0

        mov     StringLenIB, 0

    .ELSEIF uMsg==WM_CLOSE

        invoke  EndDialog, hWnd, 0

    .ELSEIF uMsg==WM_COMMAND

        mov  eax, wParam
        mov  edx, eax
        shr  edx, 16

        .IF dx==BN_CLICKED

            .IF ax==IDB_CANCEL

                invoke  EndDialog, hWnd, 0

            .ELSEIF ax==IDB_OK || ax==IDOK                         ; check also if RETURN \ ENTER is pressed

                mov esi, hEditBoxIB
                invoke  SendMessageA, esi, WM_GETTEXTLENGTH, 0, 0
                mov StringLenIB, eax
                test eax, eax                                  ; check the length of the input text
                jz @F                                      ; if no text is entered then quit application
                inc eax
                mov edx, IBparams
                invoke SendMessageA, esi, WM_GETTEXT, eax, DWORD PTR [edx+8]    ; DWORD PTR [edx] -> pointer to the buffer receiving keyboard input
                @@:
                mov ecx, IBparams
                mov edx, DWORD PTR [ecx+24]
                mov DWORD PTR [edx], eax
                invoke EndDialog, hWnd, 1

            .ENDIF

        .ENDIF

    .ELSE

        xor eax, eax
        ret

    .ENDIF

    mov  eax, TRUE
    ret

DlgProc ENDP

END

Demo.asm

.386
.model flat,stdcall
option casemap:none

;include windows.inc
MB_OK EQU 0

;include kernel32.inc
ExitProcess PROTO STDCALL :DWORD

;include user32.inc
MessageBoxA PROTO STDCALL :DWORD,:DWORD,:DWORD,:DWORD

; Extern - InputBox.asm
InputBox PROTO pText:DWORD,\      ; Address of text to displayed in the static control
               pCaption:DWORD,\   ; Address of title of input box
               pBuffer:DWORD,\    ; Address of buffer receiving the input text
               buffersize:DWORD,\ ; Size of buffer including the terminating NULL
               xpos:DWORD,\       ; X-coordinate of input box
               ypos:DWORD,\       ; Y-coordinate of input box
               pStringLen:DWORD   ; Pointer to number of characters received to the input box

IB_XPOS     equ 300
IB_YPOS     equ 250
buffersize  equ 32

.DATA
InputCaption    db 'InputBox',0
OutputCaption   db 'Your string is',0
msg             db 'Please enter a string',0
msg2            db 'Sorry, you did not type anything',13,10
                db 'Please try again',0

.CODE

demo PROC
LOCAL buffer[buffersize]:BYTE, StrLen:DWORD, message:DWORD

    mov message, OFFSET msg
    @@:
    invoke InputBox, message, ADDR InputCaption, ADDR buffer, buffersize, IB_XPOS, IB_YPOS, ADDR StrLen
    test   eax, eax                 ; Dialog cancelled?
    jz     finish                   ; Yes -> end the programm
    mov    eax, StrLen
    test   eax, eax                 ; StrLen == 0?
    jnz    @F                       ; Yes -> jump forward to the next @@
    mov    message, OFFSET msg2
    jmp    @B                       ; Jump backward to the last @@
    @@:
    invoke MessageBoxA, 0, ADDR buffer, ADDR OutputCaption, MB_OK

    finish:
    invoke ExitProcess, 0

demo ENDP

END demo

组装两个文件并将它们链接在一起。您可能需要添加对kernel32.lib和user32.lib的引用

© www.soinside.com 2019 - 2024. All rights reserved.