News:

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

Main Menu

Examples for Win64 Iczelion tutorial

Started by Mikl__, April 30, 2015, 03:14:46 PM

Previous topic - Next topic

Mikl__

#15
Win x64 Tutorial #8b: Menu and template-structure
OPTION DOTNAME
option casemap:none
include temphls.inc
include win64.inc
include kernel32.inc
includelib kernel32.lib
include user32.inc
includelib user32.lib
OPTION PROLOGUE:rbpFramePrologue
OPTION EPILOGUE:rbpFrameEpilogue
ZZZ_TEST equ 0
ZZZ_OPEN equ 1
ZZZ_SAVE equ 2
ZZZ_EXIT equ 3
IMAGE_BASE equ 400000h
;----------------macros------------------
du macro string
local bslash
bslash = 0
irpc c,<string>
if bslash eq 0
if '&c' eq "/"
        bslash = 1
elseif '&c'gt 127
db ('&c'- 0B0h),4
else
dw '&c'
endif
else
           bslash = 0
           if '&c' eq "n"
           DW 0Dh,0Ah
           elseif '&c' eq "/"
           dw '/'
           elseif '&c' eq "r"
           dw 0Dh
           elseif '&c' eq "l"
           dw 0Ah
           elseif '&c' eq "s"
           dw 20h
           elseif '&c' eq "c"
           dw 3Bh
           elseif '&c' eq "t"
           dw 9
   endif
endif
endm
dw 0
endm
;-----------------------------------------
.code
WinMain proc
msg equ [rbp-sizeof MSG]

enter sizeof MSG+sizeof WNDCLASSEX+20h,0;90h,0
xor ebx,ebx
push 10029h ;hIconSm
lea edi,ClassName
push rdi ;lpszClassName
push rbx ;lpszMenuName
push COLOR_WINDOW;hbrBackground
push 10005h ;hCursor
push 10029h        ;hIcon
mov esi,IMAGE_BASE
push rsi ;hInstance
push rbx        ;cbClsExtra & cbWndExtra
lea eax,WndProc
push rax ;lpfnWndProc
push sizeof WNDCLASSEX;cbSize & style
mov rcx,rsp ;addr WNDCLASSEX
push rbx
push rbx
push rbx
push rbx
    call RegisterClassEx
add rsp,sizeof WNDCLASSEX+20h
        lea ecx,appMenuTemplate
call LoadMenuIndirect
push rbx
push rsi ;rsi=400000h
shl esi,9 ;rsi=CW_USEDEFAULT
push rax
push rbx
push rsi
push rsi
push rsi
push rsi
mov r9d,WS_OVERLAPPEDWINDOW or WS_VISIBLE
mov r8,rdi ;offset ClassName
mov edx,edi ;offset ClassName
xor ecx,ecx
push rbx
push rbx
push rbx
push rbx
    call CreateWindowEx
    lea edi,msg
@@:     mov ecx,edi
xor edx,edx
mov r8,rbx
mov r9,rbx
        call GetMessage
mov ecx,edi
        call DispatchMessage
        jmp @b
WinMain endp
WndProc:enter 20h,0

        cmp  edx,WM_DESTROY
        je   wmDESTROY
        cmp  edx,WM_COMMAND
        je   wmCOMMAND
        leave
        jmp DefWindowProc
wmDESTROY: xor ecx,ecx
        call ExitProcess
wmCOMMAND:cmp r8,ZZZ_EXIT
        je wmDESTROY
show_msg:mov r9,rbx;r9=MB_OK
mov rdx,menu_handlers[r8*8]
        lea r8,menu_name
        call MessageBox
wmBYE:  leave
        retn
;---------------------------------------
ClassName db 'Win64 Iczelion''s lesson #8b: Menu and template-structure',0
menu_name db 'ZZZ_Menu',0
test_msg        db      'You select menu item TEST',0
open_msg        db      'You select menu item OPEN',0
save_msg        db      'You select menu item SAVE',0
menu_handlers dq test_msg, open_msg, save_msg
align 8
appMenuTemplate dw 1 ; menu template version
dw 4 ; offset from end of this word to menu item list
dd 0 ; menu bar help ID
dd MFT_STRING,MFS_ENABLED,0
dw MFR_POPUP ; first column
du <&File>
dw 0     ; pad to align 4
dd 0        ; popup help ID
dd MFT_STRING,MFS_ENABLED,ZZZ_TEST
dw 0
du <&Test>
                dw 0     ; pad to align 4
dd MFT_STRING,MFS_ENABLED,ZZZ_OPEN
dw 0
du <&Open>
                dw 0     ; pad to align 4
dd MFT_STRING,MFS_ENABLED,ZZZ_SAVE
dw 0
du <&Save>
                dw 0     ; pad to align 4
dd MFT_SEPARATOR,0,0
dw 0,0   ; pad to align 4
dd MFT_STRING,MFS_ENABLED,ZZZ_EXIT
dw MFR_END ; bottom of column
du <&Exit>
dw 0 ; pad to align 4
dd MFT_STRING,MFS_ENABLED,ZZZ_EXIT
dw MFR_END    ; second column, last one
du <&Exit>
dw 0 ; pad to align 4
dd 0 ; popup help ID
end

Mikl__

#16
Win x64 Tutorial #8c: Program creation menu
OPTION DOTNAME
option casemap:none
include temphls.inc
include win64.inc
include kernel32.inc
includelib kernel32.lib
include user32.inc
includelib user32.lib
OPTION PROLOGUE:rbpFramePrologue
OPTION EPILOGUE:rbpFrameEpilogue
ZZZ_TEST equ 0
ZZZ_OPEN equ 1
ZZZ_SAVE equ 2
ZZZ_EXIT equ 3
IMAGE_BASE equ 400000h
;-----------------------------------------
.code
WinMain proc
msg equ [rbp-sizeof MSG]

