News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Yet Another Iczelion Tutorial 10 Part 1

Started by markallyn, April 19, 2018, 01:36:50 AM

Previous topic - Next topic

markallyn

Hello everyone,

Following in _Mikl's steps I have attempted another version of Iczelion's Tutorial 10 (Dialog box).  I offer this in hopes that others will point out ways in which the coding style could be (and should be) improved.  I do not know if you folks would consider it to be written in "new style" or "old style".  I have attached a zip file with the .asm, .rc, and .bat file.


    OPTION DOTNAME
    option casemap:none
   
    include \masm32\include64\masm64rt.inc
   
    .data
      ClassName db "DLGCLASS",0
      AppName   db "Our First Dialog Box",0
      DlgName   db "MyDialog",0
      MenuName  db "MyMenu",0
      TestString db "Forg Yu!",0

    .data?
      hInstance dq ?
      hWnd      dq ?
      sWid      dq ?
      sHgt      dq ?
      lft       dq ?
      top       dq ?
      wid       dq ?
      hgt       dq ?
      hIcon     dq ?
      hMnu      dq ?
      hDlg      dq ?
      buffer db 512 dup(?)
   
    .const
      IDC_EDIT equ  3000
      IDC_BUTTON  equ  3001
      IDC_EXIT  equ 3002
      IDM_GETTEXT  equ  32000
      IDM_CLEAR  equ  32001
      IDM_EXIT  equ  32002

     
    .code

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

main proc

    LOCAL wc:WNDCLASSEX

    mov hInstance, rv(GetModuleHandle,0)
    mov hIcon, rv(LoadIcon,hInstance,10)

    mov wc.cbSize,          SIZEOF WNDCLASSEX
    mov wc.style,           CS_HREDRAW or CS_VREDRAW
    mrm wc.lpfnWndProc,     OFFSET WndProc
    mov wc.cbClsExtra,      0
    mov wc.cbWndExtra,      DLGWINDOWEXTRA
    mrm wc.hInstance,       hInstance
    mrm wc.hIcon,           hIcon
    mov wc.hCursor,         10003h
    mov wc.hbrBackground,   COLOR_BTNFACE+1
    mrm wc.lpszMenuName,    OFFSET MenuName
    mrm wc.lpszClassName,   OFFSET ClassName
    mrm wc.hIconSm,         hIcon

    invoke RegisterClassEx, ADDR wc
    invoke CreateDialogParam, hInstance, ADDR DlgName, NULL, NULL, NULL
    mov hDlg, rax
    invoke ShowWindow, hDlg, SW_SHOWNORMAL
    invoke UpdateWindow, hDlg
    invoke GetDlgItem, hDlg, IDC_EDIT
    invoke SetFocus, rax
   
    call msgloop
   
    invoke ExitProcess, rax

    ret

main endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

msgloop proc

    LOCAL msg   :MSG

    mov r11, rdi                ; preserve rdi
    lea rdi, msg                ; load structure address
    jmp gmsg

  @@:
    invoke IsDialogMessage, hDlg, ADDR msg
    .if rax==TRUE
    jmp gmsg
    .endif
    invoke TranslateMessage,rdi
   
    invoke DispatchMessage,rdi
  gmsg:
    invoke GetMessage,rdi,0,0,0
   
    test rax, rax
    jnz @B

    mov rdi, r11                ; restore rdi
    ret

msgloop endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

