1

リストボックスが入ったウィンドウを開こうとしています。ただし、何も起こりません。Windowsのタスクマネージャで約5秒間開いたままになり、その後閉じます。

Flat Assembler(http://flatassembler.net/)を使用して、プログラムをアセンブルおよびリンクしています。

    format PE GUI 4.0
    entry Start
    jp Start
    include 'win32a.inc'

    library kernel, 'KERNEL32.DLL', \
            user,   'USER32.DLL',   \
            gdi,    'GDI32.DLL'

    import kernel,\
           GetModuleHandle,  'GetModuleHandleA',\
           ExitProcess,      'ExitProcess'

    import user,\
           RegisterClass,    'RegisterClassA',  \
           CreateWindowEx,   'CreateWindowExA', \
           DefWindowProc,    'DefWindowProcA',  \
           SetWindowLong,    'SetWindowLongA',  \
           RedrawWindow,     'RedrawWindow',    \
           GetMessage,       'GetMessageA',     \
           TranslateMessage, 'TranslateMessage',\
           DispatchMessage,  'DispatchMessageA',\
           SendMessage,      'SendMessageA',    \
           LoadCursor,       'LoadCursorA',     \
           LoadIcon,         'LoadIconA',       \
           LoadMenu,         'LoadMenuA',       \
           GetClientRect,    'GetClientRect',   \
           MoveWindow,       'MoveWindow',      \
           SetFocus,         'SetFocus',        \
           MessageBox,       'MessageBoxA',     \
           PostQuitMessage,  'PostQuitMessage', \
           ShowWindow,       'ShowWindow'

    import gdi,\
           DeleteObject,     'DeleteObject'


    MENU_FILE_OPEN  = 101
    MENU_FILE_EXIT  = 102
    MENU_HELP_ABOUT = 901

Start:
    invoke GetModuleHandle, $00
    mov    [wc.hInstance],  eax
    invoke LoadIcon,        eax, $11
    mov    [wc.hIcon],      eax
    invoke LoadCursor,      $00, IDC_ARROW
    mov    [wc.hCursor],    eax
    invoke RegisterClass,   wc
    test   eax,             eax
    jz     Error

    invoke LoadMenu, [wc.hInstance], $25
    invoke CreateWindowEx, $0, str_win_class, str_title,\
                           WS_VISIBLE + WS_OVERLAPPEDWINDOW, $20, $20\
                           $100, $da, $0, eax, [wc.hInstance], $0
    mov    [hWnd], eax
    test   eax, eax
    jz     Error

    invoke ShowWindow, hWnd, SW_SHOWNORMAL

MessageLoop:
    invoke GetMessage, message, NULL, $0, $0
    cmp    eax, $1
    jb     EndLoop
    jne    MessageLoop
    invoke TranslateMessage, message
    invoke DispatchMessage,  message
    jmp    MessageLoop

Error:
    invoke MessageBox, NULL, str_error_open, str_error_title,\
                       MB_ICONERROR + MB_OK

EndLoop:
    invoke ExitProcess, [message.wParam]



proc WindowProc hWnd, wMsg, wParam, lParam
    push   ebx esi edi
    cmp    [wMsg], WM_CREATE
    je     .wmcreate
    cmp    [wMsg], WM_SIZE
    je     .wmsize
    cmp    [wMsg], WM_SETFOCUS
    je     .wmsetfocus
    cmp    [wMsg], WM_COMMAND
    je     .wmcommand
    cmp    [wMsg], WM_DESTROY
    je     .wmdestroy

  .defwndproc:
    invoke DefWindowProc, [hWnd], [wMsg], [wParam], [lParam]
    jmp    .finish

  .wmcreate:
    invoke GetClientRect, [hWnd], client
    invoke CreateWindowEx, WS_EX_CLIENTEDGE, str_listbox, $0, WS_VISIBLE +    \
                           WS_CHILD + WS_VSCROLL + ES_AUTOVSCROLL,            \
                           [client.left], [client.top], [client.right],       \
                           [client.bottom], [hWnd], $0, [wc.hInstance], $0
    or     eax, eax ; To check if EAX equals zero
    jz     .failed
    mov    [listHWnd], eax
    xor    eax, eax
    jmp    .finish

  .failed:
    or     eax, -1
    jmp    .finish

  .wmsize:
    invoke GetClientRect, [hWnd], client
    invoke MoveWindow, [listHWnd], [client.left], [client.top], [client.right],\
                       [client.bottom], $1
    xor    eax, eax
    jmp    .finish

  .wmsetfocus:
    invoke SetFocus, [listHWnd]
    xor    eax, eax
    jmp    .finish

  .wmcommand:
    mov    eax, [wParam]
    and    eax, $ffff
    cmp    eax, MENU_FILE_OPEN
    je     .open
    cmp    eax, MENU_FILE_EXIT
    je     .wmdestroy
    cmp    eax, MENU_HELP_ABOUT
    je     .about
    jmp    .defwndproc

  .open:
    ; TODO Ask the user which file to open
    invoke MessageBox, [hWnd], str_info_todo, str_title_todo,                 \
                       MB_ICONINFORMATION + MB_OK
    xor    eax, eax
    jmp    .finish

  .about:
    invoke MessageBox, [hWnd], str_about_text, str_about_title, MB_OK
    xor    eax, eax
    jmp    .finish

  .wmdestroy:
    invoke PostQuitMessage, $0
    xor    eax, eax

  .finish:
    pop    edi esi ebx
    ret
endp

    str_title       db 'MegaChip8 Emulator', $00
    str_error_title db 'Error', $00
    str_error_open  db 'Couldn', $27, 't open window!', $00
    str_win_class   db 'MEGACHIP8', $00
    str_listbox     db 'LISTBOX', $00
    str_info_todo   db 'This function is still on the to-do list.', $00
    str_title_todo  db 'To-Do', $00
    str_about_title db 'About MegaChip8 Emulator', $00
    str_about_text  db 'This emulator is written by Sijmen "Vijfhoek" Schoon.',\
                       $0d, $0a, 'All rights reserved.', $00

    message MSG
    wc WNDCLASS 0, WindowProc, 0, 0, NULL, NULL, NULL, COLOR_BTNFACE + 1,\
                NULL, str_win_class
    client RECT

    hWnd dd ?
    listHWnd dd ?
4

1 に答える 1

1

ええと、私もFASMを使っているので、自分で試して何が問題なのかを調べる方が簡単です。あなたは明らかにセクションを宣言するのを忘れています。したがって、「インポート」セクションはありません=>WindowsはDLLをバインドしません。正しいコードは次のとおりです。

format PE GUI 4.0
entry Start
include 'win32a.inc'

section '.idata' import data readable writeable

library kernel, 'KERNEL32.DLL', \
        user,   'USER32.DLL',   \
        gdi,    'GDI32.DLL'

import kernel,\
       GetModuleHandle,  'GetModuleHandleA',\
       ExitProcess,      'ExitProcess'

import user,\
       RegisterClass,    'RegisterClassA',  \
       CreateWindowEx,   'CreateWindowExA', \
       DefWindowProc,    'DefWindowProcA',  \
       SetWindowLong,    'SetWindowLongA',  \
       RedrawWindow,     'RedrawWindow',    \
       GetMessage,       'GetMessageA',     \
       TranslateMessage, 'TranslateMessage',\
       DispatchMessage,  'DispatchMessageA',\
       SendMessage,      'SendMessageA',    \
       LoadCursor,       'LoadCursorA',     \
       LoadIcon,         'LoadIconA',       \
       LoadMenu,         'LoadMenuA',       \
       GetClientRect,    'GetClientRect',   \
       MoveWindow,       'MoveWindow',      \
       SetFocus,         'SetFocus',        \
       MessageBox,       'MessageBoxA',     \
       PostQuitMessage,  'PostQuitMessage', \
       ShowWindow,       'ShowWindow'

import gdi,\
       DeleteObject,     'DeleteObject'


MENU_FILE_OPEN  = 101
MENU_FILE_EXIT  = 102
MENU_HELP_ABOUT = 901

section '.text' code readable executable

Start:
invoke GetModuleHandle, $00
mov    [wc.hInstance],  eax
invoke LoadIcon,        eax, $11
mov    [wc.hIcon],      eax
invoke LoadCursor,      $00, IDC_ARROW
....

セクションが宣言されていない場合、FASMはファイルを通常のPEにするために「.flat」を追加します。ただし、インポートフラグはありません。そのため、ブレークポイントの設定に問題がありました。

于 2013-01-04T10:00:58.313 に答える