enter sizeof MSG+sizeof WNDCLASSEX+20h,0
xor ebx,ebx
push 10029h ;hIconSm
lea edi,ClassName
push rdi ;lpszClassName
push rbx ;lpszMenuName
push COLOR_WINDOW;hbrBackground
push 10005h ;hCursor
push 10029h        ;hIcon
mov esi,IMAGE_BASE
push rsi ;hInstance
push rbx        ;cbClsExtra & cbWndExtra
lea eax,WndProc
push rax ;lpfnWndProc
push sizeof WNDCLASSEX;cbSize & style
mov rcx,rsp ;addr WNDCLASSEX
push rbx
push rbx
push rbx
push rbx
    call RegisterClassEx
add rsp,sizeof WNDCLASSEX+20h
        push rbx
push rsi ;rsi=400000h
shl esi,9 ;rsi=CW_USEDEFAULT
push rbx
push rbx
push rsi
push rsi
push rsi
push rsi
mov r9d,WS_OVERLAPPEDWINDOW or WS_VISIBLE
mov r8,rdi ;offset ClassName
mov edx,edi ;offset ClassName
xor ecx,ecx
push rbx
push rbx
push rbx
push rbx
    call CreateWindowEx
    lea edi,msg
@@:     mov ecx,edi
xor edx,edx
mov r8,rbx
mov r9,rbx
        call GetMessage
mov ecx,edi
        call DispatchMessage
        jmp @b
WinMain endp
WndProc:
hWnd equ  [rbp+10h]

enter 20h,0

        mov  hWnd,rcx
cmp  edx,WM_CREATE
je   wmCREATE
        cmp  edx,WM_DESTROY
        je   wmDESTROY
        cmp  edx,WM_COMMAND
        je   wmCOMMAND
        leave
        jmp DefWindowProc
wmDESTROY: xor ecx,ecx
        call ExitProcess
wmCREATE: call CreatePopupMenu
  mov rdi,rax
  lea r9,menu_test1
  mov r8,rbx;ZZZ_TEST
  xor edx,edx;MF_STRING
  mov rcx,rdi
  call AppendMenu
  lea r9,menu_open1
  mov r8d,ZZZ_OPEN
  xor edx,edx;MF_STRING
  mov rcx,rdi
  call AppendMenu
  lea r9,menu_save1
  mov r8d,ZZZ_SAVE
  xor edx,edx;MF_STRING
  mov rcx,rdi
  call AppendMenu
  mov r9,rbx
  mov r8,rbx
  mov edx,MF_SEPARATOR
  mov rcx,rdi
  call AppendMenu
  lea r9,menu_exit1
  mov r8d,ZZZ_EXIT
  xor edx,edx;MF_STRING
  mov rcx,rdi
  call AppendMenu
  call CreateMenu
  mov hMenu,rax
  lea r9,menu_file
  mov r8,rdi
  mov edx,MF_POPUP
  mov rcx,rax
  call AppendMenu
  lea r9,menu_exit1
  mov r8d,ZZZ_EXIT
  xor edx,edx;MF_STRING
  mov rcx,hMenu
  call AppendMenu
  mov rdx,hMenu
  mov rcx,hWnd
  call SetMenu
  jmp wmBYE
wmCOMMAND:cmp r8,ZZZ_EXIT
        je wmDESTROY
show_msg:mov r9,rbx;r9=MB_OK
mov rdx,menu_handlers[r8*8]
        lea r8,menu_name
        call MessageBox
wmBYE:  leave
        retn
;---------------------------------------
ClassName db 'Win64 Iczelion''s lesson #8c: Program creation menu',0
menu_file db 'File',0
menu_test1 db 'Test',0
menu_open1 db 'Open',0
menu_save1 db 'Save',0
menu_exit1 db 'Exit',0
menu_name db 'ZZZ_Menu',0
test_msg        db 'You select menu item TEST',0
open_msg        db 'You select menu item OPEN',0
save_msg        db 'You select menu item SAVE',0
menu_handlers dq test_msg, open_msg, save_msg
hMenu dq ?
end

Mikl__

#17
Win x64 Tutorial #8d: Creating the dynamic menu
asm-fileinclude win64a.inc

IMAGE_BASE equ 400000h
STYLBTN equ BS_DEFPUSHBUTTON+WS_VISIBLE+WS_CHILD
;-----------------------------------------
.code
WinMain proc
msg equ [rbp-sizeof MSG]

enter sizeof MSG+sizeof WNDCLASSEX+20h,0;90h,0
xor ebx,ebx
push 10029h ;hIconSm
lea edi,ClassName
push rdi ;lpszClassName
push rbx ;lpszMenuName
push COLOR_WINDOW;hbrBackground
push 10005h ;hCursor
push 10029h        ;hIcon
mov esi,IMAGE_BASE
push rsi ;hInstance
push rbx        ;cbClsExtra & cbWndExtra
lea eax,WndProc
push rax ;lpfnWndProc
push sizeof WNDCLASSEX;cbSize & style
mov rcx,rsp ;addr WNDCLASSEX
push rbx
push rbx
push rbx
push rbx
    call RegisterClassEx
add rsp,sizeof WNDCLASSEX+20h
        push rbx
push rsi ;rsi=400000h
shl esi,9 ;rsi=CW_USEDEFAULT
push rbx
push rbx
push rsi
push rsi
push rsi
push rsi
mov r9d,WS_OVERLAPPEDWINDOW or WS_VISIBLE
mov r8,rdi ;offset ClassName
mov edx,edi ;offset ClassName
xor ecx,ecx
push rbx
push rbx
push rbx
push rbx
    call CreateWindowEx
    lea edi,msg
@@:     mov ecx,edi
xor edx,edx
mov r8,rbx
mov r9,rbx
        call GetMessage
mov ecx,edi
        call DispatchMessage
        jmp @b
WinMain endp
WndProc:
hWnd equ  [rbp+10h]
wParam equ  [rbp+20h]
lParam equ  [rbp+28h]
buffer  equ  [rbp-sizeof_buffer]
MENI equ  buffer-sizeof MENUITEMINFO
sizeof_buffer = 96

