Small Windows programs

Posted:

For complicated reasons, I started playing with Flat Assembler today. Ripping apart someone else’s code, I was able to come up with this gem that creates a dialog box with a dead button. When compiled, the executable is a mere 2,500 bytes. I’m not sure I’d want to do an entire app in assembler, but it does seem to cut to the chase of the Windows API very well.

format PE GUI 4.0
entry codestart

include 'win32a.inc'

  IDD_MAIN             =  100
  ID_START             =  201

section '.data' data readable writeable
  hInstance dd ?

section '.code' code readable executable
  codestart:
    invoke  GetModuleHandle, 0
    mov     [hInstance], eax
    invoke  DialogBoxParam, eax, IDD_MAIN, HWND_DESKTOP, \
            MainDlg, 0
    invoke  ExitProcess, 0

  proc MainDlg hdlg, msg, wparam, lparam
    push    ebx esi edi
    cmp     [msg], WM_INITDIALOG
    je      .wminitdlg
    cmp     [msg], WM_COMMAND
    je      .wmcommand
    cmp     [msg], WM_CLOSE
    je      .wmclose
    xor     eax, eax
    jmp     .finish

    .wminitdlg:
      jmp     .finish

    .wmcommand:
      cmp     [wparam], BN_CLICKED shl 16 + ID_START
      je      .startbutton

    .wmclose:
      invoke  EndDialog, [hdlg], 0

    .startbutton:
      jmp     .finish

    .finish:
      pop     edi esi ebx
      ret
  endp

section '.idata' import data readable writeable

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

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

  import  user,\
      DialogBoxParam, 'DialogBoxParamA',\
      EndDialog,      'EndDialog'

section '.rsrc' resource data readable
  directory RT_DIALOG, dialogs
  resource  dialogs,\
        IDD_MAIN, LANG_ENGLISH + SUBLANG_DEFAULT, \
                main_dialog
  dialog    main_dialog, 'Dialog test', 0, 0, 150, 50, \
                WS_CAPTION + WS_POPUP + WS_SYSMENU +\
                DS_MODALFRAME + DS_CENTER
        dialogitem 'BUTTON', 'Hello', ID_START, \
                50, 15, 50, 20, WS_VISIBLE + WS_TABSTOP
  enddialog