WndProc proc

    LOCAL hWin      :QWORD
    LOCAL uMsg      :QWORD
    LOCAL wParam    :QWORD
    LOCAL lParam    :QWORD

    mov hWin, rcx
    mov uMsg, rdx
    mov wParam, r8
    mov lParam, r9
    .if uMsg == WM_DESTROY
      invoke PostQuitMessage,NULL

    .elseif uMsg == WM_COMMAND
      mov rax, wParam
      mov rbx, lParam
      .if lParam==0
        .if ax==IDM_GETTEXT
  invoke GetDlgItemText, hWin, IDC_EDIT, ADDR buffer, 512
  invoke MessageBox, NULL, ADDR buffer, ADDR AppName, MB_OK
        .elseif ax==IDM_CLEAR
          invoke SetDlgItemText, hWin, IDC_EDIT, NULL
        .else
  invoke DestroyWindow, hWin
        .endif
       .else
        mov rdx, wParam
        shr edx, 16
        .if dx==BN_CLICKED
          .if ax==IDC_BUTTON
            invoke SetDlgItemText, hWin, IDC_EDIT, ADDR TestString
          .elseif ax==IDC_EXIT
            invoke SendMessage, hWin, WM_COMMAND, IDM_EXIT, 0
          .endif
         .endif
        .endif
    .else
      invoke DefWindowProc,hWin,uMsg,wParam,lParam
.endif
ret

WndProc endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

end



I am trying hard to write acceptable quality code.  Hopefully this is an approximation to the goal that is not too far off the mark.

Mark Allyn

aw27

I have not download, I presume you tested and it works but why are you saving a non-volatile register in a volatile register and expecting it to be preserved?
mov r11, rdi                ; preserve rdi

hutch--

Mark,

Replace,

WndProc proc

    LOCAL hWin      :QWORD
    LOCAL uMsg      :QWORD
    LOCAL wParam    :QWORD
    LOCAL lParam    :QWORD

    mov hWin, rcx
    mov uMsg, rdx
    mov wParam, r8
    mov lParam, r9


With this.


WndProc proc hWin:QWORD,uMsg:QWORD,wParam:QWORD,lParam:QWORD


These addresses are already correct, no point in duplicating them with LOCAL values.


    OPTION DOTNAME
    option casemap:none


This is already included in the masm64rt.inc file, no point in duplicating them.

Mikl__

Hi, Mark!
asm-file; GUI #
include win64a.inc
IDM_SAYHELLO equ 0
IDM_GETTEXT equ 1
IDM_CLEAR equ 2
IDM_EXIT equ 3
IDC_EDIT equ 0
IDC_BUTTON equ 1
IDC_EXIT equ 2
IDC_MENU equ 100
IDC_DIALOG equ 200
IDC_ICON1 equ 500
.code
WinMain proc
local msg:MSG
local hwnd:QWORD

mov esi,IMAGE_BASE
xor ebx,ebx
mov edi,offset ClassName
push rbx ;hIconSm
push rdi ;lpszClassName
push IDC_MENU ;lpszMenuName
push COLOR_BTNFACE+1;hbrBackground
push 10005h ;hCursor
push rbx        ;hIcon
push rsi ;hInstance
push DLGWINDOWEXTRA;cbClsExtra & cbWndExtra
pushaddr dialog_procedure;lpfnWndProc
push sizeof WNDCLASSEX;cbSize & style
invoke RegisterClassEx,esp ;addr WNDCLASSEX
mov r9d,offset dialog_procedure
;mov [esp+20h],r8;IDC_MENU
invoke CreateDialogParam,IMAGE_BASE,IDC_DIALOG,0,,0
mov hwnd,rax
lea edi,msg
message_loop:invoke GetMessage,edi,0,0,0
or eax,eax
jz exit_msg_loop
invoke IsDialogMessage,hwnd,edi
or eax,eax
jnz message_loop
invoke DispatchMessage,edi
        jmp message_loop
exit_msg_loop:invoke RtlExitUserProcess,NULL
WinMain endp

dialog_procedure proc hDlg:QWORD,uMsg:QWORD,wParam:QWORD,lParam:QWORD
size_of_buffer equ 96
local buffer[size_of_buffer]:BYTE

mov hDlg,rcx

cmp edx,WM_CLOSE
je wmCLOSE
        cmp edx,WM_INITDIALOG