enter sizeof MENUITEMINFO+sizeof_buffer+20h,0

        mov  hWnd,rcx
        mov  lParam,r9
mov  wParam,r8

  cmp  edx,WM_CREATE
  je   wmCREATE
          cmp  edx,WM_DESTROY
                  je   wmDESTROY
          cmp  edx,WM_COMMAND
          je   wmCOMMAND
          cmp edx,WM_MENUSELECT
  je wmMENUSELECT
wmDEFAULT:   leave
          jmp DefWindowProc
wmDESTROY:   xor ecx,ecx
          call ExitProcess
wmCOMMAND:   mov rax,HWNDBTN;проверить, не нажата ли кнопка
  cmp lParam,rax
  je YES_BUT
  cmp word ptr wParam,5;проверить, не выбран ли пункт меню MENUC - выход
  je wmDESTROY
  cmp word ptr wParam,4;проверить, не выбран ли пункт меню с идентификатором 5
  jne wmBYE
YES_BUT:;обработка нажатия кнопки. сначала стереть текст в заголовке
  lea r9,SPACE
  mov r8,rbx
  mov edx,WM_SETTEXT
  call SendMessage
  dec PRIZN
  jns l5
  add PRIZN,3;if (PRIZN < 0) PRIZN=2
  jmp l5
wmCREATE:   add rsp,40h
  push rbx
  push IMAGE_BASE
  push rbx
  push rcx;[hWnd]
  push 25
  push 120
  push 10
  push 10
  mov r9,STYLBTN
  lea r8,CPBUT
  mov edx,offset CLSBUTN
  xor ecx,ecx
  sub rsp,20h
  call CreateWindowEx
  mov HWNDBTN,rax;запомнить дескриптор кнопки
l5:   ;загрузить необходимое меню
  mov rdx,PRIZN
  mov ecx,IMAGE_BASE
  call LoadMenu
  mov rdx,rax
  mov rcx,hWnd
  call SetMenu;установить меню
  jmp wmBYE
wmMENUSELECT:   mov rcx,lParam
  jrcxz wmBYE;пропускаем первое сообщение при обращении к меню
  test word ptr wParam+2,MF_POPUP;проверяем, что активизировано - пункт меню или заголовок выпадающего меню
  setne al
  movzx r8,al
;если 0, то в lword wParam идентификатор пункта меню
;если 1, то в lword wParam номер заголовка выпадающего меню

;заполнение структуры для вызова функции GetMenuItemInfo
  lea r9,MENI
  mov [r9+MENUITEMINFO.cbSize],sizeof MENUITEMINFO
  mov [r9+MENUITEMINFO.fMask],MIIM_TYPE
  mov [r9+MENUITEMINFO.hSubMenu],rcx;MENI.hSubMenu:=lParam
  lea rax,buffer
  mov [r9+MENUITEMINFO.dwTypeData],rax;указатель на буфер, получающий необходимую строку
  mov [r9+MENUITEMINFO.cch],sizeof_buffer;длина буфера
  ;получить информацию о выбранном пункте меню
  movzx rdx,word ptr wParam
  call GetMenuItemInfo
;проверить результат выполнения функции
  or rax,rax;cmp eax,0
  jz wmBYE
;вывести название пункта меню как заголовок всего окна
  lea r9,MENI
  mov r9,[r9+MENUITEMINFO.dwTypeData]
  mov r8,rbx
  mov edx,WM_SETTEXT
  mov rcx,hWnd
  call SendMessage
wmBYE:  leave
        retn
;---------------------------------------
ClassName db 'Win64 Iczelion''s lesson #8d: Creating the dynamic menu',0
CPBUT   db 'Change menu',0
CLSBUTN   db 'BUTTON',0
HWNDBTN   dq 0
PRIZN   dq 2
SPACE   db 30 dup(32),0
end
rc-file#define WS_SYSMENU      0x00080000L
#define WS_MINIMIZEDBOX 0x00020000L
#define WS_MAXIMIZEDBOX 0x00010000L
#define WS_POPUP        0x80000000L
#define DS_3DLOOK       0x0004L
#define st WS_SYSMENU | WS_MINIMIZEDBOX | WS_MAXIMIZEDBOX
#define MENUC 0
#define MENUP 1
#define MENUN 2
MENUN MENU
{
  MENUITEM "",0
}
MENUP MENU
{             
POPUP "First point"
{
MENUITEM "First",1
MENUITEM "Second",2
}
POPUP "Second point"
{
  MENUITEM "Third",3
  MENUITEM "Fourth",4
  MENUITEM SEPARATOR
  POPUP "Else submenu"
  {
    MENUITEM "Additional point",6
  }
  MENUITEM "Exit",5
}
}
MENUC MENU
{             
POPUP "First set"
{
MENUITEM "White",101
MENUITEM "Grey",102
MENUITEM "Black",103
}
POPUP "Second set"
{
  MENUITEM "Red",104
  MENUITEM "Blue",105
  MENUITEM "Green",106
}
}

Mikl__

#18
Win x64 Tutorial #8e: Creating a floating menu
include win64a.inc

IMAGE_BASE equ 400000h
ZZZ_TEST equ 0
ZZZ_OPEN equ 1
ZZZ_SAVE equ 2
ZZZ_EXIT equ 3
;-----------------------------------------
.code
WinMain proc

enter sizeof WNDCLASSEX+20h,0
xor ebx,ebx
push 10029h ;hIconSm
lea edi,ClassName
push rdi ;lpszClassName
push rbx ;lpszMenuName
push COLOR_WINDOW;hbrBackground
push 10005h ;hCursor
push 10029h        ;hIcon
mov esi,IMAGE_BASE
push rsi ;hInstance
push rbx        ;cbClsExtra & cbWndExtra
lea eax,WndProc
push rax ;lpfnWndProc
push sizeof WNDCLASSEX;cbSize & style
mov rcx,rsp ;addr WNDCLASSEX
push rbx
push rbx
push rbx
push rbx
    call RegisterClassEx
