Subversion Repositories Kolibri OS

Rev

Rev 9014 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ; int __stdcall GenericBox(DLGTEMPLATE* dlg, void* DlgProc);
  2. ;       int __stdcall DlgProc(DLGTEMPLATE* dlg, int msg, int param1, int param2);
  3.  
  4. virtual at 0
  5. dlgtemplate:
  6. ; Флаги:
  7. ; бит 0: использовать стандартные цвета диалога
  8. ; бит 1: использовать стандартные цвета предупреждения/ошибки
  9. ; (если любой из этих битов установлен, поля main_color,border_color,header_color
  10. ;  игнорируются)
  11. ; бит 2: не рисовать тень
  12. .flags          dd      ?
  13. .x              dd      ?
  14. .y              dd      ?
  15. .width          dd      ?
  16. .height         dd      ?
  17. .border_size_x  dd      ?
  18. .border_size_y  dd      ?
  19. .title          dd      ?
  20. .main_color     db      ?
  21. .border_color   db      ?
  22. .header_color   db      ?
  23.                 db      ?       ; align
  24. .dataptr        dd      ?       ; used internally, ignored on input
  25. .size = $
  26. end virtual
  27.  
  28. align 16
  29. GenericBox:
  30.         push    [cursor_x]
  31.         push    [cursor_y]
  32.         push    dword [esp+8+8]
  33.         push    dword [esp+8+8]
  34.         call    ShowGenericBox
  35.         test    eax, eax
  36.         jz      @f
  37.         pop     [cursor_y]
  38.         pop     [cursor_x]
  39.         ret
  40. @@:
  41.         pushad
  42. ; message loop
  43. .event:
  44. ;        call    get_event
  45.         push    SF_WAIT_EVENT
  46.         pop     eax
  47.         int     40h
  48.         dec     eax
  49.         jz      .redraw
  50.         dec     eax
  51.         jz      .key
  52.         sub     eax,4
  53.         jz      .mouse
  54.         jmp     exit
  55. .redraw:
  56.         call    draw_window
  57.         jmp     .event
  58. .key:
  59.         mov     al, SF_GET_KEY
  60.         int     40h
  61.         shr     eax, 8
  62.         cmp     al, 0xE0
  63.         jnz     @f
  64.         mov     [bWasE0], 1
  65.         jmp     .event
  66. @@:
  67.         xchg    ah, [bWasE0]
  68.         cmp     al, 0x1D
  69.         jz      .ctrl_down
  70.         cmp     al, 0x9D
  71.         jz      .ctrl_up
  72.         cmp     al, 0x2A
  73.         jz      .lshift_down
  74.         cmp     al, 0xAA
  75.         jz      .lshift_up
  76.         cmp     al, 0x36
  77.         jz      .rshift_down
  78.         cmp     al, 0xB6
  79.         jz      .rshift_up
  80.         cmp     al, 0x38
  81.         jz      .alt_down
  82.         cmp     al, 0xB8
  83.         jz      .alt_up
  84.         mov     ebx, [esp+24h+8]
  85.         mov     ecx, [esp+28h+8]
  86.         push    0
  87.         push    eax
  88.         push    2
  89.         push    ebx
  90.         call    ecx ;DlgProc
  91.         test    eax, eax
  92.         jz      .event
  93.         mov     [esp+28], eax
  94.         jmp     .exit
  95. .ctrl_down:
  96.         test    ah, ah
  97.         jnz     .rctrl_down
  98.         or      [ctrlstate], 4
  99.         jmp     .event
  100. .rctrl_down:
  101.         or      [ctrlstate], 8
  102.         jmp     .event
  103. .ctrl_up:
  104.         test    ah, ah
  105.         jnz     .rctrl_up
  106.         and     [ctrlstate], not 4
  107.         jmp     .event
  108. .rctrl_up:
  109.         and     [ctrlstate], not 8
  110.         jmp     .event
  111. .lshift_down:
  112.         test    ah, ah
  113.         jnz     @f
  114.         or      [ctrlstate], 1
  115. @@:     jmp     .event
  116. .lshift_up:
  117.         test    ah, ah
  118.         jnz     @b
  119.         and     [ctrlstate], not 1
  120.         jmp     @b
  121. .rshift_down:
  122.         or      [ctrlstate], 2
  123.         jmp     .event
  124. .rshift_up:
  125.         and     [ctrlstate], not 2
  126.         jmp     .event
  127. .alt_down:
  128.         test    ah, ah
  129.         jnz     .ralt_down
  130.         or      [ctrlstate], 0x10
  131.         jmp     .event
  132. .ralt_down:
  133.         or      [ctrlstate], 0x20
  134.         jmp     .event
  135. .alt_up:
  136.         test    ah, ah
  137.         jnz     .ralt_up
  138.         and     [ctrlstate], not 0x10
  139.         jmp     .event
  140. .ralt_up:
  141.         and     [ctrlstate], not 0x20
  142.         jmp     .event
  143. align 4
  144. .mouse:
  145.         mov     eax,SF_MOUSE_GET
  146.         mov     ebx,SSF_BUTTON_EXT
  147.         int     0x40
  148.         bt      eax,8 ;left but. down
  149.         jnc     .event
  150.  
  151.         mov     eax,SF_MOUSE_GET
  152.         mov     ebx,SSF_WINDOW_POSITION
  153.         int     0x40
  154.         cmp     ax, word[skinh]
  155.         jl      .event
  156.         sub     ax, word[skinh]
  157.         xor     dx,dx
  158.         mov     bx, font_height
  159.         div     bx
  160.         movzx   edx,ax
  161.         shr     eax,16
  162.         sub     eax, 5 ;window border
  163.  
  164.         push    edx
  165.         xor     dx,dx
  166.         mov     bx, font_width
  167.         div     bx
  168.         movzx   eax,ax
  169.         pop     edx
  170.  
  171.         mov     ebx, [esp+24h+8] ;DLGTEMPLATE* dlg
  172.         cmp     dword[ebx+dlgtemplate.size], 0
  173.         jne     .event ;если диалоговое окно не стандартное (список значений)
  174.         cmp     edx, [ebx+dlgtemplate.y]
  175.         jl      .event
  176.         cmp     eax, [ebx+dlgtemplate.x]
  177.         jl      .event
  178.         sub     edx, [ebx+dlgtemplate.y]
  179.         sub     eax, [ebx+dlgtemplate.x]
  180.         cmp     edx, [ebx+dlgtemplate.height]
  181.         jge     .event
  182.         cmp     eax, [ebx+dlgtemplate.width]
  183.         jge     .event
  184.  
  185.         add     ebx, dlgtemplate.size+12
  186.         mov     ecx, [ebx-4]
  187.         or      ecx, ecx
  188.         jz      .event
  189.  
  190.         push    ebx ecx
  191. .m_loop:
  192.         cmp     [ebx+dlgitemtemplate.type], 2 ;button
  193.         je      .m_comp
  194.         cmp     [ebx+dlgitemtemplate.type], 3 ;edit
  195.         je      .m_comp
  196.         ;cmp     [ebx+dlgitemtemplate.type], 5 ;check
  197.         ;je      .m_comp
  198.         jmp     .m_next
  199. align 4
  200. .m_comp:
  201.         cmp     [ebx+dlgitemtemplate.x1], eax
  202.         jg      .m_next
  203.         cmp     [ebx+dlgitemtemplate.y1], edx
  204.         jg      .m_next
  205.         cmp     [ebx+dlgitemtemplate.x2], eax
  206.         jl      .m_next
  207.         cmp     [ebx+dlgitemtemplate.y2], edx
  208.         jl      .m_next
  209.  
  210.         cmp     [ebx+dlgitemtemplate.type], 2 ;button
  211.         jne      @f
  212.         mov     [esp+28+8], ebx ;save to eax
  213.         pop     ecx ebx
  214.         jmp     .exit
  215. @@:
  216.         mov     eax, [ebx+dlgitemtemplate.flags]
  217.         and     eax, 4
  218.         jnz     .m_old_focus
  219.         mov     eax, ebx
  220.         jmp     .m_new_focus
  221. align 4
  222. .m_next:
  223.         add     ebx, sizeof.DlgBtn
  224.         loop    .m_loop
  225. .m_old_focus:
  226.         pop     ecx ebx
  227.         jmp     .event
  228. align 4
  229. .m_new_focus:
  230.         pop     ecx ebx
  231.         call    DlgClearFocus
  232.         or      dword[eax+dlgitemtemplate.flags], 4
  233.  
  234.         sub     ebx, dlgtemplate.size+12
  235.         push    ebp
  236.         mov     ebp, ebx
  237.         call    ManagerDlgProc.dodraw
  238.         pop     ebp
  239.         call    draw_image
  240.         jmp     .event
  241. align 4
  242. .exit:
  243.         popad
  244.         push    eax
  245.         push    0
  246.         push    dword [esp+12+8]
  247.         call    HideGenericBox
  248.         pop     eax
  249.         pop     [cursor_y]
  250.         pop     [cursor_x]
  251.         pushad
  252.         call    draw_image
  253.         popad
  254.         ret     8
  255.  
  256. ;input:
  257. ; ebx - pointer to first item
  258. ; ecx - count items
  259. align 4
  260. DlgClearFocus:
  261.         push    ebx ecx
  262. @@:
  263.         and     byte [ebx+dlgitemtemplate.flags], not 4
  264.         add     ebx, sizeof.DlgBtn
  265.         loop    @b
  266.         pop     ecx ebx
  267.         ret
  268.  
  269. ; int __stdcall ShowGenericBox(DLGTEMPLATE* dlg, void* DlgProc);
  270. align 16
  271. ShowGenericBox:
  272.         pushad
  273.         mov     ebx, [esp+20h+4]
  274. ; center window if required
  275.         push    [ebx+dlgtemplate.x]
  276.         push    [ebx+dlgtemplate.y]
  277.         cmp     [ebx+dlgtemplate.x], -1
  278.         jnz     @f
  279.         mov     eax, [cur_width]
  280.         sub     eax, [ebx+dlgtemplate.width]
  281.         shr     eax, 1
  282.         mov     [ebx+dlgtemplate.x], eax
  283. @@:
  284.         cmp     [ebx+dlgtemplate.y], -1
  285.         jnz     @f
  286.         mov     eax, [cur_height]
  287.         sub     eax, [ebx+dlgtemplate.height]
  288.         shr     eax, 1
  289.         mov     [ebx+dlgtemplate.y], eax
  290. @@:
  291. ; some checks
  292.         mov     eax, [ebx+dlgtemplate.x]
  293.         cmp     eax, 1
  294.         jl      .sizeerr
  295.         add     eax, [ebx+dlgtemplate.width]
  296.         cmp     eax, [cur_width]
  297.         jge     .sizeerr
  298.         mov     eax, [ebx+dlgtemplate.y]
  299.         cmp     eax, 1
  300.         jl      .sizeerr
  301.         add     eax, [ebx+dlgtemplate.height]
  302.         cmp     eax, [cur_height]
  303.         jge     .sizeerr
  304.         cmp     [ebx+dlgtemplate.border_size_x], 1
  305.         jl      .sizeerr
  306.         cmp     [ebx+dlgtemplate.border_size_y], 1
  307.         jge     .sizeok
  308. .sizeerr:
  309.         pop     [ebx+dlgtemplate.y]
  310.         pop     [ebx+dlgtemplate.x]
  311.         popad
  312.         or      eax, -1
  313.         ret     8
  314. .sizeok:
  315. ; set color if required
  316.         test    byte [ebx+dlgtemplate.flags], 1
  317.         jz      @f
  318.         mov     edi, dialog_colors
  319.         jmp     .setcolor
  320. @@:
  321.         test    byte [ebx+dlgtemplate.flags], 2
  322.         jz      @f
  323.         mov     edi, warning_colors
  324. .setcolor:
  325.         mov     al, [edi + dialog_main_color-dialog_colors]
  326.         mov     [ebx+dlgtemplate.main_color], al
  327.         mov     al, [edi + dialog_border_color-dialog_colors]
  328.         mov     [ebx+dlgtemplate.border_color], al
  329.         mov     al, [edi + dialog_header_color-dialog_colors]
  330.         mov     [ebx+dlgtemplate.header_color], al
  331. @@:
  332. ; allocate memory for data under dialog
  333. ; for 'No memory' dialog use static data area
  334.         mov     eax, nomem_dlgsavearea
  335.         cmp     ebx, nomem_dlgdata
  336.         jz      .allocated
  337.         mov     eax, [ebx+dlgtemplate.width]
  338.         add     eax, [ebx+dlgtemplate.border_size_x]
  339.         add     eax, [ebx+dlgtemplate.border_size_x]
  340.         inc     eax
  341.         inc     eax
  342.         mov     edx, [ebx+dlgtemplate.height]
  343.         add     edx, [ebx+dlgtemplate.border_size_y]
  344.         add     edx, [ebx+dlgtemplate.border_size_y]
  345.         inc     edx
  346.         mul     edx
  347.         lea     ecx, [eax*2+8]
  348.         call    xpgalloc
  349.         test    eax, eax
  350.         jnz     @f
  351.         pop     [ebx+dlgtemplate.y]
  352.         pop     [ebx+dlgtemplate.x]
  353.         popad
  354.         or      eax, -1
  355.         ret     8
  356. @@:
  357. .allocated:
  358.         mov     [ebx+dlgtemplate.dataptr], eax
  359.         pop     dword [eax+4]
  360.         pop     dword [eax]
  361.         lea     ebp, [eax+8]
  362. ; save data
  363.         mov     eax, [ebx+dlgtemplate.y]
  364.         add     eax, [ebx+dlgtemplate.height]
  365.         add     eax, [ebx+dlgtemplate.border_size_y]
  366.         inc     eax
  367.         push    eax
  368.         mov     eax, [ebx+dlgtemplate.x]
  369.         add     eax, [ebx+dlgtemplate.width]
  370.         add     eax, [ebx+dlgtemplate.border_size_x]
  371.         inc     eax
  372.         inc     eax
  373.         push    eax
  374.         mov     eax, [ebx+dlgtemplate.y]
  375.         sub     eax, [ebx+dlgtemplate.border_size_y]
  376.         push    eax
  377.         mov     eax, [ebx+dlgtemplate.x]
  378.         sub     eax, [ebx+dlgtemplate.border_size_x]
  379.         push    eax
  380.         call    save_console_data
  381. ; draw shadow
  382.         test    byte [ebx+dlgtemplate.flags], 4
  383.         jnz     .noshadow
  384.         call    draw_dialog_shadow
  385. .noshadow:
  386.         popad
  387.         push    dword [esp+8]
  388.         push    dword [esp+8]
  389.         call    DrawGenericBox
  390.         xor     eax, eax
  391.         ret     8
  392.  
  393. draw_dialog_shadow:
  394.         mov     eax, [ebx+dlgtemplate.x]
  395.         sub     eax, [ebx+dlgtemplate.border_size_x]
  396.         ja      @f
  397.         xor     eax, eax
  398. @@:
  399.         inc     eax
  400.         inc     eax
  401.         mov     edx, [ebx+dlgtemplate.y]
  402.         sub     edx, [ebx+dlgtemplate.border_size_y]
  403.         ja      @f
  404.         xor     edx, edx
  405. @@:
  406.         inc     edx
  407.         call    get_console_ptr
  408.         mov     ecx, [ebx+dlgtemplate.y]
  409.         add     ecx, [ebx+dlgtemplate.height]
  410.         add     ecx, [ebx+dlgtemplate.border_size_y]
  411.         inc     ecx
  412.         cmp     ecx, [cur_height]
  413.         jb      @f
  414.         mov     ecx, [cur_height]
  415. @@:
  416.         sub     ecx, edx
  417.         mov     edx, ecx
  418.         mov     ecx, [ebx+dlgtemplate.x]
  419.         add     ecx, [ebx+dlgtemplate.width]
  420.         add     ecx, [ebx+dlgtemplate.border_size_x]
  421.         inc     ecx
  422.         inc     ecx
  423.         cmp     ecx, [cur_width]
  424.         jb      @f
  425.         mov     ecx, [cur_width]
  426. @@:
  427.         sub     ecx, eax
  428.         mov     eax, ecx
  429. .shadow_loop:
  430.         mov     ecx, eax
  431.         push    edi
  432. .sl1:
  433.         inc     edi
  434.         test    byte [edi], 0x0F
  435.         jnz     @f
  436.         or      byte [edi], 8
  437. @@:
  438.         and     byte [edi], 0x0F
  439.         inc     edi
  440.         loop    .sl1
  441.         pop     edi
  442.         add     edi, [cur_width]
  443.         add     edi, [cur_width]
  444.         dec     edx
  445.         jnz     .shadow_loop
  446.         ret
  447.  
  448. ; void __stdcall DrawGenericBox(DLGDATA* dlg, void* DlgProc)
  449. align 16
  450. DrawGenericBox:
  451.         pushad
  452.         mov     ebx, [esp+24h]
  453. ; draw area background
  454.         mov     eax, [ebx+dlgtemplate.x]
  455.         sub     eax, [ebx+dlgtemplate.border_size_x]
  456.         ja      @f
  457.         xor     eax, eax
  458. @@:
  459.         mov     edx, [ebx+dlgtemplate.y]
  460.         sub     edx, [ebx+dlgtemplate.border_size_y]
  461.         ja      @f
  462.         xor     edx, edx
  463. @@:
  464.         call    get_console_ptr
  465.         mov     ecx, [ebx+dlgtemplate.x]
  466.         add     ecx, [ebx+dlgtemplate.width]
  467.         add     ecx, [ebx+dlgtemplate.border_size_x]
  468.         cmp     ecx, [cur_width]
  469.         jb      @f
  470.         mov     ecx, [cur_width]
  471. @@:
  472.         sub     ecx, eax
  473.         mov     esi, ecx
  474.         mov     ecx, [ebx+dlgtemplate.y]
  475.         add     ecx, [ebx+dlgtemplate.height]
  476.         add     ecx, [ebx+dlgtemplate.border_size_y]
  477.         cmp     ecx, [cur_height]
  478.         jb      @f
  479.         mov     ecx, [cur_height]
  480. @@:
  481.         sub     ecx, edx
  482.         mov     edx, ecx
  483.         mov     al, ' '
  484.         mov     ah, [ebx+dlgtemplate.border_color]
  485. .1:
  486.         mov     ecx, esi
  487.         push    edi
  488.         rep     stosw
  489.         pop     edi
  490.         add     edi, [cur_width]
  491.         add     edi, [cur_width]
  492.         dec     edx
  493.         jnz     .1
  494. ; draw border
  495.         mov     eax, [ebx+dlgtemplate.x]
  496.         dec     eax
  497.         mov     edx, [ebx+dlgtemplate.y]
  498.         dec     edx
  499.         call    get_console_ptr
  500.         mov     edx, [ebx+dlgtemplate.height]
  501.         inc     edx
  502.         inc     edx
  503.         mov     ah, [ebx+dlgtemplate.border_color]
  504.         push    ebx
  505.         mov     ebx, [ebx+dlgtemplate.width]
  506.         inc     ebx
  507.         inc     ebx
  508.         call    draw_border
  509.         pop     ebx
  510. ; draw header
  511.         mov     esi, [ebx+dlgtemplate.title]
  512.         test    esi, esi
  513.         jz      .noheader
  514.         cmp     byte [esi], 0
  515.         jz      .noheader
  516.         push    esi
  517. @@:     lodsb
  518.         test    al, al
  519.         jnz     @b
  520.         mov     eax, esi
  521.         pop     esi
  522.         sub     eax, esi
  523.         inc     eax     ; eax = длина заголовка + 2
  524.         mov     ecx, [ebx+dlgtemplate.width]
  525.         cmp     eax, ecx
  526.         jbe     .fullhea
  527.         sub     ecx, 5
  528.         jb      .noheader
  529.         xor     edx, edx
  530.         jmp     .drawhea
  531. .fullhea:
  532.         mov     edx, ecx
  533.         sub     edx, eax
  534.         shr     edx, 1
  535. .drawhea:
  536.         mov     eax, [ebx+dlgtemplate.x]
  537.         add     eax, edx
  538.         mov     edx, [ebx+dlgtemplate.y]
  539.         dec     edx
  540.         call    get_console_ptr
  541.         mov     ah, [ebx+dlgtemplate.header_color]
  542.         mov     al, ' '
  543.         stosw
  544. .2:
  545.         dec     ecx
  546.         jz      .3
  547.         lodsb
  548.         test    al, al
  549.         jz      .4
  550.         stosw
  551.         jmp     .2
  552. .3:
  553.         mov     al, '.'
  554.         stosw
  555.         stosw
  556.         stosw
  557. .4:
  558.         mov     al, ' '
  559.         stosw
  560. .noheader:
  561. ; draw window background
  562.         mov     eax, [ebx+dlgtemplate.x]
  563.         mov     edx, [ebx+dlgtemplate.y]
  564.         call    get_console_ptr
  565.         mov     ah, [ebx+dlgtemplate.main_color]
  566.         mov     al, ' '
  567.         mov     edx, [ebx+dlgtemplate.height]
  568. @@:
  569.         mov     ecx, [ebx+dlgtemplate.width]
  570.         push    edi
  571.         rep     stosw
  572.         pop     edi
  573.         add     edi, [cur_width]
  574.         add     edi, [cur_width]
  575.         dec     edx
  576.         jnz     @b
  577. ; send redraw message
  578.         mov     eax, [esp+28h]
  579.         push    0
  580.         push    0
  581.         push    1
  582.         push    ebx
  583.         call    eax
  584.         call    draw_image
  585.         popad
  586.         ret     8
  587.  
  588. ; void __stdcall HideGenericBox(DLGTEMPLATE* dlg, int bRedrawWindow);
  589. align 16
  590. HideGenericBox:
  591. ; void __stdcall HideDialogBox(DLGDATA* dlg, int bRedrawWindow);
  592. HideDialogBox:
  593.         pushad
  594.         mov     ebx, [esp+24h]
  595.         mov     ebp, [ebx+dlgtemplate.dataptr]
  596.         add     ebp, 8
  597. ; restore data
  598.         mov     eax, [ebx+dlgtemplate.y]
  599.         add     eax, [ebx+dlgtemplate.height]
  600.         add     eax, [ebx+dlgtemplate.border_size_y]
  601.         inc     eax
  602.         push    eax
  603.         mov     eax, [ebx+dlgtemplate.x]
  604.         add     eax, [ebx+dlgtemplate.width]
  605.         add     eax, [ebx+dlgtemplate.border_size_x]
  606.         inc     eax
  607.         inc     eax
  608.         push    eax
  609.         mov     eax, [ebx+dlgtemplate.y]
  610.         sub     eax, [ebx+dlgtemplate.border_size_y]
  611.         push    eax
  612.         mov     eax, [ebx+dlgtemplate.x]
  613.         sub     eax, [ebx+dlgtemplate.border_size_x]
  614.         push    eax
  615.         call    restore_console_data
  616.         call    draw_keybar
  617.         lea     ecx, [ebp-8]
  618.         push    dword [ecx]
  619.         push    dword [ecx+4]
  620.         pop     [ebx+dlgtemplate.y]
  621.         pop     [ebx+dlgtemplate.x]
  622.         cmp     ebx, nomem_dlgdata
  623.         jz      @f
  624.         call    pgfree
  625. @@:
  626.         or      [cursor_x], -1
  627.         or      [cursor_y], -1
  628.         cmp     dword [esp+28h], 0
  629.         jz      @f
  630.         call    draw_image
  631. @@:
  632.         popad
  633.         ret     8
  634.  
  635. save_console_data:
  636.         cmp     dword [esp+4], 0
  637.         jge     @f
  638.         and     dword [esp+4], 0
  639. @@:
  640.         cmp     dword [esp+8], 0
  641.         jge     @f
  642.         and     dword [esp+8], 0
  643. @@:
  644.         mov     eax, [esp+12]
  645.         cmp     eax, [cur_width]
  646.         jbe     @f
  647.         mov     eax, [cur_width]
  648. @@:
  649.         sub     eax, [esp+4]
  650.         ja      @f
  651.         ret     16
  652. @@:
  653.         mov     [esp+12], eax
  654.         mov     eax, [esp+16]
  655.         cmp     eax, [cur_height]
  656.         jbe     @f
  657.         mov     eax, [cur_height]
  658. @@:
  659.         sub     eax, [esp+8]
  660.         ja      @f
  661.         ret     16
  662. @@:
  663.         mov     [esp+16], eax
  664.         mov     eax, [esp+4]
  665.         mov     edx, [esp+8]
  666.         call    get_console_ptr
  667.         mov     esi, edi
  668.         mov     edi, ebp
  669. .l:
  670.         mov     ecx, [esp+12]
  671.         push    esi
  672.         shr     ecx, 1
  673.         rep     movsd
  674.         adc     ecx, ecx
  675.         rep     movsw
  676.         pop     esi
  677.         add     esi, [cur_width]
  678.         add     esi, [cur_width]
  679.         dec     dword [esp+16]
  680.         jnz     .l
  681.         ret     16
  682.  
  683. restore_console_data:
  684.         cmp     dword [esp+4], 0
  685.         jge     @f
  686.         and     dword [esp+4], 0
  687. @@:
  688.         cmp     dword [esp+8], 0
  689.         jge     @f
  690.         and     dword [esp+8], 0
  691. @@:
  692.         mov     eax, [esp+12]
  693.         cmp     eax, [cur_width]
  694.         jbe     @f
  695.         mov     eax, [cur_width]
  696. @@:
  697.         sub     eax, [esp+4]
  698.         ja      @f
  699.         ret     16
  700. @@:
  701.         mov     [esp+12], eax
  702.         mov     eax, [esp+16]
  703.         cmp     eax, [cur_height]
  704.         jbe     @f
  705.         mov     eax, [cur_height]
  706. @@:
  707.         sub     eax, [esp+8]
  708.         ja      @f
  709.         ret     16
  710. @@:
  711.         mov     [esp+16], eax
  712.         mov     eax, [esp+4]
  713.         mov     edx, [esp+8]
  714.         call    get_console_ptr
  715.         mov     esi, ebp
  716. .l:
  717.         mov     ecx, [esp+12]
  718.         push    edi
  719.         shr     ecx, 1
  720.         rep     movsd
  721.         adc     ecx, ecx
  722.         rep     movsw
  723.         pop     edi
  724.         add     edi, [cur_width]
  725.         add     edi, [cur_width]
  726.         dec     dword [esp+16]
  727.         jnz     .l
  728.         ret     16
  729.  
  730. ; int __stdcall menu(void* variants, const char* title, unsigned flags);
  731. ; variants указывает на текущий элемент в двусвязном линейном списке
  732. align 16
  733. menu:
  734.         pop     eax
  735.         push    [cur_height]
  736.         push    [cur_width]
  737.         push    0
  738.         push    0
  739.         push    eax
  740.  
  741. ; int __stdcall menu_centered_in(unsigned left, unsigned top, unsigned width, unsigned height,
  742. ;       void* variants, const char* title, unsigned flags);
  743. menu_centered_in:
  744.         pushad
  745.         mov     ecx, 60
  746. ; 40 bytes for dlgtemplate + additional:
  747. ; +40: dd cur_variant   - [???]
  748. ; +44: dd num_variants  - сколько элементов влазит в окно
  749. ; +48: dd begin_variant - [dd ..,..,???]
  750. ; +52: dd end_variant   - [dd ..,..,???]
  751. ; +56: dd cur_variant_idx - ???
  752.         call    xpgalloc
  753.         test    eax, eax
  754.         jnz     @f
  755. .ret_bad:
  756.         popad
  757.         or      eax, -1
  758.         ret     28
  759. @@:
  760.         mov     ebx, eax
  761.         mov     eax, 1
  762.         test    byte [esp+20h+28], 1 ;unsigned flags
  763.         jz      @f
  764.         mov     al, 3
  765. @@:
  766.         mov     [ebx+dlgtemplate.border_size_x], eax
  767.         inc     eax
  768.         shr     eax, 1
  769.         mov     [ebx+dlgtemplate.border_size_y], eax
  770. ; Находим ширину и высоту окна
  771.         xor     eax, eax
  772.         xor     ecx, ecx
  773.         mov     esi, [esp+20h+20] ;void* variants
  774.         mov     [ebx+40], esi
  775.         mov     dword [ebx+56], eax
  776. @@:
  777.         cmp     dword [esi+4], eax
  778.         jz      .find_width
  779.         mov     esi, [esi+4]
  780.         inc     dword [ebx+56]
  781.         jmp     @b
  782. .find_width:
  783.         mov     [ebx+48], esi
  784.         add     esi, 8
  785.         push    esi
  786.         xor     edx, edx
  787. .fw1:
  788.         cmp     byte [esi], '&'
  789.         jnz     @f
  790.         mov     dl, 1
  791. @@:
  792.         inc     esi
  793.         cmp     byte [esi-1], 0
  794.         jnz     .fw1
  795.         sub     esi, [esp]
  796.         sub     esi, edx
  797.         dec     esi
  798.         cmp     eax, esi
  799.         ja      @f
  800.         mov     eax, esi
  801. @@:
  802.         inc     ecx
  803.         pop     esi
  804.         mov     esi, [esi-8]
  805.         test    esi, esi
  806.         jnz     .find_width
  807.         add     eax, 3
  808.         add     eax, [ebx+dlgtemplate.border_size_x]
  809.         add     eax, [ebx+dlgtemplate.border_size_x]
  810.         cmp     eax, [cur_width]
  811.         jb      @f
  812.         mov     eax, [cur_width]
  813. @@:
  814.         sub     eax, [ebx+dlgtemplate.border_size_x]
  815.         sub     eax, [ebx+dlgtemplate.border_size_x]
  816.         mov     [ebx+dlgtemplate.width], eax
  817.         mov     [ebx+dlgtemplate.height], ecx
  818.         mov     [ebx+44], ecx
  819.         sub     eax, [esp+20h+12]
  820.         neg     eax
  821.         sar     eax, 1
  822.         add     eax, [esp+20h+4]
  823.         cmp     eax, [ebx+dlgtemplate.border_size_x]
  824.         jge     @f
  825.         mov     eax, [ebx+dlgtemplate.border_size_x]
  826. @@:
  827.         push    eax
  828.         add     eax, [ebx+dlgtemplate.width]
  829.         add     eax, [ebx+dlgtemplate.border_size_x]
  830.         cmp     eax, [cur_width]
  831.         jbe     @f
  832.         pop     eax
  833.         mov     eax, [cur_width]
  834.         sub     eax, [ebx+dlgtemplate.width]
  835.         sub     eax, [ebx+dlgtemplate.border_size_x]
  836.         push    eax
  837. @@:
  838.         pop     [ebx+dlgtemplate.x]
  839.         sub     ecx, [esp+20h+16]
  840.         neg     ecx
  841.         sar     ecx, 1
  842.         add     ecx, [esp+20h+8]
  843.         cmp     ecx, [ebx+dlgtemplate.border_size_y]
  844.         jge     @f
  845.         mov     ecx, [ebx+dlgtemplate.border_size_y]
  846. @@:
  847.         push    ecx
  848.         add     ecx, [ebx+dlgtemplate.height]
  849.         add     ecx, [ebx+dlgtemplate.border_size_y]
  850.         cmp     ecx, [cur_height]
  851.         jbe     @f
  852.         pop     ecx
  853.         mov     ecx, [cur_height]
  854.         sub     ecx, [ebx+dlgtemplate.height]
  855.         sub     ecx, [ebx+dlgtemplate.border_size_y]
  856.         push    ecx
  857. @@:
  858.         pop     [ebx+dlgtemplate.y]
  859.         mov     eax, [cur_height]
  860.         sub     eax, 6
  861.         cmp     [ebx+dlgtemplate.height], eax
  862.         jbe     .small_height
  863.         mov     [ebx+dlgtemplate.height], eax
  864.         mov     [ebx+dlgtemplate.y], 3
  865. .small_height:
  866.         mov     ecx, [ebx+dlgtemplate.height]
  867.         mov     eax, [ebx+40]
  868.         mov     [ebx+48], eax
  869.         dec     ecx
  870.         jz      .skip
  871.         push    ecx
  872. @@:
  873.         cmp     dword [eax+4], 0
  874.         jz      @f
  875.         mov     eax, [eax+4]
  876.         loop    @b
  877. @@:
  878.         mov     [ebx+48], eax
  879.         pop     ecx
  880. .loop:
  881.         mov     eax, [eax]
  882.         loop    .loop
  883. .skip:
  884.         mov     [ebx+52], eax
  885.         mov     eax, [esp+20h+24]
  886.         mov     [ebx+dlgtemplate.title], eax
  887.         mov     al, [menu_normal_color]
  888.         mov     [ebx+dlgtemplate.main_color], al
  889.         mov     al, [menu_border_color]
  890.         mov     [ebx+dlgtemplate.border_color], al
  891.         mov     al, [menu_header_color]
  892.         mov     [ebx+dlgtemplate.header_color], al
  893.         push    MenuDlgProc
  894.         push    ebx
  895.         call    GenericBox
  896.         mov     [esp+28], eax
  897.         mov     ecx, ebx
  898.         call    pgfree
  899.         popad
  900.         ret     28
  901.  
  902. align 16
  903. MenuDlgProc:
  904.         mov     eax, [esp+8]
  905.         cmp     al, 1
  906.         jz      .draw
  907.         cmp     al, 2
  908.         jz      .key
  909.         ret     16
  910. .draw:
  911.         call    .dodraw
  912.         ret     16
  913. .prev:
  914.         mov     eax, [ebx+40]
  915.         cmp     dword [eax+4], 0
  916.         jz      .end
  917.         call    .line_prev
  918. .posret:
  919.         mov     [ebx+40], eax
  920. .redraw:
  921.         call    .dodraw
  922.         call    draw_image
  923.         xor     eax, eax
  924.         ret     16
  925. .next:
  926.         mov     eax, [ebx+40]
  927.         cmp     dword [eax], 0
  928.         jz      .home
  929.         call    .line_next
  930.         jmp     .posret
  931. .pgdn:
  932.         mov     eax, [ebx+40]
  933.         mov     ecx, [ebx+dlgtemplate.height]
  934. .pgdnl:
  935.         cmp     dword [eax], 0
  936.         jz      .posret
  937.         call    .line_next
  938.         loop    .pgdnl
  939.         jmp     .posret
  940. .key:
  941.         mov     al, [esp+12]
  942.         cmp     al, 0x48
  943.         jz      .prev
  944.         cmp     al, 0x4B
  945.         jz      .prev
  946.         cmp     al, 0x4D
  947.         jz      .next
  948.         cmp     al, 0x50
  949.         jz      .next
  950.         cmp     al, 0x1C
  951.         jz      .enter
  952.         cmp     al, 1
  953.         jz      .esc
  954.         cmp     al, 0x47
  955.         jz      .home
  956.         cmp     al, 0x4F
  957.         jz      .end
  958.         cmp     al, 0x51
  959.         jz      .pgdn
  960.         cmp     al, 0x49
  961.         jz      .pgup
  962.         cmp     al, 0x52
  963.         jz      .ins
  964.         cmp     al, 0x53
  965.         jz      .del
  966.         mov     edx, [ebx+40]
  967. @@:
  968.         cmp     dword [edx+4], 0
  969.         jz      @f
  970.         mov     edx, [edx+4]
  971.         jmp     @b
  972. @@:
  973. .l:
  974.         lea     esi, [edx+7]
  975. @@:
  976.         inc     esi
  977.         cmp     byte [esi], 0
  978.         jz      .n
  979.         cmp     byte [esi], '&'
  980.         jnz     @b
  981.         movzx   ecx, byte [esi+1]
  982.         cmp     [ascii2scan+ecx], al
  983.         jnz     .n
  984.         mov     eax, edx
  985.         ret     16
  986. .n:
  987.         mov     edx, [edx]
  988.         test    edx, edx
  989.         jnz     .l
  990. .ret:
  991.         xor     eax, eax
  992.         ret     16
  993. .pgup:
  994.         mov     eax, [ebx+40]
  995.         mov     ecx, [ebx+dlgtemplate.height]
  996. .pgupl:
  997.         cmp     dword [eax+4], 0
  998.         jz      .posret
  999.         call    .line_prev
  1000.         loop    .pgupl
  1001.         jmp     .posret
  1002. .home:
  1003.         mov     eax, [ebx+40]
  1004. @@:
  1005.         cmp     dword [eax+4], 0
  1006.         jz      @f
  1007.         mov     eax, [eax+4]
  1008.         jmp     @b
  1009. @@:
  1010.         mov     [ebx+48], eax
  1011.         push    eax
  1012.         mov     ecx, [ebx+dlgtemplate.height]
  1013.         dec     ecx
  1014.         jz      .h1
  1015. .h2:
  1016.         mov     eax, [eax]
  1017.         loop    .h2
  1018. .h1:
  1019.         mov     [ebx+52], eax
  1020.         pop     eax
  1021.         and     dword [ebx+56], 0
  1022.         jmp     .posret
  1023. .end:
  1024.         mov     eax, [ebx+40]
  1025. @@:
  1026.         cmp     dword [eax], 0
  1027.         jz      @f
  1028.         mov     eax, [eax]
  1029.         jmp     @b
  1030. @@:
  1031.         mov     [ebx+52], eax
  1032.         push    eax
  1033.         mov     ecx, [ebx+dlgtemplate.height]
  1034.         dec     ecx
  1035.         jz      .e1
  1036. .e2:
  1037.         mov     eax, [eax+4]
  1038.         loop    .e2
  1039. .e1:
  1040.         mov     [ebx+48], eax
  1041.         mov     eax, [ebx+44]
  1042.         dec     eax
  1043.         mov     [ebx+56], eax
  1044.         pop     eax
  1045.         jmp     .posret
  1046. .esc:
  1047.         or      eax, -1
  1048.         ret     16
  1049. .enter:
  1050.         mov     eax, [ebx+40]
  1051.         ret     16
  1052. .ins:
  1053.         push    5
  1054.         pop     edx
  1055.         jmp     @f
  1056. .del:
  1057.         push    4
  1058.         pop     edx
  1059. @@:
  1060.         mov     eax, [ebx+40]
  1061.         cmp     byte [eax+8], '/'
  1062.         jnz     @f
  1063.         cmp     word [eax+9], 'cd'
  1064.         jnz     @f
  1065.         movzx   ecx, byte [eax+11]
  1066.         sub     ecx, '0'
  1067.         push    SF_CD
  1068.         pop     eax
  1069.         mov     ebx, edx
  1070.         int     40h
  1071. @@:
  1072.         xor     eax, eax
  1073.         ret     16
  1074.  
  1075. .line_prev:
  1076.         cmp     eax, [ebx+48]
  1077.         jnz     @f
  1078.         mov     edx, [ebx+48]
  1079.         mov     edx, [edx+4]
  1080.         mov     [ebx+48], edx
  1081.         mov     edx, [ebx+52]
  1082.         mov     edx, [edx+4]
  1083.         mov     [ebx+52], edx
  1084. @@:
  1085.         mov     eax, [eax+4]
  1086.         dec     dword [ebx+56]
  1087.         ret
  1088. .line_next:
  1089.         cmp     eax, [ebx+52]
  1090.         jnz     @f
  1091.         mov     edx, [ebx+48]
  1092.         mov     edx, [edx]
  1093.         mov     [ebx+48], edx
  1094.         mov     edx, [ebx+52]
  1095.         mov     edx, [edx]
  1096.         mov     [ebx+52], edx
  1097. @@:
  1098.         mov     eax, [eax]
  1099.         inc     dword [ebx+56]
  1100.         ret
  1101.  
  1102. .dodraw:
  1103.         mov     eax, [ebx+dlgtemplate.x]
  1104.         mov     edx, [ebx+dlgtemplate.y]
  1105.         call    get_console_ptr
  1106.         mov     esi, [ebx+48]
  1107. .0:
  1108.         xor     edx, edx
  1109.         mov     ah, [menu_selected_color]
  1110.         cmp     esi, [ebx+40]
  1111.         jz      @f
  1112.         mov     ah, [menu_normal_color]
  1113. @@:
  1114.         push    edi
  1115.         mov     ecx, [ebx+dlgtemplate.width]
  1116.         mov     al, ' '
  1117.         stosw
  1118.         dec     ecx
  1119.         stosw
  1120.         dec     ecx
  1121.         dec     ecx
  1122.         push    esi
  1123.         add     esi, 8
  1124. @@:
  1125.         lodsb
  1126.         test    al, al
  1127.         jz      @f
  1128.         cmp     al, '&'
  1129.         jnz     .noamp
  1130.         test    dl, dl
  1131.         jnz     .noamp
  1132.         mov     dl, 1
  1133.         lodsb
  1134.         push    eax
  1135.         mov     ah, [menu_selected_highlight_color]
  1136.         push    ecx
  1137.         mov     ecx, [esp+8]
  1138.         cmp     ecx, [ebx+40]
  1139.         pop     ecx
  1140.         jz      .amp1
  1141.         mov     ah, [menu_highlight_color]
  1142. .amp1:
  1143.         stosw
  1144.         pop     eax
  1145.         jmp     .amp2
  1146. .noamp:
  1147.         stosw
  1148. .amp2:
  1149.         loop    @b
  1150.         mov     al, ' '
  1151.         cmp     byte [esi], 0
  1152.         jnz     .1
  1153.         lodsb
  1154.         jmp     .1
  1155. @@:
  1156.         mov     al, ' '
  1157. .1:
  1158.         stosw
  1159.         mov     al, ' '
  1160.         rep     stosw
  1161.         pop     esi edi
  1162.         add     edi, [cur_width]
  1163.         add     edi, [cur_width]
  1164.         cmp     esi, [ebx+52]
  1165.         jz      @f
  1166.         mov     esi, [esi]
  1167.         test    esi, esi
  1168.         jnz     .0
  1169. @@:
  1170. ; Линейка прокрутки
  1171.         mov     ecx, [ebx+dlgtemplate.height]
  1172.         cmp     ecx, [ebx+44]
  1173.         jz      .noscrollbar
  1174.         sub     ecx, 2
  1175.         jbe     .noscrollbar
  1176.         mov     eax, [ebx+56]
  1177.         mul     ecx
  1178.         div     dword [ebx+44]
  1179.         push    eax
  1180.         mov     eax, [ebx+dlgtemplate.x]
  1181.         add     eax, [ebx+dlgtemplate.width]
  1182.         mov     edx, [ebx+dlgtemplate.y]
  1183.         call    get_console_ptr
  1184.         pop     edx
  1185.         inc     edx
  1186.         mov     al, 0x1E
  1187.         mov     ah, [menu_scrollbar_color]
  1188.         mov     [edi], ax
  1189.         add     edi, [cur_width]
  1190.         add     edi, [cur_width]
  1191. .2:
  1192.         mov     al, 0xB2
  1193.         dec     edx
  1194.         jz      @f
  1195.         mov     al, 0xB0
  1196. @@:
  1197.         mov     [edi], ax
  1198.         add     edi, [cur_width]
  1199.         add     edi, [cur_width]
  1200.         loop    .2
  1201.         mov     al, 0x1F
  1202.         stosw
  1203. .noscrollbar:
  1204.         ret
  1205.  
  1206. get_ascii_char:
  1207. ; query keyboard layout
  1208.         pushad
  1209.         mov     al, [ctrlstate]
  1210.         and     al, 3
  1211.         xor     ecx, ecx
  1212.         cmp     al, 1
  1213.         sbb     ecx, -2
  1214.         push    SF_SYSTEM_GET
  1215.         pop     eax
  1216.         push    SSF_KEYBOARD_LAYOUT
  1217.         pop     ebx
  1218.         mov     edx, layout
  1219.         int     0x40
  1220.         popad
  1221. ; translate scancode to ASCII
  1222.         movzx   eax, byte [layout+eax]
  1223.         ret
  1224.  
  1225. struct DlgLbl
  1226. type           dd      1
  1227. x1             dd      ?
  1228. y1             dd      ?
  1229. x2             dd      ?
  1230. y2             dd      ?
  1231. text           dd      ?
  1232. flags          dd      ?
  1233. ends
  1234.  
  1235. struct DlgBtn
  1236. type           dd      2
  1237. x1             dd      ?
  1238. y1             dd      ?
  1239. x2             dd      ?
  1240. y2             dd      ?
  1241. text           dd      ?
  1242. flags          dd      ?
  1243. ends
  1244.  
  1245. struct DlgEdit
  1246. type           dd      3
  1247. x1             dd      ?
  1248. y1             dd      ?
  1249. x2             dd      ?
  1250. y2             dd      ?
  1251. text           dd      ?
  1252. flags          dd      ?
  1253. ends
  1254.  
  1255. struct DlgLine
  1256. type           dd      4
  1257. x1             dd      ?
  1258. y1             dd      ?
  1259. x2             dd      ?
  1260. y2             dd      ?
  1261.                dq      0
  1262. ends
  1263.  
  1264. struct DlgCheck
  1265. type           dd      5
  1266. x1             dd      ?
  1267. y1             dd      ?
  1268. x2             dd      ?
  1269. y2             dd      ?
  1270. text           dd      ?
  1271. flags          dd      ?
  1272. ends
  1273.  
  1274. struct DlgList
  1275. type           dd      6
  1276. x1             dd      ?
  1277. y1             dd      ?
  1278. x2             dd      ?
  1279. y2             dd      ?
  1280. text           dd      ?
  1281. flags          dd      ?
  1282. ends
  1283.  
  1284. virtual at 0
  1285. dlgitemtemplate:
  1286. ; Элементы:
  1287. ;       1 = статический текст
  1288. ;       2 = кнопка
  1289. ;       3 = поле редактирования
  1290. ;       4 = горизонтальный разделитель
  1291. ;       5 = флажок
  1292. ;       6 = список
  1293. .type           dd      ?
  1294. .x1             dd      ?
  1295. .y1             dd      ?
  1296. .x2             dd      ?
  1297. .y2             dd      ?
  1298. ; Данные:
  1299. ; для текста: const char* data - ASCIIZ-строка
  1300. ; для кнопки и флажка: const char* data - заголовок
  1301. ; для редактора: struct {unsigned maxlength; unsigned pos; unsigned start;
  1302. ;                        char data[maxlength+1];}* data;
  1303. ; для списка: struct {listitem* curitemptr; unsigned numitems;
  1304. ;               listitem *head; unsigned curitem;}* data;
  1305. ; head = указатель на первый отображаемый элемент,
  1306. ; curitemptr = указатель на выделенный элемент, curitem = его индекс в списке (от 0)
  1307. ; (где struct listitem {listitem* next; listitem* prev; char text[];};)
  1308. .data           dd      ?
  1309. .flags          dd      ?
  1310. ; Флаги:
  1311. ;       0 = выравнивание влево
  1312. ;       1 = выравнивание по центру
  1313. ;       2 = выравнивание вправо
  1314. ;       4 = элемент имеет фокус ввода
  1315. ;       8 = элемент может иметь фокус ввода
  1316. ;       10h: для кнопки = кнопка по умолчанию (Enter на не-кнопке)
  1317. ;            для поля ввода = данные были модифицированы
  1318. ;            для флажка = флажок установлен
  1319. ;       20h: для поля ввода = не отображать вводимые данные (показывать '*')
  1320. .size = $
  1321. end virtual
  1322. ;       struct DLGDATA
  1323. ;       {
  1324. ;               DLGTEMPLATE dialog;     /* window description */
  1325. ;               void* DlgProc;          /* dialog procedure */
  1326. ; /* int __stdcall DlgProc(DLGDATA* dlg, int msg, int param1, int param2); */
  1327. ;               void* user_data;        /* arbitrary user data */
  1328. ;               unsigned num_items;     /* number of items in the following array */
  1329. ;               DLGITEMTEMPLATE items[]; /* array of dialog items */
  1330. ;       }
  1331. ; int __stdcall DialogBox(DLGDATA* dlg);
  1332. align 16
  1333. DialogBox:
  1334.         push    ManagerDlgProc
  1335.         push    dword [esp+8]
  1336.         call    GenericBox
  1337.         ret     4
  1338.  
  1339. ; int __stdcall ShowDialogBox(DLGDATA* dlg);
  1340. ShowDialogBox:
  1341.         push    ManagerDlgProc
  1342.         push    dword [esp+8]
  1343.         call    ShowGenericBox
  1344.         ret     4
  1345.  
  1346. ; void __stdcall DrawDialogBox(DLGDATA* dlg);
  1347. DrawDialogBox:
  1348.         push    ManagerDlgProc
  1349.         push    dword [esp+8]
  1350.         call    DrawGenericBox
  1351.         ret     4
  1352.  
  1353. align 16
  1354. ManagerDlgProc:
  1355.         mov     ebp, ebx
  1356.         mov     eax, [esp+8]
  1357.         dec     eax
  1358.         jz      .draw
  1359.         dec     eax
  1360.         jz      .key
  1361.         xor     eax, eax
  1362.         ret     16
  1363. .draw:
  1364.         call    .dodraw
  1365.         ret     16
  1366. .key:
  1367. ; find item with focus
  1368.         add     ebx, dlgtemplate.size+12
  1369.         mov     ecx, [ebx-4]
  1370.         jecxz   .nobtns
  1371. @@:
  1372.         test    [ebx+dlgitemtemplate.flags], 4
  1373.         jnz     @f
  1374.         add     ebx, dlgitemtemplate.size
  1375.         loop    @b
  1376. @@:
  1377. .nobtns:
  1378.         mov     al, [esp+12]
  1379.         cmp     al, 1
  1380.         jz      .esc
  1381.         cmp     al, 0x1C
  1382.         jz      .enter
  1383.         cmp     al, 0xF
  1384.         jz      .tab
  1385.         cmp     al, 0x48
  1386.         jz      .up
  1387.         cmp     al, 0x50
  1388.         jz      .down
  1389.         jecxz   .nobtns2
  1390.         cmp     [ebx+dlgitemtemplate.type], 3
  1391.         jz      .key_edit
  1392.         cmp     [ebx+dlgitemtemplate.type], 5
  1393.         jnz     @f
  1394.         cmp     al, 0x39
  1395.         jnz     @f
  1396.         xor     [ebx+dlgitemtemplate.flags], 10h
  1397.         jmp     .ret_draw
  1398. @@:
  1399. .nobtns2:
  1400.         cmp     al, 0x4B
  1401.         jz      .left
  1402.         cmp     al, 0x4D
  1403.         jz      .right
  1404. .ret0:
  1405.         xor     eax, eax
  1406.         ret     16
  1407. .esc:
  1408.         or      eax, -1
  1409.         ret     16
  1410. .enter:
  1411.         cmp     [ebx+dlgitemtemplate.type], 2
  1412.         jnz     @f
  1413. .enter_found:
  1414.         mov     eax, ebx
  1415.         ret     16
  1416. @@:
  1417.         lea     ebx, [ebp+dlgtemplate.size+12]
  1418.         mov     ecx, [ebx-4]
  1419. .enter_find:
  1420.         cmp     [ebx+dlgitemtemplate.type], 2
  1421.         jnz     @f
  1422.         test    [ebx+dlgitemtemplate.flags], 0x10
  1423.         jnz     .enter_found
  1424. @@:
  1425.         add     ebx, dlgitemtemplate.size
  1426.         loop    .enter_find
  1427.         jmp     .enter_found
  1428. .tab:
  1429.         test    [ctrlstate], 3
  1430.         jnz     .shift_tab
  1431. .right:
  1432. .down:
  1433.         jecxz   .ret0
  1434.         and     byte [ebx+dlgitemtemplate.flags], not 4
  1435.         dec     ecx
  1436.         jz      .find_first_btn
  1437. @@:
  1438.         add     ebx, dlgitemtemplate.size
  1439.         test    [ebx+dlgitemtemplate.flags], 8
  1440.         jnz     .btn_found
  1441.         loop    @b
  1442. .find_first_btn:
  1443.         lea     ebx, [ebp+dlgtemplate.size+12]
  1444. @@:
  1445.         test    [ebx+dlgitemtemplate.flags], 8
  1446.         jnz     .btn_found
  1447.         add     ebx, dlgitemtemplate.size
  1448.         jmp     @b
  1449. .btn_found:
  1450.         or      byte [ebx+dlgitemtemplate.flags], 4
  1451. .ret_draw:
  1452.         mov     ebx, ebp
  1453.         call    .dodraw
  1454.         call    draw_image
  1455.         xor     eax, eax
  1456.         ret     16
  1457. .shift_tab:
  1458. .left:
  1459. .up:
  1460.         jecxz   .ret0
  1461.         and     byte [ebx+dlgitemtemplate.flags], not 4
  1462.         sub     ecx, [ebp+dlgtemplate.size+8]
  1463.         neg     ecx
  1464.         jz      .find_last_btn
  1465. @@:
  1466.         sub     ebx, dlgitemtemplate.size
  1467.         test    [ebx+dlgitemtemplate.flags], 8
  1468.         loopz   @b
  1469.         jnz     .btn_found
  1470. .find_last_btn:
  1471.         mov     ebx, [ebp+dlgtemplate.size+8]
  1472.         imul    ebx, dlgitemtemplate.size
  1473.         lea     ebx, [ebx+ebp+dlgtemplate.size+12]
  1474. @@:
  1475.         sub     ebx, dlgitemtemplate.size
  1476.         test    [ebx+dlgitemtemplate.flags], 8
  1477.         jz      @b
  1478.         jmp     .btn_found
  1479. .key_edit:
  1480. ; обработка клавиш в поле ввода
  1481.         test    al, 0x80
  1482.         jnz     .ret0
  1483.         or      [ebx+dlgitemtemplate.flags], 0x10
  1484.         mov     edx, [ebx+dlgitemtemplate.data]
  1485.         cmp     al, 0x4B
  1486.         jz      .editor_left
  1487.         cmp     al, 0x4D
  1488.         jz      .editor_right
  1489.         cmp     al, 0x47
  1490.         jz      .editor_home
  1491.         cmp     al, 0x4F
  1492.         jz      .editor_end
  1493.         cmp     al, 0x0E
  1494.         jz      .editor_backspace
  1495.         cmp     al, 0x53
  1496.         jnz     .editor_char
  1497. .editor_del:
  1498.         mov     ecx, [edx+4]
  1499.         lea     edi, [ecx+edx+12]
  1500.         lea     esi, [edi+1]
  1501.         cmp     byte [edi], 0
  1502.         jz      .ret_test
  1503.         jmp     .copy_and_ret_test
  1504. .editor_left:
  1505.         mov     ecx, [edx+4]
  1506.         jecxz   @f
  1507.         dec     dword [edx+4]
  1508. @@:     jmp     .ret_test
  1509. .editor_right:
  1510.         mov     ecx, [edx+4]
  1511.         cmp     byte [edx+ecx+12], 0
  1512.         jz      @b
  1513.         inc     dword [edx+4]
  1514.         jmp     @b
  1515. .editor_home:
  1516.         and     dword [edx+4], 0
  1517.         jmp     @b
  1518. .editor_end:
  1519.         lea     edi, [edx+12]
  1520.         xor     eax, eax
  1521.         or      ecx, -1
  1522.         repnz   scasb
  1523.         not     ecx
  1524.         dec     ecx
  1525.         mov     [edx+4], ecx
  1526. .ret_test:
  1527.         mov     eax, [edx+4]
  1528.         cmp     [edx+8], eax
  1529.         jl      .ret_test.l1
  1530.         mov     [edx+8], eax
  1531.         jmp     .ret_test.l2
  1532. .ret_test.l1:
  1533.         add     eax, [ebx+dlgitemtemplate.x1]
  1534.         sub     eax, [ebx+dlgitemtemplate.x2]
  1535.         cmp     [edx+8], eax
  1536.         jge     .ret_test.l2
  1537.         mov     [edx+8], eax
  1538. .ret_test.l2:
  1539.         jmp     .ret_draw
  1540. .editor_backspace:
  1541.         mov     ecx, [edx+4]
  1542.         jecxz   .ret_test
  1543.         dec     dword [edx+4]
  1544.         lea     esi, [edx+ecx+12]
  1545.         lea     edi, [esi-1]
  1546. .copy_and_ret_test:
  1547. @@:
  1548.         lodsb
  1549.         stosb
  1550.         test    al, al
  1551.         jnz     @b
  1552.         jmp     .ret_test
  1553. .editor_char:
  1554.         test    [ctrlstate], 0x3C
  1555.         jnz     .ret_draw
  1556.         movzx   eax, al
  1557.         call    get_ascii_char
  1558.         push    eax
  1559. ; insert entered symbol
  1560.         xor     eax, eax
  1561.         lea     edi, [edx+12]
  1562.         or      ecx, -1
  1563.         repnz   scasb
  1564.         not     ecx
  1565.         pop     eax
  1566.         cmp     ecx, [edx]
  1567.         ja      .ret_test       ; buffer capacity exceeded
  1568.         lea     edi, [edx+ecx+12-1]
  1569.         mov     esi, [edx+4]
  1570.         lea     esi, [edx+esi+12]
  1571. @@:
  1572.         mov     cl, [edi]
  1573.         mov     [edi+1], cl
  1574.         dec     edi
  1575.         cmp     edi, esi
  1576.         jae     @b
  1577.         mov     [esi], al
  1578.         inc     dword [edx+4]
  1579. @@:     jmp     .ret_test
  1580.  
  1581. align 4
  1582. .dodraw:
  1583.         or      [cursor_x], -1
  1584.         or      [cursor_y], -1
  1585.         add     ebx, dlgtemplate.size+8
  1586.         mov     ecx, [ebx]
  1587.         add     ebx, 4
  1588.         jecxz   .done_draw
  1589. .draw_loop:
  1590.         push    ecx
  1591.         mov     eax, [ebx+dlgitemtemplate.type]
  1592.         cmp     eax, draw_functions_num
  1593.         jae     .draw_loop_continue
  1594.         call    [draw_functions + eax*4]
  1595. .draw_loop_continue:
  1596.         pop     ecx
  1597.         add     ebx, dlgitemtemplate.size
  1598.         loop    .draw_loop
  1599. .done_draw:
  1600.         ret
  1601.  
  1602. iglobal
  1603. align 4
  1604. label draw_functions dword
  1605.         dd      ManagerDlgProc.done_draw
  1606.         dd      draw_static_text
  1607.         dd      draw_button
  1608.         dd      draw_editbox
  1609.         dd      draw_h_separator
  1610.         dd      draw_checkbox
  1611.         dd      draw_listbox
  1612. draw_functions_num = ($ - draw_functions) / 4
  1613. endg
  1614.  
  1615. align 4
  1616. draw_static_text:
  1617. ; рисуем статический текст
  1618.         mov     ah, [dialog_main_color]
  1619.         test    byte [ebp+dlgtemplate.flags], 2
  1620.         jz      draw_text
  1621.         mov     ah, [warning_main_color]
  1622. draw_text:
  1623. ; определяем длину строки
  1624.         mov     esi, [ebx+dlgitemtemplate.data]
  1625. draw_text_esi:
  1626.         test    esi, esi
  1627.         jz      .ret2
  1628.         push    eax
  1629.         push    -1
  1630.         pop     ecx
  1631. @@:
  1632.         inc     ecx
  1633.         cmp     byte [ecx+esi], 0
  1634.         jnz     @b
  1635. ; в ecx длина строки
  1636.         xor     eax, eax
  1637.         mov     edx, [ebx+dlgitemtemplate.x2]
  1638.         sub     edx, [ebx+dlgitemtemplate.x1]
  1639.         inc     edx
  1640.         cmp     ecx, edx
  1641.         jae     .text_draw
  1642.         mov     al, byte [ebx+dlgitemtemplate.flags]
  1643.         and     al, 3
  1644.         jz      .text_align_left
  1645.         cmp     al, 1
  1646.         jz      .text_align_center
  1647. ; текст выровнен вправо
  1648.         mov     eax, edx
  1649.         sub     eax, ecx
  1650.         jmp     .text_draw
  1651. .text_align_center:
  1652.         mov     eax, edx
  1653.         sub     eax, ecx
  1654.         shr     eax, 1
  1655.         jmp     .text_draw
  1656. .text_align_left:
  1657.         xor     eax, eax
  1658. .text_draw:
  1659.         push    ecx
  1660.         push    eax
  1661.         push    edx
  1662.         call    dlgitem_get_console_ptr
  1663.         pop     edx
  1664.         pop     ecx
  1665.         mov     ah, [esp+5]
  1666.         mov     al, ' '
  1667.         rep     stosw
  1668.         pop     ecx
  1669.         cmp     ecx, edx
  1670.         jbe     .text_copy
  1671.         cmp     [ebx+dlgitemtemplate.type], 3
  1672.         jnz     @f
  1673.         mov     ecx, edx
  1674.         jmp     .text_copy
  1675. @@:
  1676.         cmp     edx, 3
  1677.         jb      .ret
  1678.         mov     al, '.'
  1679.         stosw
  1680.         stosw
  1681.         stosw
  1682.         add     esi, ecx
  1683.         mov     ecx, edx
  1684.         sub     ecx, 3
  1685.         sub     esi, ecx
  1686. .text_copy:
  1687.         jecxz   .ret
  1688. ; check for password editboxes
  1689.         cmp     [ebx+dlgitemtemplate.type], 3
  1690.         jnz     @f
  1691.         test    [ebx+dlgitemtemplate.flags], 20h
  1692.         jz      @f
  1693.         mov     al, '*'
  1694.         rep     stosw
  1695.         jmp     .ret
  1696. @@:
  1697.         lodsb
  1698.         stosw
  1699.         loop    @b
  1700. .ret:
  1701.         mov     eax, [ebp+dlgtemplate.x]
  1702.         mov     edx, [ebp+dlgtemplate.y]
  1703.         add     eax, [ebx+dlgitemtemplate.x2]
  1704.         inc     eax
  1705.         add     edx, [ebx+dlgitemtemplate.y1]
  1706.         mov     ecx, edi
  1707.         call    get_console_ptr
  1708.         xchg    ecx, edi
  1709.         sub     ecx, edi
  1710.         shr     ecx, 1
  1711.         pop     eax
  1712.         mov     al, ' '
  1713.         rep     stosw
  1714. .ret2:
  1715.         ret
  1716.  
  1717. align 4
  1718. draw_button:
  1719.         mov     ecx, dialog_colors
  1720.         test    byte [ebp+dlgtemplate.flags], 2
  1721.         jz      @f
  1722.         mov     ecx, warning_colors
  1723. @@:
  1724.         mov     ah, [dialog_normal_btn_color-dialog_colors+ecx]
  1725.         test    [ebx+dlgitemtemplate.flags], 4
  1726.         jz      @f
  1727.         mov     ah, [dialog_selected_btn_color-dialog_colors+ecx]
  1728. @@:
  1729.         jmp     draw_text
  1730.  
  1731. align 4
  1732. draw_editbox:
  1733.         mov     edx, [ebx+dlgitemtemplate.data]
  1734.         test    [ebx+dlgitemtemplate.flags], 4
  1735.         jz      @f
  1736.         mov     eax, [ebx+dlgitemtemplate.x1]
  1737.         add     eax, [edx+4]
  1738.         sub     eax, [edx+8]
  1739.         add     eax, [ebp+dlgtemplate.x]
  1740.         mov     [cursor_x], eax
  1741.         mov     eax, [ebx+dlgitemtemplate.y1]
  1742.         add     eax, [ebp+dlgtemplate.y]
  1743.         mov     [cursor_y], eax
  1744. @@:
  1745.         mov     ecx, dialog_colors
  1746.         test    byte [ebp+dlgtemplate.flags], 2
  1747.         jz      @f
  1748.         mov     ecx, warning_colors
  1749. @@:
  1750.         mov     ah, [dialog_edit_color-dialog_colors+ecx]
  1751.         test    [ebx+dlgitemtemplate.flags], 10h
  1752.         jnz     @f
  1753.         mov     ah, [dialog_unmodified_edit_color-dialog_colors+ecx]
  1754. @@:
  1755.         mov     esi, [ebx+dlgitemtemplate.data]
  1756.         add     esi, [edx+8]
  1757.         add     esi, 12
  1758.         jmp     draw_text_esi
  1759.  
  1760. align 4
  1761. dlgitem_get_console_ptr:
  1762.         mov     eax, [ebx+dlgitemtemplate.x1]
  1763.         mov     edx, [ebx+dlgitemtemplate.y1]
  1764.         mov     ecx, eax
  1765.         add     eax, [ebp+dlgtemplate.x]
  1766.         add     edx, [ebp+dlgtemplate.y]
  1767.         jmp     get_console_ptr
  1768.  
  1769. align 4
  1770. draw_h_separator:
  1771. ; рисуем горизонтальный разделитель
  1772.         call    dlgitem_get_console_ptr
  1773. .scan:
  1774.         mov     al, 0xC7
  1775.         test    ecx, ecx
  1776.         js      @f
  1777.         mov     al, 0xB6
  1778.         cmp     ecx, [ebp+dlgtemplate.width]
  1779.         jz      @f
  1780.         mov     al, 0xC4
  1781. @@:
  1782.         stosb
  1783.         jz      .done
  1784.         inc     ecx
  1785.         inc     edi
  1786.         cmp     ecx, [ebx+dlgitemtemplate.x2]
  1787.         jb      .scan
  1788. .done:
  1789.         ret
  1790.  
  1791. align 4
  1792. draw_checkbox:
  1793. ; рисуем флажок
  1794.         call    dlgitem_get_console_ptr
  1795.         test    byte [ebx+dlgitemtemplate.flags], 4
  1796.         jz      @f
  1797.         inc     eax
  1798.         mov     [cursor_x], eax
  1799.         mov     [cursor_y], edx
  1800. @@:
  1801.         mov     ah, [dialog_main_color]
  1802.         test    byte [ebp+dlgtemplate.flags], 2
  1803.         jz      @f
  1804.         mov     ah, [warning_main_color]
  1805. @@:
  1806.         mov     al, '['
  1807.         stosw
  1808.         mov     al, 'x'
  1809.         test    byte [ebx+dlgitemtemplate.flags], 10h
  1810.         jnz     @f
  1811.         mov     al, ' '
  1812. @@:
  1813.         stosw
  1814.         mov     al, ']'
  1815.         stosw
  1816.         mov     al, ' '
  1817.         stosw
  1818.         mov     ecx, [ebx+dlgitemtemplate.x2]
  1819.         sub     ecx, [ebx+dlgitemtemplate.x1]
  1820.         jb      .ret
  1821.         sub     ecx, 3
  1822.         jbe     .ret
  1823.         mov     esi, [ebx+dlgitemtemplate.data]
  1824. @@:
  1825.         lodsb
  1826.         test    al, al
  1827.         jz      .ret
  1828.         stosw
  1829.         loop    @b
  1830. .ret:
  1831.         ret
  1832.  
  1833. align 4
  1834. draw_listbox:
  1835. ; рисуем список
  1836.         call    dlgitem_get_console_ptr
  1837.         mov     edx, [ebx+dlgitemtemplate.data]
  1838.         mov     esi, [edx+8]
  1839.         mov     eax, [ebx+dlgitemtemplate.y2]
  1840.         sub     eax, [ebx+dlgitemtemplate.y1]
  1841.         push    eax
  1842.         push    eax
  1843. .0:
  1844.         test    esi, esi
  1845.         jz      .listdone
  1846.         push    esi edi
  1847.         push    edx
  1848.         or      edx, -1
  1849.         mov     ecx, [ebx+dlgitemtemplate.x2]
  1850.         sub     ecx, [ebx+dlgitemtemplate.x1]
  1851.         inc     ecx
  1852.         xor     eax, eax
  1853. @@:
  1854.         inc     edx
  1855.         cmp     byte [esi+8+edx], al
  1856.         jnz     @b
  1857. @@:
  1858.         cmp     ecx, edx
  1859.         jae     .text_draw
  1860.         mov     al, byte [ebx+dlgitemtemplate.flags]
  1861.         and     al, 3
  1862.         jz      .text_align_left
  1863.         cmp     al, 1
  1864.         jz      .text_align_center
  1865. ; текст выровнен вправо
  1866.         mov     eax, edx
  1867.         sub     eax, ecx
  1868.         jmp     .text_draw
  1869. .text_align_center:
  1870.         mov     eax, edx
  1871.         sub     eax, ecx
  1872.         shr     eax, 1
  1873.         jmp     .text_draw
  1874. .text_align_left:
  1875. ;        xor     eax, eax
  1876. .text_draw:
  1877.         pop     edx
  1878.         cmp     esi, [edx]
  1879.         lea     esi, [esi+8+eax]
  1880.         mov     ah, [dialog_selected_list_color]
  1881.         jz      @f
  1882.         mov     ah, [dialog_list_color]
  1883. @@:
  1884.         jecxz   .next
  1885. @@:
  1886.         lodsb
  1887.         test    al, al
  1888.         jz      @f
  1889.         stosw
  1890.         loop    @b
  1891. @@:
  1892.         mov     al, ' '
  1893.         rep     stosw
  1894. .next:
  1895.         pop     edi esi
  1896.         add     edi, [cur_width]
  1897.         add     edi, [cur_width]
  1898.         mov     esi, [esi]
  1899.         dec     dword [esp]
  1900.         jns     .0
  1901. .listdone:
  1902.         pop     eax
  1903. ; Линейка прокрутки
  1904.         pop     ecx
  1905.         inc     ecx
  1906.         mov     esi, [edx+4]
  1907.         cmp     ecx, esi
  1908.         jae     .noscrollbar
  1909.         sub     ecx, 2
  1910.         jbe     .noscrollbar
  1911.         mov     eax, [edx+12]
  1912.         mul     ecx
  1913.         div     esi
  1914.         push    eax
  1915.         mov     eax, [ebx+dlgitemtemplate.x2]
  1916.         add     eax, [ebp+dlgtemplate.x]
  1917.         mov     edx, [ebx+dlgitemtemplate.y1]
  1918.         add     edx, [ebp+dlgtemplate.y]
  1919.         call    get_console_ptr
  1920.         pop     edx
  1921.         inc     edx
  1922.         mov     al, 0x1E
  1923.         mov     ah, [dialog_scroll_list_color]
  1924.         mov     [edi], ax
  1925.         add     edi, [cur_width]
  1926.         add     edi, [cur_width]
  1927. .2:
  1928.         mov     al, 0xB1
  1929.         dec     edx
  1930.         jz      @f
  1931.         mov     al, 0xB0
  1932. @@:
  1933.         mov     [edi], ax
  1934.         add     edi, [cur_width]
  1935.         add     edi, [cur_width]
  1936.         loop    .2
  1937.         mov     al, 0x1F
  1938.         stosw
  1939. .noscrollbar:
  1940.         ret
  1941.  
  1942. align 4
  1943. listbox_key:
  1944.         mov     edx, [ebx+dlgitemtemplate.data]
  1945.         cmp     al, 0x48
  1946.         jz      .prev
  1947.         cmp     al, 0x50
  1948.         jz      .next
  1949.         cmp     al, 0x47
  1950.         jz      .home
  1951.         cmp     al, 0x4F
  1952.         jz      .end
  1953.         cmp     al, 0x51
  1954.         jz      .pgdn
  1955.         cmp     al, 0x49
  1956.         jz      .pgup
  1957.         ret
  1958. .next:
  1959.         call    .calc_last_line
  1960.         mov     eax, [edx]
  1961.         cmp     dword [eax], 0
  1962.         jz      @f
  1963.         call    .line_next
  1964. @@:
  1965.         mov     [edx], eax
  1966.         ret
  1967. .pgdn:
  1968.         call    .calc_last_line
  1969.         mov     eax, [edx]
  1970.         mov     ecx, [ebx+dlgitemtemplate.y2]
  1971.         sub     ecx, [ebx+dlgitemtemplate.y1]
  1972. .pgdnl:
  1973.         cmp     dword [eax], 0
  1974.         jz      @f
  1975.         call    .line_next
  1976.         loop    .pgdnl
  1977. @@:
  1978.         mov     [edx], eax
  1979.         ret
  1980. .prev:
  1981.         mov     eax, [edx]
  1982.         cmp     dword [eax+4], 0
  1983.         jz      @f
  1984.         call    .line_prev
  1985. @@:
  1986.         mov     [edx], eax
  1987.         ret
  1988. .pgup:
  1989.         mov     eax, [edx]
  1990.         mov     ecx, [ebx+dlgitemtemplate.y2]
  1991.         sub     ecx, [ebx+dlgitemtemplate.y1]
  1992. ;        inc     ecx
  1993. .pgupl:
  1994.         cmp     dword [eax+4], 0
  1995.         jz      @f
  1996.         call    .line_prev
  1997.         loop    .pgupl
  1998. @@:
  1999.         mov     [edx], eax
  2000.         ret
  2001. .home:
  2002.         mov     eax, [edx]
  2003. @@:
  2004.         cmp     dword [eax+4], 0
  2005.         jz      @f
  2006.         mov     eax, [eax+4]
  2007.         jmp     @b
  2008. @@:
  2009.         mov     [edx], eax
  2010.         mov     [edx+8], eax
  2011.         and     dword [edx+12], 0
  2012.         ret
  2013. .end:
  2014.         mov     eax, [edx]
  2015. @@:
  2016.         cmp     dword [eax], 0
  2017.         jz      @f
  2018.         mov     eax, [eax]
  2019.         jmp     @b
  2020. @@:
  2021.         mov     [edx], eax
  2022.         mov     ecx, [ebx+dlgitemtemplate.y2]
  2023.         sub     ecx, [ebx+dlgitemtemplate.y1]
  2024.         jz      .e1
  2025. .e2:
  2026.         mov     eax, [eax+4]
  2027.         loop    .e2
  2028. .e1:
  2029.         mov     [edx+8], eax
  2030.         mov     eax, [edx+4]
  2031.         dec     eax
  2032.         mov     [edx+12], eax
  2033.         ret
  2034.  
  2035. .line_prev:
  2036.         cmp     eax, [edx+8]
  2037.         mov     eax, [eax+4]
  2038.         jnz     @f
  2039.         mov     [edx+8], eax
  2040. @@:
  2041.         dec     dword [edx+12]
  2042.         ret
  2043. .calc_last_line:
  2044.         mov     esi, [edx+8]
  2045.         mov     ecx, [ebx+dlgitemtemplate.y2]
  2046.         sub     ecx, [ebx+dlgitemtemplate.y1]
  2047.         jz      .clldone
  2048. @@:
  2049.         mov     esi, [esi]
  2050.         test    esi, esi
  2051.         jz      @f
  2052.         loop    @b
  2053. .clldone:
  2054.         ret
  2055. .line_next:
  2056.         cmp     eax, esi
  2057.         mov     eax, [eax]
  2058.         jnz     @f
  2059.         push    eax
  2060.         mov     eax, [edx+8]
  2061.         mov     eax, [eax]
  2062.         mov     [edx+8], eax
  2063.         pop     eax
  2064.         mov     esi, eax
  2065. @@:
  2066.         inc     dword [edx+12]
  2067.         ret
  2068.  
  2069. ; void __stdcall SayNoMem(void);
  2070. SayNoMem:
  2071.         or      dword [nomem_dlgdata+4], -1
  2072.         or      dword [nomem_dlgdata+8], -1
  2073.         push    nomem_dlgdata
  2074.         call    DialogBox
  2075.         ret
  2076.  
  2077. ; int __stdcall ConfirmCancel(void);
  2078. ; return value: 0 = the user is sure, nonzero = the user wants to continue
  2079. ConfirmCancel:
  2080.         push    YesOrNoBtn
  2081.         push    2
  2082.         push    ConfirmCancelMsg
  2083.         push    1
  2084.         push    aCancelled
  2085.         call    SayErrTitle
  2086.         test    eax, eax
  2087.         ret
  2088.  
  2089. ; int __stdcall SayErr(int num_strings, const char* strings[],
  2090. ;                      int num_buttons, const char* buttons[]);
  2091. SayErr:
  2092.         pop     eax
  2093.         push    aError
  2094.         push    eax
  2095. ; int __stdcall SayErrTitle(const char* title,
  2096. ;                       int num_strings, const char* strings[],
  2097. ;                       int num_buttons, const char* buttons[]);
  2098. SayErrTitle:
  2099.         push    2
  2100.         jmp     @f
  2101.  
  2102. ; int __stdcall Message(const char* title,
  2103. ;                       int num_strings, const char* strings[],
  2104. ;                       int num_buttons, const char* buttons[]);
  2105. align 16
  2106. Message:
  2107.         push    1
  2108. @@:
  2109.         pop     eax
  2110. ; [esp+4] = title
  2111. ; [esp+8] = num_strings
  2112. ; [esp+12] = strings
  2113. ; [esp+16] = num_buttons
  2114. ; [esp+20] = buttons
  2115.         pushad
  2116.         mov     ecx, [esp+32+8]
  2117.         add     ecx, [esp+32+16]
  2118.         imul    ecx, dlgitemtemplate.size
  2119.         add     ecx, dlgtemplate.size+12
  2120.         call    xpgalloc
  2121.         test    eax, eax
  2122.         jnz     @f
  2123.         popad
  2124.         or      eax, -1
  2125.         ret     28
  2126. @@:
  2127.         mov     ebx, eax
  2128.         mov     edi, eax
  2129.         mov     eax, [esp+28]
  2130.         stosd                           ; dlgtemplate.flags
  2131.         or      eax, -1
  2132.         stosd                           ; dlgtemplate.x
  2133.         stosd                           ; dlgtemplate.y
  2134. ; calculate width
  2135.         mov     ecx, [esp+32+8]
  2136.         mov     esi, [esp+32+12]
  2137.         xor     edx, edx
  2138. .calcwidth:
  2139.         lodsd
  2140. @@:
  2141.         inc     eax
  2142.         cmp     byte [eax-1], 0
  2143.         jnz     @b
  2144.         sub     eax, [esi-4]
  2145.         inc     eax
  2146.         cmp     edx, eax
  2147.         ja      @f
  2148.         mov     edx, eax
  2149. @@:
  2150.         loop    .calcwidth
  2151.         mov     ecx, [esp+32+16]
  2152.         mov     esi, [esp+32+20]
  2153.         xor     ebp, ebp
  2154. .calcwidth2:
  2155.         lodsd
  2156. @@:
  2157.         inc     eax
  2158.         cmp     byte [eax-1], 0
  2159.         jnz     @b
  2160.         sub     eax, [esi-4]
  2161.         inc     eax
  2162.         add     ebp, eax
  2163.         loop    .calcwidth2
  2164.         inc     ebp
  2165.         inc     ebp
  2166.         cmp     edx, ebp
  2167.         ja      @f
  2168.         mov     edx, ebp
  2169. @@:
  2170.         mov     eax, [cur_width]
  2171.         sub     eax, 8
  2172.         cmp     edx, eax
  2173.         jb      @f
  2174.         mov     edx, eax
  2175. @@:
  2176.         mov     eax, edx
  2177.         stosd                           ; dlgtemplate.width
  2178.         mov     eax, [esp+32+8]
  2179.         inc     eax
  2180.         stosd                           ; dlgtemplate.height
  2181.         mov     eax, 3
  2182.         stosd                           ; dlgtemplate.border_size_x
  2183.         mov     al, 2
  2184.         stosd                           ; dlgtemplate.border_size_y
  2185.         mov     eax, [esp+32+4]
  2186.         stosd                           ; dlgtemplate.title
  2187.         xor     eax, eax
  2188.         stosd                           ; (ignored)
  2189.         stosd                           ; (ignored)
  2190.         stosd                           ; DlgProc
  2191.         stosd                           ; userdata
  2192.         mov     eax, [esp+32+8]
  2193.         add     eax, [esp+32+16]
  2194.         stosd                           ; num_items
  2195. ; fill strings
  2196.         xor     ecx, ecx
  2197.         mov     esi, [esp+32+12]
  2198. @@:
  2199.         mov     eax, 1
  2200.         stosd                           ; dlgitemtemplate.type
  2201.         dec     eax
  2202.         stosd                           ; dlgitemtemplate.x1
  2203.         mov     eax, ecx
  2204.         stosd                           ; dlgitemtemplate.y1
  2205.         lea     eax, [edx-1]
  2206.         stosd                           ; dlgitemtemplate.x2
  2207.         mov     eax, ecx
  2208.         stosd                           ; dlgitemtemplate.y2
  2209.         movsd                           ; dlgitemtemplate.data
  2210.         mov     eax, 1
  2211.         stosd                           ; dlgitemtemplate.flags
  2212.         inc     ecx
  2213.         cmp     ecx, [esp+32+8]
  2214.         jb      @b
  2215. ; fill buttons
  2216.         mov     ecx, [esp+32+16]
  2217.         mov     esi, [esp+32+20]
  2218.         sub     edx, ebp
  2219.         jc      .big
  2220.         shr     edx, 1
  2221.         inc     edx
  2222.         jmp     .fillbtns
  2223. .big:
  2224.         xor     edx, edx
  2225. .fillbtns:
  2226.         mov     eax, 2
  2227.         stosd                           ; dlgitemtemplate.type
  2228.         mov     eax, edx
  2229.         stosd                           ; dlgitemtemplate.x1
  2230.         mov     eax, [ebx+dlgtemplate.height]
  2231.         dec     eax
  2232.         stosd                           ; dlgitemtemplate.y1
  2233.         push    eax
  2234.         lodsd
  2235.         sub     eax, edx
  2236. @@:
  2237.         inc     edx
  2238.         cmp     byte [eax+edx-1], 0
  2239.         jnz     @b
  2240.         mov     eax, edx
  2241.         inc     edx
  2242.         stosd                           ; dlgitemtemplate.x2
  2243.         pop     eax
  2244.         stosd                           ; dlgitemtemplate.y2
  2245.         mov     eax, [esi-4]
  2246.         stosd                           ; dlgitemtemplate.data
  2247.         mov     eax, 9
  2248.         cmp     ecx, [esp+32+16]
  2249.         jnz     @f
  2250.         or      al, 4
  2251. @@:
  2252.         stosd                           ; dlgitemtemplate.flags
  2253.         loop    .fillbtns
  2254.         push    ebx
  2255.         call    DialogBox
  2256.         cmp     eax, -1
  2257.         jz      @f
  2258.         sub     eax, ebx
  2259.         sub     eax, dlgtemplate.size+12
  2260.         xor     edx, edx
  2261.         mov     ecx, dlgitemtemplate.size
  2262.         div     ecx
  2263.         sub     eax, [esp+32+8]
  2264. @@:
  2265.         mov     [esp+28], eax
  2266.         mov     ecx, ebx
  2267.         call    pgfree
  2268.         popad
  2269.         ret     20
  2270.