je wmINITDIALOG
cmp edx,WM_COMMAND
jne wmBYE
wmCOMMAND:movzx rax,r8w ;movzx eax,word ptr wParam
or r9,r9 ;cmp lParam,0
jnz @f
jmp [menu_handlers+rax*8]; choose menu
; choose button or EditBox
@@: dec eax ;cmp eax,IDC_BUTTON=1
jne @f
SAYHELLO:mov r8d,offset expTxt
jmp @0
@@: dec eax ;cmp eax,IDC_EXIT=2
jne wmBYE
invoke SendMessage,,WM_CLOSE,0,0
jmp wmBYE
CLEAR: xor r8d,r8d
@0: invoke SetDlgItemText,,0
jmp wmBYE
GETTEXT:lea r8d,buffer
invoke GetDlgItemText,,0,,size_of_buffer
lea edx,buffer
mov mb.lpszText,rdx
        lea ecx,mb
invoke MessageBoxIndirect
jmp wmBYE
wmINITDIALOG:invoke LoadIcon,IMAGE_BASE,IDC_ICON1
invoke SendMessage,hDlg,WM_SETICON,0,rax
jmp wmBYE
wmCLOSE:invoke DestroyWindow;,hDlg
invoke PostQuitMessage,0
wmBYE:  xor eax,eax
leave
retn
menu_handlers dq SAYHELLO,GETTEXT,CLEAR,wmCLOSE
dialog_procedure endp
;---------------------------------------
ClassName db 'DLGCLASS',0
expTxt db "Wow! I'm in an edit box now",0
AppName db 'Our Third Dialog Box',0
mb label   MSGBOXPARAMS
  dd sizeof MSGBOXPARAMS,?;cbSize      
  dq 0  ;hwndOwner
  dq IMAGE_BASE  ;hInstance      
  dq ?  ;lpszText    
  dq AppName  ;lpszCaption
  dd MB_OK or MB_USERICON,?;dwStyle
  dq IDC_ICON1  ;lpszIcon
  dd 0,?;dwContextHelpId
  dq 0  ;lpfnMsgBoxCallback
  dd 0,?;dwLanguageId
end

rc-file
#include "resource.h"

#define IDM_SAYHELLO 0
#define IDM_GETTEXT 1
#define IDM_CLEAR 2
#define IDM_EXIT 3
#define IDC_EDIT 0
#define IDC_BUTTON 1
#define IDC_EXIT 2

#define IDC_MENU 100
#define IDC_DIALOG 200
#define IDC_ICON1 500

IDC_ICON1 ICON "Images\\br_Fox1.ico"
IDC_DIALOG DIALOG 10, 10, 205, 60
STYLE 0x0004 | DS_CENTER | WS_CAPTION | WS_MINIMIZEBOX |
WS_SYSMENU | WS_VISIBLE | WS_OVERLAPPED | DS_MODALFRAME | DS_3DLOOK
CAPTION "Tutorial 10c: CreateDialogParam+WndProc+Class"
MENU IDC_MENU
BEGIN
    ICON IDC_ICON1,WS_VISIBLE | WS_CHILD | SS_ICON, 5,10,32,32
    EDITTEXT          IDC_EDIT,   25,17,111,13, ES_AUTOHSCROLL | ES_LEFT
    DEFPUSHBUTTON    "Say Hello", IDC_BUTTON,    141,10,52,13
    PUSHBUTTON      "E&xit", IDC_EXIT,  141,26,52,13
END


IDC_MENU  MENU
BEGIN
    POPUP "Test Controls"
    BEGIN
        MENUITEM "Say Hello",IDM_SAYHELLO
        MENUITEM "Get Text",IDM_GETTEXT
        MENUITEM "Clear Edit Box",IDM_CLEAR
        MENUITEM "", , 0x0800 /*MFT_SEPARATOR*/
        MENUITEM "E&xit",IDM_EXIT
    END
END

markallyn

aw27, Hutch, and Mikl__,

Thanks for the very helpful suggestions.  I will incorporate them in an updated version.  As you can see, I am a rank beginner when it comes to Windows GUI.  I want to turn this into a simple front-end for performing floating point calculations and solving coupled ordinary differential equations. 

Regards,
Mark