add rsp,sizeof WNDCLASSEX+20h
        push rbx
push rsi ;rsi=400000h
shl esi,9 ;rsi=CW_USEDEFAULT
push rbx
push rbx
push rsi
push rsi
push rsi
push rsi
mov r9d,WS_OVERLAPPEDWINDOW or WS_VISIBLE
mov r8,rdi ;offset ClassName
mov edx,edi ;offset ClassName
xor ecx,ecx
push rbx
push rbx
push rbx
push rbx
    call CreateWindowEx
    mov edi,offset msg
@@:     mov ecx,edi
xor edx,edx
mov r8,rbx
mov r9,rbx
        call GetMessage
mov ecx,edi
        call DispatchMessage
        jmp @b
WinMain endp
WndProc:
hWnd equ  [rbp+10h]
rect    equ  [rbp-18h]
hMenu  equ  [rbp-20h]
enter sizeof RECT+8+40h+8,0

        mov  hWnd,rcx

  cmp  edx,WM_DESTROY
                  je   wmDESTROY
          cmp  edx,WM_COMMAND
          je   wmCOMMAND
          cmp  edx,WM_RBUTTONDOWN
          je   wmRBUTTONDOWN
wmDEFAULT:   leave
          jmp DefWindowProc
wmDESTROY:   xor ecx,ecx
          call ExitProcess
wmRBUTTONDOWN: call CreatePopupMenu
mov edi,eax;hPopupMenu,eax
call CreateMenu
mov hMenu,rax;hMenu=rbp-20h
mov r9d,offset menu_test1
mov r8,rbx;ZZZ_TEST
xor edx,edx;MF_STRING
mov ecx,edi
call AppendMenu
mov r9d,offset menu_open1
mov r8d,ZZZ_OPEN
xor edx,edx;MF_STRING
mov ecx,edi
call AppendMenu
mov r9d,offset menu_save1
mov r8d,ZZZ_SAVE
xor edx,edx;MF_STRING
mov ecx,edi
call AppendMenu
mov r9,rbx
mov r8,rbx
mov edx,MF_SEPARATOR
mov ecx,edi
call AppendMenu
mov r9d,offset menu_exit1
mov r8d,ZZZ_EXIT
xor edx,edx;MF_STRING
mov ecx,edi
call AppendMenu
mov r9d,offset menu_file
mov r8,rdi
mov edx,MF_POPUP
mov rcx,hMenu
call AppendMenu
mov r9d,offset menu_exit1
mov r8d,ZZZ_EXIT
xor edx,edx;MF_STRING
mov rcx,hMenu
call AppendMenu
mov ecx,edi
xor edx,edx;mov edx,TPM_LEFTALIGN+TPM_LEFTBUTTON
mov r8d,msg.pt.x
mov r9d,msg.pt.y
mov [rsp+30h],rbx
mov rax,hWnd
mov [rsp+28h],rax
mov [rsp+20h],rbx
call TrackPopupMenu
lea rdx,rect;rect=rbp-18h
mov rcx,hWnd
call GetWindowRect
jmp wmBYE
wmCOMMAND:   cmp r8,ZZZ_EXIT
       je   wmDESTROY
show_msg:      mov r9,rbx;r9=MB_OK
       mov rdx,[menu_handlers+r8*8]
       mov r8d,offset menu_name
       call MessageBox
wmBYE:  leave
        retn
;---------------------------------------
ClassName db 'Win64 Iczelion''s lesson #8e: Creating a floating menu',0
menu_file db 'File',0
menu_test1 db 'Test',0
menu_open1 db 'Open',0
menu_save1 db 'Save',0
menu_exit1 db 'Exit',0
menu_name db 'ZZZ_Menu',0
test_msg db 'You select menu item TEST',0
open_msg db 'You select menu item OPEN',0
save_msg db 'You select menu item SAVE',0
menu_handlers dq test_msg, open_msg, save_msg
msg MSG <>
end

Mikl__

#19
Win x64 Tutorial #8g: Using the accelerator table
asm-fileOPTION DOTNAME
option casemap:none
include temphls.inc
include win64.inc
include kernel32.inc
includelib kernel32.lib
include user32.inc
includelib user32.lib
OPTION PROLOGUE:rbpFramePrologue
OPTION EPILOGUE:rbpFrameEpilogue
IMAGE_BASE      equ 400000h
ZZZ_TEST equ 0
ZZZ_OPEN equ 1
ZZZ_SAVE equ 2
ZZZ_EXIT equ 3
IDM_MENU      equ 37
IDR_MAINACCEL equ 105

.code
WinMain proc
msg equ [rbp-sizeof MSG]

enter sizeof MSG+sizeof WNDCLASSEX+20h,0;90h,0
xor ebx,ebx
push 10029h ;hIconSm
lea rdi,ClassName
push rdi ;lpszClassName
push IDM_MENU ;lpszMenuName
push COLOR_WINDOW;hbrBackground
push 10005h ;hCursor
push 10029h        ;hIcon
mov esi,IMAGE_BASE
push rsi ;hInstance
push rbx        ;cbClsExtra & cbWndExtra
lea rax,WndProc
push rax ;lpfnWndProc
push sizeof WNDCLASSEX;cbSize & style
mov rcx,rsp ;addr WNDCLASSEX
push rbx
push rbx
push rbx
push rbx
    call RegisterClassEx
add rsp,sizeof WNDCLASSEX+20h
push rbx
push rsi ;rsi=400000h
shl esi,9 ;rsi=CW_USEDEFAULT
push rbx
push rbx
push rsi
push rsi
push rsi
push rsi
mov r9d,WS_OVERLAPPEDWINDOW or WS_VISIBLE
mov r8,rdi ;offset ClassName
mov edx,edi ;offset ClassName
xor ecx,ecx
push rbx
push rbx
push rbx
push rbx
    call CreateWindowEx
        mov hwnd,rax
