Subversion Repositories Kolibri OS

Rev

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