kolibrios-fun/programs/fs/kfar/trunk/dialogs.inc

1742 lines
46 KiB
PHP
Raw Normal View History

; int __stdcall GenericBox(DLGTEMPLATE* dlg, void* DlgProc);
; int __stdcall DlgProc(DLGTEMPLATE* dlg, int msg, int param1, int param2);
virtual at 0
dlgtemplate:
; <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:
; <EFBFBD><EFBFBD><EFBFBD> 0: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; <EFBFBD><EFBFBD><EFBFBD> 1: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<EFBFBD><EFBFBD><EFBFBD>
; (<EFBFBD> <EFBFBD><EFBFBD> <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD> main_color,border_color,header_color
; <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
; <EFBFBD><EFBFBD><EFBFBD> 2: <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD>
.flags dd ?
.x dd ?
.y dd ?
.width dd ?
.height dd ?
.border_size_x dd ?
.border_size_y dd ?
.title dd ?
.main_color db ?
.border_color db ?
.header_color db ?
db ? ; align
.dataptr dd ? ; used internally, ignored on input
.size = $
end virtual
GenericBox:
push [cursor_x]
push [cursor_y]
push dword [esp+8+8]
push dword [esp+8+8]
call ShowGenericBox
test eax, eax
jz @f
pop [cursor_y]
pop [cursor_x]
ret
@@:
pushad
; message loop
.event:
push 10
pop eax
int 40h
dec eax
jz .redraw
dec eax
jz .key
jmp exit
.redraw:
call draw_window
jmp .event
.key:
mov al, 2
int 40h
shr eax, 8
cmp al, 0xE0
jnz @f
mov [bWasE0], 1
jmp .event
@@:
xchg ah, [bWasE0]
cmp al, 0x1D
jz .ctrl_down
cmp al, 0x9D
jz .ctrl_up
cmp al, 0x2A
jz .lshift_down
cmp al, 0xAA
jz .lshift_up
cmp al, 0x36
jz .rshift_down
cmp al, 0xB6
jz .rshift_up
cmp al, 0x38
jz .alt_down
cmp al, 0xB8
jz .alt_up
mov ebx, [esp+24h+8]
mov ecx, [esp+28h+8]
push 0
push eax
push 2
push ebx
call ecx
test eax, eax
jz .event
mov [esp+28], eax
jmp .exit
.ctrl_down:
test ah, ah
jnz .rctrl_down
or [ctrlstate], 4
jmp .event
.rctrl_down:
or [ctrlstate], 8
jmp .event
.ctrl_up:
test ah, ah
jnz .rctrl_up
and [ctrlstate], not 4
jmp .event
.rctrl_up:
and [ctrlstate], not 8
jmp .event
.lshift_down:
test ah, ah
jnz @f
or [ctrlstate], 1
@@: jmp .event
.lshift_up:
test ah, ah
jnz @b
and [ctrlstate], not 1
jmp @b
.rshift_down:
or [ctrlstate], 2
jmp .event
.rshift_up:
and [ctrlstate], not 2
jmp .event
.alt_down:
test ah, ah
jnz .ralt_down
or [ctrlstate], 0x10
jmp .event
.ralt_down:
or [ctrlstate], 0x20
jmp .event
.alt_up:
test ah, ah
jnz .ralt_up
and [ctrlstate], not 0x10
jmp .event
.ralt_up:
and [ctrlstate], not 0x20
jmp .event
.exit:
popad
push eax
push 0
push dword [esp+12+8]
call HideGenericBox
pop eax
pop [cursor_y]
pop [cursor_x]
pushad
call draw_image
popad
ret 8
; int __stdcall ShowGenericBox(DLGTEMPLATE* dlg, void* DlgProc);
ShowGenericBox:
pushad
mov ebx, [esp+20h+4]
; center window if required
push [ebx+dlgtemplate.x]
push [ebx+dlgtemplate.y]
cmp [ebx+dlgtemplate.x], -1
jnz @f
mov eax, [cur_width]
sub eax, [ebx+dlgtemplate.width]
shr eax, 1
mov [ebx+dlgtemplate.x], eax
@@:
cmp [ebx+dlgtemplate.y], -1
jnz @f
mov eax, [cur_height]
sub eax, [ebx+dlgtemplate.height]
shr eax, 1
mov [ebx+dlgtemplate.y], eax
@@:
; some checks
mov eax, [ebx+dlgtemplate.x]
cmp eax, 1
jl .sizeerr
add eax, [ebx+dlgtemplate.width]
cmp eax, [cur_width]
jge .sizeerr
mov eax, [ebx+dlgtemplate.y]
cmp eax, 1
jl .sizeerr
add eax, [ebx+dlgtemplate.height]
cmp eax, [cur_height]
jge .sizeerr
cmp [ebx+dlgtemplate.border_size_x], 1
jl .sizeerr
cmp [ebx+dlgtemplate.border_size_y], 1
jge .sizeok
.sizeerr:
pop [ebx+dlgtemplate.y]
pop [ebx+dlgtemplate.x]
popad
or eax, -1
ret 8
.sizeok:
; set color if required
test byte [ebx+dlgtemplate.flags], 1
jz @f
mov edi, dialog_colors
jmp .setcolor
@@:
test byte [ebx+dlgtemplate.flags], 2
jz @f
mov edi, warning_colors
.setcolor:
mov al, [edi + dialog_main_color-dialog_colors]
mov [ebx+dlgtemplate.main_color], al
mov al, [edi + dialog_border_color-dialog_colors]
mov [ebx+dlgtemplate.border_color], al
mov al, [edi + dialog_header_color-dialog_colors]
mov [ebx+dlgtemplate.header_color], al
@@:
; allocate memory for data under dialog
; for 'No memory' dialog use static data area
mov eax, nomem_dlgsavearea
cmp ebx, nomem_dlgdata
jz .allocated
mov eax, [ebx+dlgtemplate.width]
add eax, [ebx+dlgtemplate.border_size_x]
add eax, [ebx+dlgtemplate.border_size_x]
inc eax
inc eax
mov edx, [ebx+dlgtemplate.height]
add edx, [ebx+dlgtemplate.border_size_y]
add edx, [ebx+dlgtemplate.border_size_y]
inc edx
mul edx
lea ecx, [eax*2+8]
call xpgalloc
test eax, eax
jnz @f
pop [ebx+dlgtemplate.y]
pop [ebx+dlgtemplate.x]
popad
or eax, -1
ret 8
@@:
.allocated:
mov [ebx+dlgtemplate.dataptr], eax
pop dword [eax+4]
pop dword [eax]
lea ebp, [eax+8]
; save data
mov eax, [ebx+dlgtemplate.y]
add eax, [ebx+dlgtemplate.height]
add eax, [ebx+dlgtemplate.border_size_y]
inc eax
push eax
mov eax, [ebx+dlgtemplate.x]
add eax, [ebx+dlgtemplate.width]
add eax, [ebx+dlgtemplate.border_size_x]
inc eax
inc eax
push eax
mov eax, [ebx+dlgtemplate.y]
sub eax, [ebx+dlgtemplate.border_size_y]
push eax
mov eax, [ebx+dlgtemplate.x]
sub eax, [ebx+dlgtemplate.border_size_x]
push eax
call save_console_data
; draw shadow
test byte [ebx+dlgtemplate.flags], 4
jnz .noshadow
mov eax, [ebx+dlgtemplate.x]
sub eax, [ebx+dlgtemplate.border_size_x]
ja @f
xor eax, eax
@@:
inc eax
inc eax
mov edx, [ebx+dlgtemplate.y]
sub edx, [ebx+dlgtemplate.border_size_y]
ja @f
xor edx, edx
@@:
inc edx
call get_console_ptr
mov ecx, [ebx+dlgtemplate.y]
add ecx, [ebx+dlgtemplate.height]
add ecx, [ebx+dlgtemplate.border_size_y]
inc ecx
cmp ecx, [cur_height]
jb @f
mov ecx, [cur_height]
@@:
sub ecx, edx
mov edx, ecx
mov ecx, [ebx+dlgtemplate.x]
add ecx, [ebx+dlgtemplate.width]
add ecx, [ebx+dlgtemplate.border_size_x]
inc ecx
inc ecx
cmp ecx, [cur_width]
jb @f
mov ecx, [cur_width]
@@:
sub ecx, eax
mov eax, ecx
.shadow_loop:
mov ecx, eax
push edi
.sl1:
inc edi
test byte [edi], 0x0F
jnz @f
or byte [edi], 8
@@:
and byte [edi], 0x0F
inc edi
loop .sl1
pop edi
add edi, [cur_width]
add edi, [cur_width]
dec edx
jnz .shadow_loop
.noshadow:
popad
push dword [esp+8]
push dword [esp+8]
call DrawGenericBox
xor eax, eax
ret 8
; void __stdcall DrawGenericBox(DLGDATA* dlg, void* DlgProc)
DrawGenericBox:
pushad
mov ebx, [esp+24h]
; draw area background
mov eax, [ebx+dlgtemplate.x]
sub eax, [ebx+dlgtemplate.border_size_x]
ja @f
xor eax, eax
@@:
mov edx, [ebx+dlgtemplate.y]
sub edx, [ebx+dlgtemplate.border_size_y]
ja @f
xor edx, edx
@@:
call get_console_ptr
mov ecx, [ebx+dlgtemplate.x]
add ecx, [ebx+dlgtemplate.width]
add ecx, [ebx+dlgtemplate.border_size_x]
cmp ecx, [cur_width]
jb @f
mov ecx, [cur_width]
@@:
sub ecx, eax
mov esi, ecx
mov ecx, [ebx+dlgtemplate.y]
add ecx, [ebx+dlgtemplate.height]
add ecx, [ebx+dlgtemplate.border_size_y]
cmp ecx, [cur_height]
jb @f
mov ecx, [cur_height]
@@:
sub ecx, edx
mov edx, ecx
mov al, ' '
mov ah, [ebx+dlgtemplate.border_color]
.1:
mov ecx, esi
push edi
rep stosw
pop edi
add edi, [cur_width]
add edi, [cur_width]
dec edx
jnz .1
; draw border
mov eax, [ebx+dlgtemplate.x]
dec eax
mov edx, [ebx+dlgtemplate.y]
dec edx
call get_console_ptr
mov edx, [ebx+dlgtemplate.height]
inc edx
inc edx
mov ah, [ebx+dlgtemplate.border_color]
push ebx
mov ebx, [ebx+dlgtemplate.width]
inc ebx
inc ebx
call draw_border
pop ebx
; draw header
mov esi, [ebx+dlgtemplate.title]
test esi, esi
jz .noheader
cmp byte [esi], 0
jz .noheader
push esi
@@: lodsb
test al, al
jnz @b
mov eax, esi
pop esi
sub eax, esi
inc eax ; eax = <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> + 2
mov ecx, [ebx+dlgtemplate.width]
cmp eax, ecx
jbe .fullhea
sub ecx, 5
jb .noheader
xor edx, edx
jmp .drawhea
.fullhea:
mov edx, ecx
sub edx, eax
shr edx, 1
.drawhea:
mov eax, [ebx+dlgtemplate.x]
add eax, edx
mov edx, [ebx+dlgtemplate.y]
dec edx
call get_console_ptr
mov ah, [ebx+dlgtemplate.header_color]
mov al, ' '
stosw
.2:
dec ecx
jz .3
lodsb
test al, al
jz .4
stosw
jmp .2
.3:
mov al, '.'
stosw
stosw
stosw
.4:
mov al, ' '
stosw
.noheader:
; draw window background
mov eax, [ebx+dlgtemplate.x]
mov edx, [ebx+dlgtemplate.y]
call get_console_ptr
mov ah, [ebx+dlgtemplate.main_color]
mov al, ' '
mov edx, [ebx+dlgtemplate.height]
@@:
mov ecx, [ebx+dlgtemplate.width]
push edi
rep stosw
pop edi
add edi, [cur_width]
add edi, [cur_width]
dec edx
jnz @b
; send redraw message
mov eax, [esp+28h]
push 0
push 0
push 1
push ebx
call eax
call draw_image
popad
ret 8
; void __stdcall HideGenericBox(DLGTEMPLATE* dlg, int bRedrawWindow);
HideGenericBox:
; void __stdcall HideDialogBox(DLGDATA* dlg, int bRedrawWindow);
HideDialogBox:
pushad
mov ebx, [esp+24h]
mov ebp, [ebx+dlgtemplate.dataptr]
add ebp, 8
; restore data
mov eax, [ebx+dlgtemplate.y]
add eax, [ebx+dlgtemplate.height]
add eax, [ebx+dlgtemplate.border_size_y]
inc eax
push eax
mov eax, [ebx+dlgtemplate.x]
add eax, [ebx+dlgtemplate.width]
add eax, [ebx+dlgtemplate.border_size_x]
inc eax
inc eax
push eax
mov eax, [ebx+dlgtemplate.y]
sub eax, [ebx+dlgtemplate.border_size_y]
push eax
mov eax, [ebx+dlgtemplate.x]
sub eax, [ebx+dlgtemplate.border_size_x]
push eax
call restore_console_data
call draw_keybar
lea ecx, [ebp-8]
push dword [ecx]
push dword [ecx+4]
pop [ebx+dlgtemplate.y]
pop [ebx+dlgtemplate.x]
cmp ebx, nomem_dlgdata
jz @f
call pgfree
@@:
or [cursor_x], -1
or [cursor_y], -1
cmp dword [esp+28h], 0
jz @f
call draw_image
@@:
popad
ret 8
save_console_data:
cmp dword [esp+4], 0
jge @f
and dword [esp+4], 0
@@:
cmp dword [esp+8], 0
jge @f
and dword [esp+8], 0
@@:
mov eax, [esp+12]
cmp eax, [cur_width]
jbe @f
mov eax, [cur_width]
@@:
sub eax, [esp+4]
ja @f
ret 16
@@:
mov [esp+12], eax
mov eax, [esp+16]
cmp eax, [cur_height]
jbe @f
mov eax, [cur_height]
@@:
sub eax, [esp+8]
ja @f
ret 16
@@:
mov [esp+16], eax
mov eax, [esp+4]
mov edx, [esp+8]
call get_console_ptr
mov esi, edi
mov edi, ebp
.l:
mov ecx, [esp+12]
push esi
shr ecx, 1
rep movsd
adc ecx, ecx
rep movsw
pop esi
add esi, [cur_width]
add esi, [cur_width]
dec dword [esp+16]
jnz .l
ret 16
restore_console_data:
cmp dword [esp+4], 0
jge @f
and dword [esp+4], 0
@@:
cmp dword [esp+8], 0
jge @f
and dword [esp+8], 0
@@:
mov eax, [esp+12]
cmp eax, [cur_width]
jbe @f
mov eax, [cur_width]
@@:
sub eax, [esp+4]
ja @f
ret 16
@@:
mov [esp+12], eax
mov eax, [esp+16]
cmp eax, [cur_height]
jbe @f
mov eax, [cur_height]
@@:
sub eax, [esp+8]
ja @f
ret 16
@@:
mov [esp+16], eax
mov eax, [esp+4]
mov edx, [esp+8]
call get_console_ptr
mov esi, ebp
.l:
mov ecx, [esp+12]
push edi
shr ecx, 1
rep movsd
adc ecx, ecx
rep movsw
pop edi
add edi, [cur_width]
add edi, [cur_width]
dec dword [esp+16]
jnz .l
ret 16
; int __stdcall menu(void* variants, const char* title, unsigned flags);
; variants <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD> <EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ᯨ᪥
menu:
pop eax
push [cur_height]
push [cur_width]
push 0
push 0
push eax
; int __stdcall menu_centered_in(unsigned left, unsigned top, unsigned width, unsigned height,
; void* variants, const char* title, unsigned flags);
menu_centered_in:
pushad
mov ecx, 60
; 40 bytes for dlgtemplate + additional:
; +40: dd cur_variant
; +44: dd num_variants
; +48: dd begin_variant
; +52: dd end_variant
; +56: dd cur_variant_idx
call xpgalloc
test eax, eax
jnz @f
.ret_bad:
popad
or eax, -1
ret 28
@@:
mov ebx, eax
mov eax, 1
test byte [esp+20h+28], 1
jz @f
mov al, 3
@@:
mov [ebx+dlgtemplate.border_size_x], eax
inc eax
shr eax, 1
mov [ebx+dlgtemplate.border_size_y], eax
; <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
xor eax, eax
xor ecx, ecx
mov esi, [esp+20h+20]
mov [ebx+40], esi
and dword [ebx+56], 0
@@:
cmp dword [esi+4], 0
jz .find_width
mov esi, [esi+4]
inc dword [ebx+56]
jmp @b
.find_width:
mov [ebx+48], esi
add esi, 8
push esi
xor edx, edx
.fw1:
cmp byte [esi], '&'
jnz @f
mov dl, 1
@@:
inc esi
cmp byte [esi-1], 0
jnz .fw1
sub esi, [esp]
sub esi, edx
dec esi
cmp eax, esi
ja @f
mov eax, esi
@@:
inc ecx
pop esi
mov esi, [esi-8]
test esi, esi
jnz .find_width
add eax, 3
add eax, [ebx+dlgtemplate.border_size_x]
add eax, [ebx+dlgtemplate.border_size_x]
cmp eax, [cur_width]
jb @f
mov eax, [cur_width]
@@:
sub eax, [ebx+dlgtemplate.border_size_x]
sub eax, [ebx+dlgtemplate.border_size_x]
mov [ebx+dlgtemplate.width], eax
mov [ebx+dlgtemplate.height], ecx
mov [ebx+44], ecx
sub eax, [esp+20h+12]
neg eax
sar eax, 1
add eax, [esp+20h+4]
cmp eax, [ebx+dlgtemplate.border_size_x]
jge @f
mov eax, [ebx+dlgtemplate.border_size_x]
@@:
push eax
add eax, [ebx+dlgtemplate.width]
add eax, [ebx+dlgtemplate.border_size_x]
cmp eax, [cur_width]
jbe @f
pop eax
mov eax, [cur_width]
sub eax, [ebx+dlgtemplate.width]
sub eax, [ebx+dlgtemplate.border_size_x]
push eax
@@:
pop [ebx+dlgtemplate.x]
sub ecx, [esp+20h+16]
neg ecx
sar ecx, 1
add ecx, [esp+20h+8]
cmp ecx, [ebx+dlgtemplate.border_size_y]
jge @f
mov ecx, [ebx+dlgtemplate.border_size_y]
@@:
push ecx
add ecx, [ebx+dlgtemplate.height]
add ecx, [ebx+dlgtemplate.border_size_y]
cmp ecx, [cur_height]
jbe @f
pop ecx
mov ecx, [cur_height]
sub ecx, [ebx+dlgtemplate.height]
sub ecx, [ebx+dlgtemplate.border_size_y]
push ecx
@@:
pop [ebx+dlgtemplate.y]
mov eax, [cur_height]
sub eax, 6
cmp [ebx+dlgtemplate.height], eax
jbe .small_height
mov [ebx+dlgtemplate.height], eax
mov [ebx+dlgtemplate.y], 3
.small_height:
mov ecx, [ebx+dlgtemplate.height]
mov eax, [ebx+40]
mov [ebx+48], eax
dec ecx
jz .skip
push ecx
@@:
cmp dword [eax+4], 0
jz @f
mov eax, [eax+4]
loop @b
@@:
mov [ebx+48], eax
pop ecx
.loop:
mov eax, [eax]
loop .loop
.skip:
mov [ebx+52], eax
mov eax, [esp+20h+24]
mov [ebx+dlgtemplate.title], eax
mov al, [menu_normal_color]
mov [ebx+dlgtemplate.main_color], al
mov al, [menu_border_color]
mov [ebx+dlgtemplate.border_color], al
mov al, [menu_header_color]
mov [ebx+dlgtemplate.header_color], al
push MenuDlgProc
push ebx
call GenericBox
mov [esp+28], eax
mov ecx, ebx
call pgfree
popad
ret 28
MenuDlgProc:
mov eax, [esp+8]
cmp al, 1
jz .draw
cmp al, 2
jz .key
ret 16
.draw:
call .dodraw
ret 16
.prev:
mov eax, [ebx+40]
cmp dword [eax+4], 0
jz .end
call .line_prev
.posret:
mov [ebx+40], eax
.redraw:
call .dodraw
call draw_image
xor eax, eax
ret 16
.next:
mov eax, [ebx+40]
cmp dword [eax], 0
jz .home
call .line_next
jmp .posret
.pgdn:
mov eax, [ebx+40]
mov ecx, [ebx+dlgtemplate.height]
.pgdnl:
cmp dword [eax], 0
jz .posret
call .line_next
loop .pgdnl
jmp .posret
.key:
mov al, [esp+12]
cmp al, 0x48
jz .prev
cmp al, 0x4B
jz .prev
cmp al, 0x4D
jz .next
cmp al, 0x50
jz .next
cmp al, 0x1C
jz .enter
cmp al, 1
jz .esc
cmp al, 0x47
jz .home
cmp al, 0x4F
jz .end
cmp al, 0x51
jz .pgdn
cmp al, 0x49
jz .pgup
cmp al, 0x52
jz .ins
cmp al, 0x53
jz .del
mov edx, [ebx+40]
@@:
cmp dword [edx+4], 0
jz @f
mov edx, [edx+4]
jmp @b
@@:
.l:
lea esi, [edx+7]
@@:
inc esi
cmp byte [esi], 0
jz .n
cmp byte [esi], '&'
jnz @b
movzx ecx, byte [esi+1]
cmp [ascii2scan+ecx], al
jnz .n
mov eax, edx
ret 16
.n:
mov edx, [edx]
test edx, edx
jnz .l
.ret:
xor eax, eax
ret 16
.pgup:
mov eax, [ebx+40]
mov ecx, [ebx+dlgtemplate.height]
.pgupl:
cmp dword [eax+4], 0
jz .posret
call .line_prev
loop .pgupl
jmp .posret
.home:
mov eax, [ebx+40]
@@:
cmp dword [eax+4], 0
jz @f
mov eax, [eax+4]
jmp @b
@@:
mov [ebx+48], eax
push eax
mov ecx, [ebx+dlgtemplate.height]
dec ecx
jz .h1
.h2:
mov eax, [eax]
loop .h2
.h1:
mov [ebx+52], eax
pop eax
and dword [ebx+56], 0
jmp .posret
.end:
mov eax, [ebx+40]
@@:
cmp dword [eax], 0
jz @f
mov eax, [eax]
jmp @b
@@:
mov [ebx+52], eax
push eax
mov ecx, [ebx+dlgtemplate.height]
dec ecx
jz .e1
.e2:
mov eax, [eax+4]
loop .e2
.e1:
mov [ebx+48], eax
mov eax, [ebx+44]
dec eax
mov [ebx+56], eax
pop eax
jmp .posret
.esc:
or eax, -1
ret 16
.enter:
mov eax, [ebx+40]
ret 16
.ins:
push 5
pop edx
jmp @f
.del:
push 4
pop edx
@@:
mov eax, [ebx+40]
cmp byte [eax+8], '/'
jnz @f
cmp word [eax+9], 'cd'
jnz @f
movzx ecx, byte [eax+11]
sub ecx, '0'
push 24
pop eax
mov ebx, edx
int 40h
@@:
xor eax, eax
ret 16
.line_prev:
cmp eax, [ebx+48]
jnz @f
mov edx, [ebx+48]
mov edx, [edx+4]
mov [ebx+48], edx
mov edx, [ebx+52]
mov edx, [edx+4]
mov [ebx+52], edx
@@:
mov eax, [eax+4]
dec dword [ebx+56]
ret
.line_next:
cmp eax, [ebx+52]
jnz @f
mov edx, [ebx+48]
mov edx, [edx]
mov [ebx+48], edx
mov edx, [ebx+52]
mov edx, [edx]
mov [ebx+52], edx
@@:
mov eax, [eax]
inc dword [ebx+56]
ret
.dodraw:
mov eax, [ebx+dlgtemplate.x]
mov edx, [ebx+dlgtemplate.y]
call get_console_ptr
mov esi, [ebx+48]
.0:
xor edx, edx
mov ah, [menu_selected_color]
cmp esi, [ebx+40]
jz @f
mov ah, [menu_normal_color]
@@:
push edi
mov ecx, [ebx+dlgtemplate.width]
mov al, ' '
stosw
dec ecx
stosw
dec ecx
dec ecx
push esi
add esi, 8
@@:
lodsb
test al, al
jz @f
cmp al, '&'
jnz .noamp
test dl, dl
jnz .noamp
mov dl, 1
lodsb
push eax
mov ah, [menu_selected_highlight_color]
push ecx
mov ecx, [esp+8]
cmp ecx, [ebx+40]
pop ecx
jz .amp1
mov ah, [menu_highlight_color]
.amp1:
stosw
pop eax
jmp .amp2
.noamp:
stosw
.amp2:
loop @b
mov al, ' '
cmp byte [esi], 0
jnz .1
lodsb
jmp .1
@@:
mov al, ' '
.1:
stosw
mov al, ' '
rep stosw
pop esi edi
add edi, [cur_width]
add edi, [cur_width]
cmp esi, [ebx+52]
jz @f
mov esi, [esi]
test esi, esi
jnz .0
@@:
; <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>
mov ecx, [ebx+dlgtemplate.height]
cmp ecx, [ebx+44]
jz .noscrollbar
sub ecx, 2
jbe .noscrollbar
mov eax, [ebx+56]
mul ecx
div dword [ebx+44]
push eax
mov eax, [ebx+dlgtemplate.x]
add eax, [ebx+dlgtemplate.width]
mov edx, [ebx+dlgtemplate.y]
call get_console_ptr
pop edx
inc edx
mov al, 0x1E
mov ah, [menu_scrollbar_color]
mov [edi], ax
add edi, [cur_width]
add edi, [cur_width]
.2:
mov al, 0xB2
dec edx
jz @f
mov al, 0xB0
@@:
mov [edi], ax
add edi, [cur_width]
add edi, [cur_width]
loop .2
mov al, 0x1F
stosw
.noscrollbar:
ret
get_ascii_char:
; query keyboard layout
pushad
mov al, [ctrlstate]
and al, 3
xor ecx, ecx
cmp al, 1
sbb ecx, -2
push 26
pop eax
push 2
pop ebx
mov edx, layout
int 0x40
popad
; translate scancode to ASCII
movzx eax, byte [layout+eax]
ret
virtual at 0
dlgitemtemplate:
; <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:
; 1 = <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD>
; 2 = <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 3 = <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
.type dd ?
.x1 dd ?
.y1 dd ?
.x2 dd ?
.y2 dd ?
; <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:
; <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>: const char* data - ASCIIZ-<EFBFBD><EFBFBD><EFBFBD>
; <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: const char* data - <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: struct {unsigned maxlength; unsigned pos; unsigned start;
; char data[maxlength+1];}* data;
.data dd ?
.flags dd ?
; <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:
; 0 = <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 1 = <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>
; 2 = <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>
; 4 = <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 8 = <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 10h: <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> = <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> (Enter <EFBFBD><EFBFBD> <EFBFBD><EFBFBD>-<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
; <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> = <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 20h: <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> = <EFBFBD><EFBFBD> <EFBFBD>⮡ࠦ<EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> '*')
.size = $
end virtual
; struct DLGDATA
; {
; DLGTEMPLATE dialog; /* window description */
; void* DlgProc; /* dialog procedure */
; /* int __stdcall DlgProc(DLGDATA* dlg, int msg, int param1, int param2); */
; void* user_data; /* arbitrary user data */
; unsigned num_items; /* number of items in the following array */
; DLGITEMTEMPLATE items[]; /* array of dialog items */
; }
; int __stdcall DialogBox(DLGDATA* dlg);
DialogBox:
push ManagerDlgProc
push dword [esp+8]
call GenericBox
ret 4
; int __stdcall ShowDialogBox(DLGDATA* dlg);
ShowDialogBox:
push ManagerDlgProc
push dword [esp+8]
call ShowGenericBox
ret 4
; void __stdcall DrawDialogBox(DLGDATA* dlg);
DrawDialogBox:
push ManagerDlgProc
push dword [esp+8]
call DrawGenericBox
ret 4
ManagerDlgProc:
mov ebp, ebx
mov eax, [esp+8]
dec eax
jz .draw
dec eax
jz .key
xor eax, eax
ret 16
.draw:
call .dodraw
ret 16
.key:
; find item with focus
add ebx, dlgtemplate.size+12
mov ecx, [ebx-4]
jecxz .nobtns
@@:
test [ebx+dlgitemtemplate.flags], 4
jnz @f
add ebx, dlgitemtemplate.size
loop @b
@@:
.nobtns:
mov al, [esp+12]
cmp al, 1
jz .esc
cmp al, 0x1C
jz .enter
cmp al, 0xF
jz .tab
cmp al, 0x48
jz .up
cmp al, 0x50
jz .down
jecxz @f
cmp [ebx+dlgitemtemplate.type], 3
jz .key_edit
@@:
cmp al, 0x4B
jz .left
cmp al, 0x4D
jz .right
.ret0:
xor eax, eax
ret 16
.esc:
or eax, -1
ret 16
.enter:
cmp [ebx+dlgitemtemplate.type], 2
jnz @f
.enter_found:
mov eax, ebx
ret 16
@@:
lea ebx, [ebp+dlgtemplate.size+12]
mov ecx, [ebx-4]
.enter_find:
cmp [ebx+dlgitemtemplate.type], 2
jnz @f
test [ebx+dlgitemtemplate.flags], 0x10
jnz .enter_found
@@:
add ebx, dlgitemtemplate.size
loop .enter_find
jmp .enter_found
.tab:
test [ctrlstate], 3
jnz .shift_tab
.right:
.down:
jecxz .ret0
and byte [ebx+dlgitemtemplate.flags], not 4
dec ecx
jz .find_first_btn
@@:
add ebx, dlgitemtemplate.size
test [ebx+dlgitemtemplate.flags], 8
jnz .btn_found
loop @b
.find_first_btn:
lea ebx, [ebp+dlgtemplate.size+12]
@@:
test [ebx+dlgitemtemplate.flags], 8
jnz .btn_found
add ebx, dlgitemtemplate.size
jmp @b
.btn_found:
or byte [ebx+dlgitemtemplate.flags], 4
.ret_draw:
mov ebx, ebp
call .dodraw
call draw_image
xor eax, eax
ret 16
.shift_tab:
.left:
.up:
jecxz .ret0
and byte [ebx+dlgitemtemplate.flags], not 4
sub ecx, [ebp+dlgtemplate.size+8]
neg ecx
jz .find_last_btn
@@:
sub ebx, dlgitemtemplate.size
test [ebx+dlgitemtemplate.flags], 8
loopz @b
jnz .btn_found
.find_last_btn:
mov ebx, [ebp+dlgtemplate.size+8]
imul ebx, dlgitemtemplate.size
lea ebx, [ebx+ebp+dlgtemplate.size+12]
@@:
sub ebx, dlgitemtemplate.size
test [ebx+dlgitemtemplate.flags], 8
jz @b
jmp .btn_found
.key_edit:
; <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
test al, 0x80
jnz .ret0
or [ebx+dlgitemtemplate.flags], 0x10
mov edx, [ebx+dlgitemtemplate.data]
cmp al, 0x4B
jz .editor_left
cmp al, 0x4D
jz .editor_right
cmp al, 0x47
jz .editor_home
cmp al, 0x4F
jz .editor_end
cmp al, 0x0E
jz .editor_backspace
cmp al, 0x53
jnz .editor_char
.editor_del:
mov ecx, [edx+4]
lea edi, [ecx+edx+12]
lea esi, [edi+1]
cmp byte [edi], 0
jz .ret_test
jmp .copy_and_ret_test
.editor_left:
mov ecx, [edx+4]
jecxz @f
dec dword [edx+4]
@@: jmp .ret_test
.editor_right:
mov ecx, [edx+4]
cmp byte [edx+ecx+12], 0
jz @b
inc dword [edx+4]
jmp @b
.editor_home:
and dword [edx+4], 0
jmp @b
.editor_end:
lea edi, [edx+12]
xor eax, eax
or ecx, -1
repnz scasb
not ecx
dec ecx
mov [edx+4], ecx
.ret_test:
mov eax, [edx+4]
cmp [edx+8], eax
jl .ret_test.l1
mov [edx+8], eax
jmp .ret_test.l2
.ret_test.l1:
add eax, [ebx+dlgitemtemplate.x1]
sub eax, [ebx+dlgitemtemplate.x2]
cmp [edx+8], eax
jge .ret_test.l2
mov [edx+8], eax
.ret_test.l2:
jmp .ret_draw
.editor_backspace:
mov ecx, [edx+4]
jecxz .ret_test
dec dword [edx+4]
lea esi, [edx+ecx+12]
lea edi, [esi-1]
.copy_and_ret_test:
@@:
lodsb
stosb
test al, al
jnz @b
jmp .ret_test
.editor_char:
test [ctrlstate], 0x3C
jnz .ret_draw
movzx eax, al
call get_ascii_char
push eax
; insert entered symbol
xor eax, eax
lea edi, [edx+12]
or ecx, -1
repnz scasb
not ecx
pop eax
cmp ecx, [edx]
ja .ret_test ; buffer capacity exceeded
lea edi, [edx+ecx+12-1]
mov esi, [edx+4]
lea esi, [edx+esi+12]
@@:
mov cl, [edi]
mov [edi+1], cl
dec edi
cmp edi, esi
jae @b
mov [esi], al
inc dword [edx+4]
@@: jmp .ret_test
.dodraw:
or [cursor_x], -1
or [cursor_y], -1
add ebx, dlgtemplate.size+8
mov ecx, [ebx]
add ebx, 4
jecxz .done_draw
.draw_loop:
push ecx
mov eax, [ebx+dlgitemtemplate.type]
dec eax
jz .draw_text
dec eax
jz .draw_button
dec eax
jnz .draw_loop_continue
call draw_editbox
jmp .draw_loop_continue
.draw_button:
call draw_button
jmp .draw_loop_continue
.draw_text:
call draw_static_text
.draw_loop_continue:
pop ecx
add ebx, dlgitemtemplate.size
loop .draw_loop
.done_draw:
ret
draw_static_text:
; <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD>
mov ah, [dialog_main_color]
test byte [ebp+dlgtemplate.flags], 2
jz draw_text
mov ah, [warning_main_color]
draw_text:
; <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>
mov esi, [ebx+dlgitemtemplate.data]
draw_text_esi:
test esi, esi
jz .ret
push -1
pop ecx
@@:
inc ecx
cmp byte [ecx+esi], 0
jnz @b
; <EFBFBD> ecx <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>
push eax
xor eax, eax
mov edx, [ebx+dlgitemtemplate.x2]
sub edx, [ebx+dlgitemtemplate.x1]
inc edx
cmp ecx, edx
jae .text_draw
mov al, byte [ebx+dlgitemtemplate.flags]
and al, 3
jz .text_align_left
cmp al, 1
jz .text_align_center
; <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>
mov eax, edx
sub eax, ecx
jmp .text_draw
.text_align_center:
mov eax, edx
sub eax, ecx
shr eax, 1
jmp .text_draw
.text_align_left:
xor eax, eax
.text_draw:
push ecx
push eax
mov eax, [ebx+dlgitemtemplate.x1]
add eax, [ebp+dlgtemplate.x]
push edx
mov edx, [ebx+dlgitemtemplate.y1]
add edx, [ebp+dlgtemplate.y]
call get_console_ptr
pop edx
pop ecx
mov ah, [esp+5]
mov al, ' '
rep stosw
pop ecx
cmp ecx, edx
jbe .text_copy
cmp [ebx+dlgitemtemplate.type], 3
jnz @f
mov ecx, edx
jmp .text_copy
@@:
cmp edx, 3
jb .ret
mov al, '.'
stosw
stosw
stosw
add esi, ecx
mov ecx, edx
sub ecx, 3
sub esi, ecx
.text_copy:
jecxz .ret
; check for password editboxes
cmp [ebx+dlgitemtemplate.type], 3
jnz @f
test [ebx+dlgitemtemplate.flags], 20h
jz @f
mov al, '*'
rep stosw
jmp .ret
@@:
lodsb
stosw
loop @b
.ret:
mov eax, [ebp+dlgtemplate.x]
mov edx, [ebp+dlgtemplate.y]
add eax, [ebx+dlgitemtemplate.x2]
inc eax
add edx, [ebx+dlgitemtemplate.y1]
mov ecx, edi
call get_console_ptr
xchg ecx, edi
sub ecx, edi
shr ecx, 1
pop eax
mov al, ' '
rep stosw
ret
draw_button:
mov ecx, dialog_colors
test byte [ebp+dlgtemplate.flags], 2
jz @f
mov ecx, warning_colors
@@:
mov ah, [dialog_normal_btn_color-dialog_colors+ecx]
test [ebx+dlgitemtemplate.flags], 4
jz @f
mov ah, [dialog_selected_btn_color-dialog_colors+ecx]
@@:
jmp draw_text
draw_editbox:
mov edx, [ebx+dlgitemtemplate.data]
test [ebx+dlgitemtemplate.flags], 4
jz @f
mov eax, [ebx+dlgitemtemplate.x1]
add eax, [edx+4]
sub eax, [edx+8]
add eax, [ebp+dlgtemplate.x]
mov [cursor_x], eax
mov eax, [ebx+dlgitemtemplate.y1]
add eax, [ebp+dlgtemplate.y]
mov [cursor_y], eax
@@:
mov ecx, dialog_colors
test byte [ebp+dlgtemplate.flags], 2
jz @f
mov ecx, warning_colors
@@:
mov ah, [dialog_edit_color-dialog_colors+ecx]
test [ebx+dlgitemtemplate.flags], 10h
jnz @f
mov ah, [dialog_unmodified_edit_color-dialog_colors+ecx]
@@:
mov esi, [ebx+dlgitemtemplate.data]
add esi, [edx+8]
add esi, 12
jmp draw_text_esi
; void __stdcall SayNoMem(void);
SayNoMem:
or dword [nomem_dlgdata+4], -1
or dword [nomem_dlgdata+8], -1
push nomem_dlgdata
call DialogBox
ret
; int __stdcall SayErr(int num_strings, const char* strings[],
; int num_buttons, const char* buttons[]);
SayErr:
pop eax
push aError
push eax
; int __stdcall SayErrTitle(const char* title,
; int num_strings, const char* strings[],
; int num_buttons, const char* buttons[]);
SayErrTitle:
push 2
jmp @f
; int __stdcall Message(const char* title,
; int num_strings, const char* strings[],
; int num_buttons, const char* buttons[]);
Message:
push 1
@@:
pop eax
; [esp+4] = title
; [esp+8] = num_strings
; [esp+12] = strings
; [esp+16] = num_buttons
; [esp+20] = buttons
pushad
mov ecx, [esp+32+8]
add ecx, [esp+32+16]
imul ecx, dlgitemtemplate.size
add ecx, dlgtemplate.size+12
call xpgalloc
test eax, eax
jnz @f
popad
or eax, -1
ret 28
@@:
mov ebx, eax
mov edi, eax
mov eax, [esp+28]
stosd ; dlgtemplate.flags
or eax, -1
stosd ; dlgtemplate.x
stosd ; dlgtemplate.y
; calculate width
mov ecx, [esp+32+8]
mov esi, [esp+32+12]
xor edx, edx
.calcwidth:
lodsd
@@:
inc eax
cmp byte [eax-1], 0
jnz @b
sub eax, [esi-4]
inc eax
cmp edx, eax
ja @f
mov edx, eax
@@:
loop .calcwidth
mov ecx, [esp+32+16]
mov esi, [esp+32+20]
xor ebp, ebp
.calcwidth2:
lodsd
@@:
inc eax
cmp byte [eax-1], 0
jnz @b
sub eax, [esi-4]
inc eax
add ebp, eax
loop .calcwidth2
inc ebp
inc ebp
cmp edx, ebp
ja @f
mov edx, ebp
@@:
mov eax, [cur_width]
sub eax, 8
cmp edx, eax
jb @f
mov edx, eax
@@:
mov eax, edx
stosd ; dlgtemplate.width
mov eax, [esp+32+8]
inc eax
stosd ; dlgtemplate.height
mov eax, 3
stosd ; dlgtemplate.border_size_x
mov al, 2
stosd ; dlgtemplate.border_size_y
mov eax, [esp+32+4]
stosd ; dlgtemplate.title
xor eax, eax
stosd ; (ignored)
stosd ; (ignored)
stosd ; DlgProc
stosd ; userdata
mov eax, [esp+32+8]
add eax, [esp+32+16]
stosd ; num_items
; fill strings
xor ecx, ecx
mov esi, [esp+32+12]
@@:
mov eax, 1
stosd ; dlgitemtemplate.type
dec eax
stosd ; dlgitemtemplate.x1
mov eax, ecx
stosd ; dlgitemtemplate.y1
lea eax, [edx-1]
stosd ; dlgitemtemplate.x2
mov eax, ecx
stosd ; dlgitemtemplate.y2
movsd ; dlgitemtemplate.data
mov eax, 1
stosd ; dlgitemtemplate.flags
inc ecx
cmp ecx, [esp+32+8]
jb @b
; fill buttons
mov ecx, [esp+32+16]
mov esi, [esp+32+20]
sub edx, ebp
jc .big
shr edx, 1
inc edx
jmp .fillbtns
.big:
xor edx, edx
.fillbtns:
mov eax, 2
stosd ; dlgitemtemplate.type
mov eax, edx
stosd ; dlgitemtemplate.x1
mov eax, [ebx+dlgtemplate.height]
dec eax
stosd ; dlgitemtemplate.y1
push eax
lodsd
sub eax, edx
@@:
inc edx
cmp byte [eax+edx-1], 0
jnz @b
mov eax, edx
inc edx
stosd ; dlgitemtemplate.x2
pop eax
stosd ; dlgitemtemplate.y2
mov eax, [esi-4]
stosd ; dlgitemtemplate.data
mov eax, 9
cmp ecx, [esp+32+16]
jnz @f
or al, 4
@@:
stosd ; dlgitemtemplate.flags
loop .fillbtns
push ebx
call DialogBox
cmp eax, -1
jz @f
sub eax, ebx
sub eax, dlgtemplate.size+12
xor edx, edx
mov ecx, dlgitemtemplate.size
div ecx
sub eax, [esp+32+8]
@@:
mov [esp+28], eax
mov ecx, ebx
call pgfree
popad
ret 20