mov ecx,IMAGE_BASE
mov edx,IDR_MAINACCEL
call LoadAccelerators
mov ACC,rax
    lea edi,msg
@@:     mov ecx,edi
xor edx,edx
mov r8,rbx
mov r9,rbx
        call GetMessage
mov ecx,edi
        call DispatchMessage
mov r8d,edi
mov rdx,ACC
mov rcx,hwnd
call TranslateAccelerator
or eax,eax
jne @b
mov ecx,edi
call TranslateMessage
        jmp @b
WinMain endp
WndProc:
        enter 20h,0

        cmp  edx,WM_DESTROY
        je   wmDESTROY
        cmp  edx,WM_COMMAND
        je   wmCOMMAND
        leave
        jmp DefWindowProc
wmDESTROY: xor ecx,ecx
        call ExitProcess
wmCOMMAND:and r8,11y
cmp r8,ZZZ_EXIT
        je wmDESTROY
show_msg:mov r9,rbx;r9=MB_OK
mov rdx,menu_handlers[r8*8]
        mov r8d,offset menu_name
        call MessageBox
wmBYE:  leave
        retn
;---------------------------------------
ClassName db 'Win64 Iczelion''s lesson #8g: Using the accelerator table',0
menu_name db 'ZZZ_Menu',0
test_msg        db 'You select menu item TEST',0
open_msg        db 'You select menu item OPEN',0
save_msg        db 'You select menu item SAVE',0
menu_handlers dq test_msg, open_msg, save_msg
ACC dq ?
hwnd dq ?
end
rc-file#define ZZZ_TEST 0
#define ZZZ_OPEN 1
#define ZZZ_SAVE 2
#define ZZZ_EXIT 3
#define IDM_MENU 37
#define IDR_MAINACCEL 105

IDM_MENU MENU
{
POPUP "&File"
{       MENUITEM "&Test\tCtrl+T",ZZZ_TEST
MENUITEM "&Open\tCtrl+O",ZZZ_OPEN
MENUITEM "&Save\tCtrl+S",ZZZ_SAVE
MENUITEM SEPARATOR
MENUITEM "&Exit\tCtrl+X",ZZZ_EXIT
}
MENUITEM "&Exit",ZZZ_EXIT
}
IDR_MAINACCEL ACCELERATORS DISCARDABLE
{
"^T",ZZZ_TEST
"^O",ZZZ_OPEN
"^S",ZZZ_SAVE
"^X",ZZZ_EXIT
}

Mikl__

Win64 Tutorial #8h:  toolbar
OPTION DOTNAME
option casemap:none
include temphls.inc
include win64.inc
include kernel32.inc
includelib kernel32.lib
include user32.inc
includelib user32.lib
include gdi32.inc
includelib gdi32.lib
include comctl32.inc
includelib comctl32.lib
OPTION PROLOGUE:rbpFramePrologue
OPTION EPILOGUE:rbpFrameEpilogue
IMAGE_BASE      equ 400000h
ID_1 equ 0
ID_2 equ 1
ID_3 equ 2


.code
WinMain proc
msg equ [rbp-sizeof MSG]

enter sizeof MSG+sizeof WNDCLASSEX+70h,0
xor ebx,ebx
add rsp,sizeof WNDCLASSEX+20h
push 10029h ;hIconSm
mov edi,offset ClassName
push rdi ;lpszClassName
push rbx ;lpszMenuName
push COLOR_WINDOW;hbrBackground
push 10005h ;hCursor
push 10029h        ;hIcon
mov esi,IMAGE_BASE
push rsi ;hInstance
push rbx        ;cbClsExtra & cbWndExtra
mov eax,offset WndProc
push rax ;lpfnWndProc
push sizeof WNDCLASSEX;cbSize & style
mov rcx,rsp ;addr WNDCLASSEX
push rbx
push rbx
push rbx
push rbx
    call RegisterClassEx
add rsp,sizeof WNDCLASSEX+20h
push rbx
push rsi ;rsi=400000h
shl esi,9 ;rsi=CW_USEDEFAULT
push rbx
push rbx
push rsi
push rsi
push rsi
push rsi
mov r9d,WS_OVERLAPPEDWINDOW or WS_VISIBLE
mov r8,rdi ;offset ClassName
mov edx,edi ;offset ClassName
xor ecx,ecx
push rbx
push rbx
push rbx
push rbx
    call CreateWindowEx
        mov rdi,rax
mov qword ptr [rsp+28h],LR_LOADFROMFILE
mov [rsp+20h],rbx
mov r9,rbx
mov r8,rbx
mov edx,offset aMybp1
mov ecx,IMAGE_BASE
call LoadImage
mov edx,sizeof TBBUTTON
mov bl,2
lea rcx,[tbb+edx*2]
@@: mov [rcx+TBBUTTON.iBitmap],ebx
mov [rcx+TBBUTTON.idCommand],ebx;ID_1 ID_2 ID_3
mov [rcx+TBBUTTON.fsState],TBSTATE_ENABLED
or ebx,ebx
jz @f
sub ecx,edx
dec ebx
jmp @b
@@: mov [rsp+60h],rdx;size of structure TBBUTTON
mov edx,18
mov [rsp+58h],rdx;width an higth
mov [rsp+50h],rdx;изображения на каждой кнопке
mov [rsp+48h],rdx;width an higth
mov [rsp+40h],rdx;каждой кнопки
mov qword ptr [rsp+38h],3;число кнопок
mov [rsp+30h],rcx;адрес массива структуры типа TBBUTTON
mov [rsp+28h],rax;идентификатор ресурса с изображением кнопок
mov [rsp+20h],rbx;0
mov r9d,3    ;число изображений кнопок в файле bmp
or r8,-1;идентификатор всей инструментальной панели, который в программе не используется и может быть равен -1
mov edx,WS_CHILD+WS_BORDER+WS_VISIBLE;+TBSTYLE_TOOLTIPS;стиль инструментальной панели
mov ecx,edi;дескриптор главного окна
call CreateToolbarEx
mov ecx,0FF0000h;blue=0FF0000h
call CreateSolidBrush
mov BlueBrush,eax;hBlueBrush
mov ecx,0FF00h;green=0FF00h
call CreateSolidBrush
mov GreenBrush,eax
    lea edi,msg
