kolibrios-fun/programs/fs/kfar/trunk/dialogs.inc
IgorA 7a4aed6e11 kfar: add mouse in menu dialogs, fix mouse alt+f12
git-svn-id: svn://kolibrios.org@9059 a494cfbc-eb01-0410-851d-a64ba20cac60
2021-07-13 08:15:21 +00:00

2309 lines
60 KiB
PHP
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

; int __stdcall GenericBox(DLGTEMPLATE* dlg, void* DlgProc);
; int __stdcall DlgProc(DLGTEMPLATE* dlg, int msg, int param1, int param2);
virtual at 0
dlgtemplate:
; ”« £¨:
; ¡¨â 0: ¨á¯®«ì§®¢ âì áâ ­¤ àâ­ë¥ æ¢¥â  ¤¨ «®£ 
; ¡¨â 1: ¨á¯®«ì§®¢ âì áâ ­¤ àâ­ë¥ æ¢¥â  ¯à¥¤ã¯à¥¦¤¥­¨ï/®è¨¡ª¨
; (¥á«¨ «î¡®© ¨§ íâ¨å ¡¨â®¢ ãáâ ­®¢«¥­, ¯®«ï main_color,border_color,header_color
; ¨£­®à¨àãîâáï)
; ¡¨â 2: ­¥ à¨á®¢ âì ⥭ì
.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
align 16
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:
; call get_event
push SF_WAIT_EVENT
pop eax
int 40h
dec eax
jz .redraw
dec eax
jz .key
sub eax, 4
jz .mouse
jmp exit
.redraw:
call draw_window
jmp .event
.key:
mov al, SF_GET_KEY
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 ;DlgProc
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
align 4
.mouse:
mov eax,SF_MOUSE_GET
mov ebx,SSF_BUTTON_EXT
int 0x40
mov byte[mousestate], 1
bt eax,8 ;left but. down
jc @f
mov byte[mousestate], 0
@@:
mov eax,SF_MOUSE_GET
mov ebx,SSF_WINDOW_POSITION
int 0x40
cmp ax, word[skinh]
jl .event
sub ax, word[skinh]
xor dx,dx
mov bx, font_height
div bx
movzx edx,ax
shr eax,16
sub eax, 5 ;window border
push edx
xor dx,dx
mov bx, font_width
div bx
movzx eax,ax
pop edx
mov ebx, [esp+24h+8] ;DLGTEMPLATE* dlg
cmp edx, [ebx+dlgtemplate.y]
jl .event
cmp eax, [ebx+dlgtemplate.x]
jl .event
sub edx, [ebx+dlgtemplate.y]
sub eax, [ebx+dlgtemplate.x]
cmp edx, [ebx+dlgtemplate.height]
jge .event
cmp eax, [ebx+dlgtemplate.width]
jge .event
cmp dword[ebx+dlgtemplate.size], 0
je .m_menu_end
;¥á«¨ ¤¨ «®£®¢®¥ ®ª­® ­¥ áâ ­¤ àâ­®¥ (ᯨ᮪ §­ ç¥­¨©)
cmp edx, [ebx+44]
jl @f
mov edx, [ebx+44]
dec edx
@@:
mov ecx, [ebx+48]
mov ecx, [ecx] ;¡¥à¥¬ 㪠§ â¥«ì ­  listitem[1]
sub ecx, [ebx+48] ;ecx - à §¬¥à ®¤­®£® listitem
mov [ebx+56], edx
imul edx, ecx
add edx, [ebx+48]
mov [ebx+40], edx
cmp byte[mousestate], 1
jne @f
mov [esp+28], edx ;save to eax
jmp .exit
@@:
call MenuDlgProc.dodraw
call draw_image
jmp .event
.m_menu_end:
cmp byte[mousestate], 1
jne .event
add ebx, dlgtemplate.size+12
mov ecx, [ebx-4]
or ecx, ecx
jz .event
push ebx ecx
.m_loop:
cmp [ebx+dlgitemtemplate.type], 2 ;button
je .m_comp
cmp [ebx+dlgitemtemplate.type], 3 ;edit
je .m_comp
cmp [ebx+dlgitemtemplate.type], 5 ;check
je .m_comp
jmp .m_next
align 4
.m_comp:
cmp [ebx+dlgitemtemplate.x1], eax
jg .m_next
cmp [ebx+dlgitemtemplate.y1], edx
jg .m_next
cmp [ebx+dlgitemtemplate.x2], eax
jl .m_next
cmp [ebx+dlgitemtemplate.y2], edx
jl .m_next
cmp [ebx+dlgitemtemplate.type], 2 ;button
jne @f
mov [esp+28+8], ebx ;save to eax
pop ecx ebx
jmp .exit
@@:
cmp [ebx+dlgitemtemplate.type], 5 ;check
jne @f
xor [ebx+dlgitemtemplate.flags], 10h
mov eax, ebx
jmp .m_new_focus
@@:
mov eax, [ebx+dlgitemtemplate.flags]
and eax, 4
jnz .m_old_focus
mov eax, ebx
jmp .m_new_focus
align 4
.m_next:
add ebx, sizeof.DlgBtn
loop .m_loop
.m_old_focus:
pop ecx ebx
jmp .event
align 4
.m_new_focus:
pop ecx ebx
call DlgClearFocus
or dword[eax+dlgitemtemplate.flags], 4
sub ebx, dlgtemplate.size+12
push ebp
mov ebp, ebx
call ManagerDlgProc.dodraw
pop ebp
call draw_image
jmp .event
align 4
.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
;input:
; ebx - pointer to first item
; ecx - count items
align 4
DlgClearFocus:
push ebx ecx
@@:
and byte [ebx+dlgitemtemplate.flags], not 4
add ebx, sizeof.DlgBtn
loop @b
pop ecx ebx
ret
; int __stdcall ShowGenericBox(DLGTEMPLATE* dlg, void* DlgProc);
align 16
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
call draw_dialog_shadow
.noshadow:
popad
push dword [esp+8]
push dword [esp+8]
call DrawGenericBox
xor eax, eax
ret 8
draw_dialog_shadow:
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
ret
; void __stdcall DrawGenericBox(DLGDATA* dlg, void* DlgProc)
align 16
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 = ¤«¨­  § £®«®¢ª  + 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);
align 16
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 㪠§ë¢ ¥â ­  ⥪ã騩 í«¥¬¥­â ¢ ¤¢ãá¢ï§­®¬ «¨­¥©­®¬ ᯨ᪥
align 16
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 - 㪠§ â¥«ì ­  ¬ áᨢ listitem[num_variants]
; +44: dd num_variants - ᪮«ìª® í«¥¬¥­â®¢ ¢ ᯨ᪥
; +48: dd begin_variant - 㪠§ â¥«ì ­  listitem[0]
; +52: dd end_variant - 㪠§ â¥«ì ­  listitem[num_variants-1]
; +56: dd cur_variant_idx - ¨­¤¥ªá ¢ë¡à ­­®£® í«¥¬¥­â  ®â 0 ¤® num_variants-1
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 ;unsigned flags
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> å®¤¨¬ è¨à¨­ã ¨ ¢ëá®âã ®ª­ 
xor eax, eax
xor ecx, ecx
mov esi, [esp+20h+20] ;void* variants
mov [ebx+40], esi
mov dword [ebx+56], eax
@@:
cmp dword [esi+4], eax
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
align 16
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 SF_CD
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
@@:
; ‹¨­¥©ª  ¯à®ªàã⪨
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 SF_SYSTEM_GET
pop eax
push SSF_KEYBOARD_LAYOUT
pop ebx
mov edx, layout
int 0x40
popad
; translate scancode to ASCII
movzx eax, byte [layout+eax]
ret
struct DlgLbl
type dd 1
x1 dd ?
y1 dd ?
x2 dd ?
y2 dd ?
text dd ?
flags dd ?
ends
struct DlgBtn
type dd 2
x1 dd ?
y1 dd ?
x2 dd ?
y2 dd ?
text dd ?
flags dd ?
ends
struct DlgEdit
type dd 3
x1 dd ?
y1 dd ?
x2 dd ?
y2 dd ?
text dd ?
flags dd ?
ends
struct DlgLine
type dd 4
x1 dd ?
y1 dd ?
x2 dd ?
y2 dd ?
dq 0
ends
struct DlgCheck
type dd 5
x1 dd ?
y1 dd ?
x2 dd ?
y2 dd ?
text dd ?
flags dd ?
ends
struct DlgList
type dd 6
x1 dd ?
y1 dd ?
x2 dd ?
y2 dd ?
text dd ?
flags dd ?
ends
virtual at 0
dlgitemtemplate:
; <EFBFBD>«¥¬¥­âë:
; 1 = áâ â¨ç¥áª¨© ⥪áâ
; 2 = ª­®¯ª 
; 3 = ¯®«¥ । ªâ¨à®¢ ­¨ï
; 4 = £®à¨§®­â «ì­ë© à §¤¥«¨â¥«ì
; 5 = ä« ¦®ª
; 6 = ᯨ᮪
.type dd ?
.x1 dd ?
.y1 dd ?
.x2 dd ?
.y2 dd ?
; „ ­­ë¥:
; ¤«ï ⥪áâ : const char* data - ASCIIZ-áâப 
; ¤«ï ª­®¯ª¨ ¨ ä« ¦ª : const char* data - § £®«®¢®ª
; ¤«ï । ªâ®à : struct {unsigned maxlength; unsigned pos; unsigned start;
; char data[maxlength+1];}* data;
; ¤«ï ᯨ᪠: struct {listitem* curitemptr; unsigned numitems;
; listitem *head; unsigned curitem;}* data;
; head = 㪠§ â¥«ì ­  ¯¥à¢ë© ®â®¡à ¦ ¥¬ë© í«¥¬¥­â,
; curitemptr = 㪠§ â¥«ì ­  ¢ë¤¥«¥­­ë© í«¥¬¥­â, curitem = ¥£® ¨­¤¥ªá ¢ ᯨ᪥ (®â 0)
; (£¤¥ struct listitem {listitem* next; listitem* prev; char text[];};)
.data dd ?
.flags dd ?
; ”« £¨:
; 0 = ¢ëà ¢­¨¢ ­¨¥ ¢«¥¢®
; 1 = ¢ëà ¢­¨¢ ­¨¥ ¯® 業âàã
; 2 = ¢ëà ¢­¨¢ ­¨¥ ¢¯à ¢®
; 4 = í«¥¬¥­â ¨¬¥¥â 䮪ãá ¢¢®¤ 
; 8 = í«¥¬¥­â ¬®¦¥â ¨¬¥âì 䮪ãá ¢¢®¤ 
; 10h: ¤«ï ª­®¯ª¨ = ª­®¯ª  ¯® 㬮«ç ­¨î (Enter ­  ­¥-ª­®¯ª¥)
; ¤«ï ¯®«ï ¢¢®¤  = ¤ ­­ë¥ ¡ë«¨ ¬®¤¨ä¨æ¨à®¢ ­ë
; ¤«ï ä« ¦ª  = ä« ¦®ª ãáâ ­®¢«¥­
; 20h: ¤«ï ¯®«ï ¢¢®¤  = ­¥ ®â®¡à ¦ âì ¢¢®¤¨¬ë¥ ¤ ­­ë¥ (¯®ª §ë¢ âì '*')
.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);
align 16
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
align 16
ManagerDlgProc:
mov ebp, ebx
mov eax, [esp+8]
dec eax
jz .draw
dec eax
jz .key
;sub eax, 4
;jz .mouse
xor eax, eax
ret 16
.draw:
call .dodraw
ret 16
;.mouse:
;todo
;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 .nobtns2
cmp [ebx+dlgitemtemplate.type], 3
jz .key_edit
cmp [ebx+dlgitemtemplate.type], 5
jnz @f
cmp al, 0x39
jnz @f
xor [ebx+dlgitemtemplate.flags], 10h
jmp .ret_draw
@@:
.nobtns2:
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:
; ®¡à ¡®âª  ª« ¢¨è ¢ ¯®«¥ ¢¢®¤ 
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
align 4
.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]
cmp eax, draw_functions_num
jae .draw_loop_continue
call [draw_functions + eax*4]
.draw_loop_continue:
pop ecx
add ebx, dlgitemtemplate.size
loop .draw_loop
.done_draw:
ret
iglobal
align 4
label draw_functions dword
dd ManagerDlgProc.done_draw
dd draw_static_text
dd draw_button
dd draw_editbox
dd draw_h_separator
dd draw_checkbox
dd draw_listbox
draw_functions_num = ($ - draw_functions) / 4
endg
align 4
draw_static_text:
; à¨á㥬 áâ â¨ç¥áª¨© ⥪áâ
mov ah, [dialog_main_color]
test byte [ebp+dlgtemplate.flags], 2
jz draw_text
mov ah, [warning_main_color]
draw_text:
; ®¯à¥¤¥«ï¥¬ ¤«¨­ã áâப¨
mov esi, [ebx+dlgitemtemplate.data]
draw_text_esi:
test esi, esi
jz .ret2
push eax
push -1
pop ecx
@@:
inc ecx
cmp byte [ecx+esi], 0
jnz @b
; ¢ ecx ¤«¨­  áâப¨
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
; ⥪áâ ¢ë஢­¥­ ¢¯à ¢®
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
push edx
call dlgitem_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
.ret2:
ret
align 4
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
align 4
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
align 4
dlgitem_get_console_ptr:
mov eax, [ebx+dlgitemtemplate.x1]
mov edx, [ebx+dlgitemtemplate.y1]
mov ecx, eax
add eax, [ebp+dlgtemplate.x]
add edx, [ebp+dlgtemplate.y]
jmp get_console_ptr
align 4
draw_h_separator:
; à¨á㥬 £®à¨§®­â «ì­ë© à §¤¥«¨â¥«ì
call dlgitem_get_console_ptr
.scan:
mov al, 0xC7
test ecx, ecx
js @f
mov al, 0xB6
cmp ecx, [ebp+dlgtemplate.width]
jz @f
mov al, 0xC4
@@:
stosb
jz .done
inc ecx
inc edi
cmp ecx, [ebx+dlgitemtemplate.x2]
jb .scan
.done:
ret
align 4
draw_checkbox:
; à¨á㥬 ä« ¦®ª
call dlgitem_get_console_ptr
test byte [ebx+dlgitemtemplate.flags], 4
jz @f
inc eax
mov [cursor_x], eax
mov [cursor_y], edx
@@:
mov ah, [dialog_main_color]
test byte [ebp+dlgtemplate.flags], 2
jz @f
mov ah, [warning_main_color]
@@:
mov al, '['
stosw
mov al, 'x'
test byte [ebx+dlgitemtemplate.flags], 10h
jnz @f
mov al, ' '
@@:
stosw
mov al, ']'
stosw
mov al, ' '
stosw
mov ecx, [ebx+dlgitemtemplate.x2]
sub ecx, [ebx+dlgitemtemplate.x1]
jb .ret
sub ecx, 3
jbe .ret
mov esi, [ebx+dlgitemtemplate.data]
@@:
lodsb
test al, al
jz .correct
stosw
loop @b
ret
.correct:
sub [ebx+dlgitemtemplate.x2], ecx
.ret:
ret
align 4
draw_listbox:
; à¨á㥬 ᯨ᮪
call dlgitem_get_console_ptr
mov edx, [ebx+dlgitemtemplate.data]
mov esi, [edx+8]
mov eax, [ebx+dlgitemtemplate.y2]
sub eax, [ebx+dlgitemtemplate.y1]
push eax
push eax
.0:
test esi, esi
jz .listdone
push esi edi
push edx
or edx, -1
mov ecx, [ebx+dlgitemtemplate.x2]
sub ecx, [ebx+dlgitemtemplate.x1]
inc ecx
xor eax, eax
@@:
inc edx
cmp byte [esi+8+edx], al
jnz @b
@@:
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
; ⥪áâ ¢ë஢­¥­ ¢¯à ¢®
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:
pop edx
cmp esi, [edx]
lea esi, [esi+8+eax]
mov ah, [dialog_selected_list_color]
jz @f
mov ah, [dialog_list_color]
@@:
jecxz .next
@@:
lodsb
test al, al
jz @f
stosw
loop @b
@@:
mov al, ' '
rep stosw
.next:
pop edi esi
add edi, [cur_width]
add edi, [cur_width]
mov esi, [esi]
dec dword [esp]
jns .0
.listdone:
pop eax
; ‹¨­¥©ª  ¯à®ªàã⪨
pop ecx
inc ecx
mov esi, [edx+4]
cmp ecx, esi
jae .noscrollbar
sub ecx, 2
jbe .noscrollbar
mov eax, [edx+12]
mul ecx
div esi
push eax
mov eax, [ebx+dlgitemtemplate.x2]
add eax, [ebp+dlgtemplate.x]
mov edx, [ebx+dlgitemtemplate.y1]
add edx, [ebp+dlgtemplate.y]
call get_console_ptr
pop edx
inc edx
mov al, 0x1E
mov ah, [dialog_scroll_list_color]
mov [edi], ax
add edi, [cur_width]
add edi, [cur_width]
.2:
mov al, 0xB1
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
align 4
listbox_key:
mov edx, [ebx+dlgitemtemplate.data]
cmp al, 0x48
jz .prev
cmp al, 0x50
jz .next
cmp al, 0x47
jz .home
cmp al, 0x4F
jz .end
cmp al, 0x51
jz .pgdn
cmp al, 0x49
jz .pgup
ret
.next:
call .calc_last_line
mov eax, [edx]
cmp dword [eax], 0
jz @f
call .line_next
@@:
mov [edx], eax
ret
.pgdn:
call .calc_last_line
mov eax, [edx]
mov ecx, [ebx+dlgitemtemplate.y2]
sub ecx, [ebx+dlgitemtemplate.y1]
.pgdnl:
cmp dword [eax], 0
jz @f
call .line_next
loop .pgdnl
@@:
mov [edx], eax
ret
.prev:
mov eax, [edx]
cmp dword [eax+4], 0
jz @f
call .line_prev
@@:
mov [edx], eax
ret
.pgup:
mov eax, [edx]
mov ecx, [ebx+dlgitemtemplate.y2]
sub ecx, [ebx+dlgitemtemplate.y1]
; inc ecx
.pgupl:
cmp dword [eax+4], 0
jz @f
call .line_prev
loop .pgupl
@@:
mov [edx], eax
ret
.home:
mov eax, [edx]
@@:
cmp dword [eax+4], 0
jz @f
mov eax, [eax+4]
jmp @b
@@:
mov [edx], eax
mov [edx+8], eax
and dword [edx+12], 0
ret
.end:
mov eax, [edx]
@@:
cmp dword [eax], 0
jz @f
mov eax, [eax]
jmp @b
@@:
mov [edx], eax
mov ecx, [ebx+dlgitemtemplate.y2]
sub ecx, [ebx+dlgitemtemplate.y1]
jz .e1
.e2:
mov eax, [eax+4]
loop .e2
.e1:
mov [edx+8], eax
mov eax, [edx+4]
dec eax
mov [edx+12], eax
ret
.line_prev:
cmp eax, [edx+8]
mov eax, [eax+4]
jnz @f
mov [edx+8], eax
@@:
dec dword [edx+12]
ret
.calc_last_line:
mov esi, [edx+8]
mov ecx, [ebx+dlgitemtemplate.y2]
sub ecx, [ebx+dlgitemtemplate.y1]
jz .clldone
@@:
mov esi, [esi]
test esi, esi
jz @f
loop @b
.clldone:
ret
.line_next:
cmp eax, esi
mov eax, [eax]
jnz @f
push eax
mov eax, [edx+8]
mov eax, [eax]
mov [edx+8], eax
pop eax
mov esi, eax
@@:
inc dword [edx+12]
ret
; 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 ConfirmCancel(void);
; return value: 0 = the user is sure, nonzero = the user wants to continue
ConfirmCancel:
push YesOrNoBtn
push 2
push ConfirmCancelMsg
push 1
push aCancelled
call SayErrTitle
test eax, eax
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[]);
align 16
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