@@:     mov ecx,edi
xor edx,edx
mov r8,rbx
mov r9,rbx
        call GetMessage
mov ecx,edi
        call DispatchMessage
jmp @b
WinMain endp
WndProc:
hWnd equ [rbp+10h]
wParam equ [rbp+20h]
lParam equ [rbp+28h]
ps equ [rbp-sizeof PAINTSTRUCT]


      enter sizeof PAINTSTRUCT+20h,0

      mov  hWnd,rcx
      mov  wParam,r8
      mov  lParam,r9

      cmp  edx,WM_DESTROY
      je   wmDESTROY
      cmp  edx,WM_PAINT
      je   wmPAINT
      cmp  edx,WM_SIZE
      je   wmSIZE
      cmp  edx,WM_COMMAND
      je wmCOMMAND
      leave
      jmp DefWindowProc
wmDESTROY:    xor ecx,ecx
      call ExitProcess
wmPAINT:      lea edx,ps
      call BeginPaint
      mov ecx,sw
      jecxz @f
      mov r8d,[BlueBrush+ecx*4-4]
      mov rcx,rax
      lea rdx,ps.PAINTSTRUCT.rcPaint
      mov eax,ps.PAINTSTRUCT.rcPaint.right
      xchg eax,ps.PAINTSTRUCT.rcPaint.top
              mov ps.PAINTSTRUCT.rcPaint.right,eax
      call FillRect
@@:       lea edx,ps
      mov rcx,hWnd
      call EndPaint
      jmp wmBYE
wmCOMMAND:    mov eax,wParam;depending on the value of wParam
;or close the window (wParam=2), or change the color of window (wParam=0 or =1)
      jmp [handler+eax*8]
;if wParam=0 or wParam=1 send message WM_PAINT
@0:       inc eax
      mov [sw],eax                   
wmSIZE:       xor edx,edx
      mov r8d,1
      mov rcx,hWnd
      call InvalidateRect
wmBYE:        leave
              retn
handler dq    @0,@0,wmDESTROY
;---------------------------------------
ClassName db 'Win64 Iczelion''s lesson #8h: toolbar',0
BlueBrush dd ?
GreenBrush dd ?
sw dd 0
tbb TBBUTTON 3 dup(<0>)
aMybp1 db "Images\btns.bmp",0
end

Mikl__

#21
Win64 Tutorial #8h:  toolbar and tooltips
include win64a.inc
include gdi32.inc
includelib gdi32.lib

IMAGE_BASE      equ 400000h

ID_1 equ 0
ID_2 equ 1
ID_3 equ 2



.code
WinMain proc
msg equ [rbp-sizeof MSG]

enter sizeof MSG+sizeof WNDCLASSEX+70h,0
xor ebx,ebx
push 10029h ;hIconSm
mov edi,offset ClassName
push rdi ;lpszClassName
push rbx ;lpszMenuName
push COLOR_WINDOW+1;hbrBackground
push 10005h ;hCursor
push 10029h        ;hIcon
mov esi,IMAGE_BASE
push rsi ;hInstance
push rbx        ;cbClsExtra & cbWndExtra
mov eax,offset WndProc
push rax ;lpfnWndProc
push sizeof WNDCLASSEX;cbSize & style
mov rcx,rsp ;addr WNDCLASSEX
push rbx
push rbx
push rbx
push rbx
    call RegisterClassEx
add rsp,sizeof WNDCLASSEX+20h
push rbx
push rsi ;rsi=400000h
shl esi,9 ;rsi=CW_USEDEFAULT
push rbx
push rbx
push rsi
push rsi
push rsi
push rsi
mov r9d,WS_OVERLAPPEDWINDOW or WS_VISIBLE
mov r8,rdi ;offset ClassName
mov edx,edi ;offset ClassName
xor ecx,ecx
push rbx
push rbx
push rbx
push rbx
    call CreateWindowEx
        mov rdi,rax
mov qword ptr [rsp+28h],LR_LOADFROMFILE
mov [rsp+20h],rbx
mov r9,rbx
mov r8,rbx
mov edx,offset aMybp1
mov ecx,IMAGE_BASE
call LoadImage
mov edx,sizeof TBBUTTON
mov bl,2
lea rcx,[tbb+edx*2]
@@: mov [rcx+TBBUTTON.iBitmap],ebx;порядковый номер кнопки (кнопки нумеруются от 0)
mov [rcx+TBBUTTON.idCommand],ebx;ID_1 ID_2 ID_3 идентификатор кнопки
mov [rcx+TBBUTTON.fsState],TBSTATE_ENABLED;состояние кнопки.
;Значение TBSTATE_ENABLED разрешает управление с пмощью данной кнопки
or ebx,ebx;заполняем массив с ebx как индекс в массиве от 2 до 0
jz @f
sub ecx,edx;переходим к следующей структуре TBBUTTON
dec ebx
jmp @b
@@: mov [rsp+60h],rdx;size TBBUTTON  ;size of structure TBBUTTON
mov edx,18
mov [rsp+58h],rdx;width an higth
mov [rsp+50h],rdx;изображения на каждой кнопке
mov [rsp+48h],rdx;width an higth
mov [rsp+40h],rdx;каждой кнопки
mov qword ptr [rsp+38h],3;число кнопок
mov [rsp+30h],rcx;адрес массива структуры типа TBBUTTON
mov [rsp+28h],rax;идентификатор ресурса с изображением кнопок
mov [rsp+20h],rbx;0
mov r9d,3    ;число изображений кнопок в файле bmp
or r8,-1;идентификатор всей инструментальной панели, который в программе не используется и может быть равен -1
mov edx,WS_CHILD or WS_BORDER or WS_VISIBLE or TBSTYLE_TOOLTIPS;стиль инструментальной панели
mov ecx,edi;дескриптор главного окна
call CreateToolbarEx
mov ecx,0FF0000h;blue=FF0000h
call CreateSolidBrush
mov BlueBrush,eax;hBlueBrush
mov ecx,000FF00h;green=00FF00h
call CreateSolidBrush
mov GreenBrush,eax
    lea edi,msg
@@:     mov ecx,edi
xor edx,edx
mov r8,rbx
mov r9,rbx
        call GetMessage
mov ecx,edi
        call DispatchMessage
jmp @b
WinMain endp
WndProc:
hWnd equ [rbp+10h]
wParam equ [rbp+20h]
lParam equ [rbp+28h]
ps equ [rbp-sizeof PAINTSTRUCT]
lpttt equ ps-8


      enter sizeof PAINTSTRUCT+20h+8,0

      mov  hWnd,rcx
      mov  wParam,r8
      mov  lParam,r9

      cmp  edx,WM_DESTROY
      je   wmDESTROY
      cmp  edx,WM_PAINT
      je   wmPAINT
      cmp  edx,WM_SIZE
      je   wmSIZE
      cmp  edx,WM_COMMAND
      je   wmCOMMAND
              cmp  edx,WM_NOTIFY
      je   wmNOTIFY
      leave
      jmp DefWindowProc
wmDESTROY:    xor ecx,ecx
      call ExitProcess
wmPAINT:      lea edx,ps     
      call BeginPaint
      mov ecx,sw     
      ;or ecx,ecx
      jecxz @f;в sw при старте программы ноль, если sw=0
;тогда не нужно изменять цвет окна
;заполняем окно выбранной кистью из массива кистей
      mov r8d,[BlueBrush+ecx*4-4]
      mov rcx,rax
      lea edx,ps.PAINTSTRUCT.rcPaint
              mov eax,ps.PAINTSTRUCT.rcPaint.right
      xchg eax,ps.PAINTSTRUCT.rcPaint.top
              mov ps.PAINTSTRUCT.rcPaint.right,eax
      call FillRect
@@:       lea edx,ps 
      mov rcx,hWnd
      call EndPaint
      jmp wmBYE
wmNOTIFY: ;r9=[lParam]   ;if( LPNMHDR(lParam)->code ==TTN_NEEDTEXT)
cmp dword ptr [r9+NMHDR._code],TTN_NEEDTEXT
jnz wmBYE
mov lpttt,r9   ;LPTOOLTIPTEXT lpttt = (LPTOOLTIPTEXT) lParam;
mov eax,dword ptr [r9+NMHDR.idFrom];switch (lpttt->hdr.idFrom) {
cmp eax,ID_3       ;case ID_1:strcpy(lpttt->szText,"Fill blue");break;
ja wmBYE ;case ID_2:strcpy(lpttt->szText,"Fill green");break;
;case ID_3:strcpy(lpttt->szText,"Exit");
lea ecx,[r9+TOOLTIPTEXT.szText]
mov rdx,[pt+eax*8]
call lstrcpy
jmp wmBYE
wmCOMMAND:    mov eax,wParam;depending on the value of wParam
;or close the window (wParam=2), or change the color of window (wParam=0 or =1)                 
      jmp [handler+eax*8]
;if wParam=0 or wParam=1 send message WM_PAINT               
@0:       inc eax
      mov [sw],eax                     
wmSIZE:       mov r8d,TRUE
      xor edx,edx
      mov rcx,hWnd
      call InvalidateRect
wmBYE:        leave
              retn
handler dq    @0,@0,wmDESTROY
;---------------------------------------
ClassName db 'Win64 Iczelion''s lesson #8i: toolbar and tooltips',0
tbb TBBUTTON 3 dup(<0>)
szText1 db 'Fill blue',0
szText2 db 'Fill green',0
szText3 db 'Exit',0
pt dq szText1,szText2,szText3
aMybp1 db "Images\btns.bmp",0
sw dd 0
BlueBrush dd ?
GreenBrush dd ?
end

jj2007

Great job, Mikl :t

No user-friendly local variables yet?
mov qword ptr [rsp+28h],LR_LOADFROMFILE
mov [rsp+20h],rbx

Mikl__

Hi, jj2007!
Quotemov qword ptr [rsp+28h],LR_LOADFROMFILE
   mov [rsp+20h],rbx
   mov r9,rbx
   mov r8,rbx
   mov edx,offset aMybp1
   mov ecx,IMAGE_BASE
   call LoadImage <--
This is not a local variables, this is parameters of procedure LoadImage
see the article of Matt Pietrek Everything You Need To Know To Start Programming 64-Bit Windows Systems

Gunther

Hi Mikl__,

Quote from: Mikl__ on May 06, 2015, 04:36:47 PM
This is not a local variables, this is parameters of procedure LoadImage
see the article of Matt Pietrek Everything You Need To Know To Start Programming 64-Bit Windows Systems

great article, by the way. No wonder, it's Matt Pietrek.

Gunther
You have to know the facts before you can distort them.

sinsi

To be truly 64-bit you shouldn't hard code the base address else things like ASLR won't work.
Also, using 'lea reg,var'  instead of 'mov reg,offset var' will use rip-relative addressing (at least in ml64).

    sub ecx,ecx
    call GetModuleHandle
    mov hinst,rax
...
    lea rdx,aMybp1    ;mov edx,offset aMybp1
    mov rcx,hinst     ;mov ecx,IMAGE_BASE
    call LoadImage
🍺🍺🍺

jj2007

Quote from: Mikl__ on May 06, 2015, 04:36:47 PM
   mov qword ptr [rsp+28h],LR_LOADFROMFILE
   mov [rsp+20h],rbx
   mov r9,rbx
   mov r8,rbx
   mov edx,offset aMybp1
   mov ecx,IMAGE_BASE
   call LoadImage <--

This is not a local variables, this is parameters of procedure LoadImage

Oops, sorry 8)
Reminds me of the early days of x86 assembly, see \Masm32\examples\exampl07\slickhuh\slickhuh.asm  :bgrin:

Mikl__

Hi, sinsi!
I write in bat-file
Quote...
/LARGEADDRESSAWARE:NO
...
/BASE:0x400000
so the lines
Quotesub ecx,ecx
    call GetModuleHandle
    mov hinst,rax
is not needed in my examples, hinst always is 400000h, and mov edx,offset var == lea rdx,var

Mikl__

jj2007,
I never pay attention \Masm32\examples\exampl07\slickhuh\slickhuh.asm but the example is quite interesting, why I had not noticed it before? though in \Masm32\examples\exampl07\slickhuh\readme.txt is
QuoteIt uses the EXTERNDEF form of prototype for API functions but makes no use of the parameter data after it, Windows equates occur in their bare number form to ensure they are unintelligible and the API function addresses are called from a meaningless name equated to their address.
To make the code even less readable in a disassembly the parameters for some of the  API call are forwarded on the stack and do not occur in the simple order prior to the function call.
the program work and it is most importantly, and a style of writing programs can be any... Assembly language programming is creativity!

Mikl__

Win64 Tutorial #9: Child Window Controls
OPTION DOTNAME
option casemap:none
include temphls.inc
include win64.inc
include kernel32.inc
includelib kernel32.lib
include user32.inc
includelib user32.lib
OPTION PROLOGUE:rbpFramePrologue
OPTION EPILOGUE:rbpFrameEpilogue
IMAGE_BASE equ 400000h
ButtonID equ 1
EditID equ 2
IDM_HELLO equ 0
IDM_CLEAR equ 1
IDM_GETTEXT equ 2
IDM_EXIT equ 3
.code
WinMain proc
msg equ [rbp-sizeof MSG]

enter sizeof MSG+sizeof WNDCLASSEX+20h,0
xor ebx,ebx
push 10029h ;hIconSm
mov edi,offset ClassName
push rdi ;lpszClassName
mov eax,offset MenuName
push rax ;lpszMenuName
push COLOR_BTNFACE+1;hbrBackground
push 10005h ;hCursor
push 10029h        ;hIcon
mov esi,IMAGE_BASE
push rsi ;hInstance
push rbx        ;cbClsExtra & cbWndExtra
mov eax,offset WndProc
push rax ;lpfnWndProc
push sizeof WNDCLASSEX;cbSize & style
mov rcx,rsp ;addr WNDCLASSEX
push rbx
push rbx
push rbx
push rbx
    call RegisterClassEx
push rbx
push rsi ;rsi=400000h
shl esi,9 ;rsi=CW_USEDEFAULT
push rbx
push rbx
push 200
push 485
push rsi
push rsi
mov r9d,WS_OVERLAPPEDWINDOW or WS_VISIBLE
mov r8,rdi ;offset ClassName
mov edx,edi ;offset ClassName
mov ecx,WS_EX_CLIENTEDGE
push rbx
push rbx
push rbx
push rbx
    call CreateWindowEx
mov edi,eax
        push rbx
push IMAGE_BASE
push EditID
push rdi
push 25
push 200
push 35
push 50
mov r9d,WS_CHILD or WS_VISIBLE or WS_BORDER or ES_LEFT or ES_AUTOHSCROLL
mov r8,rbx
mov edx,offset EditClassName
mov ecx,WS_EX_CLIENTEDGE
push rbx
push rbx
push rbx
push rbx
    call CreateWindowEx
        mov hwndEdit,rax
mov ecx,eax
        call SetFocus
        push rbx
push IMAGE_BASE
push ButtonID
push rdi
push 25
push 140
push 70
push 70
mov r9d,WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON
mov r8d,offset ButtonText
mov edx,offset ButtonClassName
xor ecx,ecx
push rbx
push rbx
push rbx
push rbx
    call CreateWindowEx
    lea edi,msg
@@:     mov ecx,edi
xor edx,edx
mov r8,rbx
mov r9,rbx
        call GetMessage
mov ecx,edi
        call TranslateMessage
mov ecx,edi
        call DispatchMessage
        jmp @b
WinMain endp
WndProc:
hWnd equ [rbp+10h]
wParam equ [rbp+20h]
lParam equ [rbp+28h]
buffer         equ [rbp-96]

enter 96+20h,0

mov  lParam,r9
mov  wParam,r8

cmp edx,WM_DESTROY
je wmDESTROY
cmp edx,WM_COMMAND
je wmCOMMAND
leave
        jmp DefWindowProc
wmDESTROY: xor ecx,ecx
        call ExitProcess
wmCOMMAND:movzx eax,word ptr wParam
cmp lParam,rbx;0
jnz @f
mov rsi,hwndEdit
jmp [menu_handlers+eax*8]
@@: dec eax ;cmp ax,ButtonID where ButtonID=1
jne wmBYE
mov r9,rbx
mov r8d,IDM_GETTEXT
mov edx,WM_COMMAND
jmp @f
HELLO: mov edx,offset TestString
mov ecx,esi ;hwndEdit
call SetWindowText
mov r9,rbx
mov r8d,VK_END
mov edx,WM_KEYDOWN
mov ecx,esi ;hwndEdit
@@: call SendMessage
jmp wmBYE
CLEAR: xor edx,edx
mov ecx,esi ;hwndEdit
call SetWindowText
jmp wmBYE
GETTEXT: lea edx,buffer
mov r8d,92
mov ecx,esi
call GetWindowText
mov r9,rbx
mov r8d,offset MenuName
        lea edx,buffer
xor ecx,ecx
call MessageBox
wmBYE: leave
retn
;---------------------------------------
ClassName db 'Win64 Iczelion lesson #9: Create a button and editing window',0
MenuName db "FirstMenu",0
ButtonClassName db "button",0
ButtonText db "Get Text",0
EditClassName db "edit",0
TestString db "Wow! I'm in an edit box now",0
hwndEdit dq ?
menu_handlers dq HELLO, CLEAR, GETTEXT, wmDESTROY
end