Subversion Repositories Kolibri OS

Rev

Rev 283 | Rev 474 | 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. .flags          dd      ?
  12. .x              dd      ?
  13. .y              dd      ?
  14. .width          dd      ?
  15. .height         dd      ?
  16. .border_size_x  dd      ?
  17. .border_size_y  dd      ?
  18. .title          dd      ?
  19. .main_color     db      ?
  20. .border_color   db      ?
  21. .header_color   db      ?
  22.                 db      ?       ; align
  23. .size = $
  24. end virtual
  25.  
  26. GenericBox:
  27.         pushad
  28.         mov     ebx, [esp+20h+4]
  29. ; center window if required
  30.         cmp     [ebx+dlgtemplate.x], -1
  31.         jnz     @f
  32.         mov     eax, [cur_width]
  33.         sub     eax, [ebx+dlgtemplate.width]
  34.         shr     eax, 1
  35.         mov     [ebx+dlgtemplate.x], eax
  36. @@:
  37.         cmp     [ebx+dlgtemplate.y], -1
  38.         jnz     @f
  39.         mov     eax, [cur_height]
  40.         sub     eax, [ebx+dlgtemplate.height]
  41.         shr     eax, 1
  42.         mov     [ebx+dlgtemplate.y], eax
  43. @@:
  44. ; some checks
  45.         mov     eax, [ebx+dlgtemplate.x]
  46.         cmp     eax, 1
  47.         jl      .sizeerr
  48.         add     eax, [ebx+dlgtemplate.width]
  49.         cmp     eax, [cur_width]
  50.         jge     .sizeerr
  51.         mov     eax, [ebx+dlgtemplate.y]
  52.         cmp     eax, 1
  53.         jl      .sizeerr
  54.         add     eax, [ebx+dlgtemplate.height]
  55.         cmp     eax, [cur_height]
  56.         jge     .sizeerr
  57.         cmp     [ebx+dlgtemplate.border_size_x], 1
  58.         jl      .sizeerr
  59.         cmp     [ebx+dlgtemplate.border_size_y], 1
  60.         jge     .sizeok
  61. .sizeerr:
  62.         popad
  63.         or      eax, -1
  64.         ret     8
  65. .sizeok:
  66. ; set color if required
  67.         test    byte [ebx+dlgtemplate.flags], 1
  68.         jz      @f
  69.         mov     edi, dialog_colors
  70.         jmp     .setcolor
  71. @@:
  72.         test    byte [ebx+dlgtemplate.flags], 2
  73.         jz      @f
  74.         mov     edi, warning_colors
  75. .setcolor:
  76.         mov     al, [dialog_main_color-dialog_colors+edi]
  77.         mov     [ebx+dlgtemplate.main_color], al
  78.         mov     al, [dialog_border_color-dialog_colors+edi]
  79.         mov     [ebx+dlgtemplate.border_color], al
  80.         mov     al, [dialog_header_color-dialog_colors+edi]
  81.         mov     [ebx+dlgtemplate.header_color], al
  82. @@:
  83. ; allocate memory for data under dialog
  84. ; for 'No memory' dialog use static data area
  85.         mov     ebp, nomem_dlgsavearea
  86.         cmp     ebx, nomem_dlgdata
  87.         jz      .allocated
  88.         mov     eax, [ebx+dlgtemplate.width]
  89.         add     eax, [ebx+dlgtemplate.border_size_x]
  90.         add     eax, [ebx+dlgtemplate.border_size_x]
  91.         inc     eax
  92.         inc     eax
  93.         mov     edx, [ebx+dlgtemplate.height]
  94.         add     edx, [ebx+dlgtemplate.border_size_y]
  95.         add     edx, [ebx+dlgtemplate.border_size_y]
  96.         inc     edx
  97.         mul     edx
  98.         add     eax, eax
  99.         call    mf_alloc
  100.         test    eax, eax
  101.         jnz     @f
  102.         popad
  103.         or      eax, -1
  104.         ret     8
  105. @@:
  106.         mov     ebp, eax
  107. .allocated:
  108. ; save data
  109.         mov     eax, [ebx+dlgtemplate.y]
  110.         add     eax, [ebx+dlgtemplate.height]
  111.         add     eax, [ebx+dlgtemplate.border_size_y]
  112.         inc     eax
  113.         push    eax
  114.         mov     eax, [ebx+dlgtemplate.x]
  115.         add     eax, [ebx+dlgtemplate.width]
  116.         add     eax, [ebx+dlgtemplate.border_size_x]
  117.         inc     eax
  118.         inc     eax
  119.         push    eax
  120.         mov     eax, [ebx+dlgtemplate.y]
  121.         sub     eax, [ebx+dlgtemplate.border_size_y]
  122.         push    eax
  123.         mov     eax, [ebx+dlgtemplate.x]
  124.         sub     eax, [ebx+dlgtemplate.border_size_x]
  125.         push    eax
  126.         call    save_console_data
  127. ; draw shadow
  128.         mov     eax, [ebx+dlgtemplate.x]
  129.         sub     eax, [ebx+dlgtemplate.border_size_x]
  130.         ja      @f
  131.         xor     eax, eax
  132. @@:
  133.         push    eax     ; save real window left
  134.         inc     eax
  135.         inc     eax
  136.         mov     edx, [ebx+dlgtemplate.y]
  137.         sub     edx, [ebx+dlgtemplate.border_size_y]
  138.         ja      @f
  139.         xor     edx, edx
  140. @@:
  141.         push    edx     ; save real window top
  142.         inc     edx
  143.         call    get_console_ptr
  144.         mov     ecx, [ebx+dlgtemplate.y]
  145.         add     ecx, [ebx+dlgtemplate.height]
  146.         add     ecx, [ebx+dlgtemplate.border_size_y]
  147.         inc     ecx
  148.         cmp     ecx, [cur_height]
  149.         jb      @f
  150.         mov     ecx, [cur_height]
  151. @@:
  152.         sub     ecx, edx
  153.         mov     edx, ecx
  154.         mov     ecx, [ebx+dlgtemplate.x]
  155.         add     ecx, [ebx+dlgtemplate.width]
  156.         add     ecx, [ebx+dlgtemplate.border_size_x]
  157.         inc     ecx
  158.         inc     ecx
  159.         cmp     ecx, [cur_width]
  160.         jb      @f
  161.         mov     ecx, [cur_width]
  162. @@:
  163.         sub     ecx, eax
  164.         mov     eax, ecx
  165. .shadow_loop:
  166.         mov     ecx, eax
  167.         push    edi
  168. .sl1:
  169.         inc     edi
  170.         test    byte [edi], 0x0F
  171.         jnz     @f
  172.         or      byte [edi], 8
  173. @@:
  174.         and     byte [edi], 0x0F
  175.         inc     edi
  176.         loop    .sl1
  177.         pop     edi
  178.         add     edi, [cur_width]
  179.         add     edi, [cur_width]
  180.         dec     edx
  181.         jnz     .shadow_loop
  182. ; draw area background
  183.         pop     edx
  184.         pop     eax
  185.         call    get_console_ptr
  186.         mov     ecx, [ebx+dlgtemplate.x]
  187.         add     ecx, [ebx+dlgtemplate.width]
  188.         add     ecx, [ebx+dlgtemplate.border_size_x]
  189.         cmp     ecx, [cur_width]
  190.         jb      @f
  191.         mov     ecx, [cur_width]
  192. @@:
  193.         sub     ecx, eax
  194.         mov     esi, ecx
  195.         mov     ecx, [ebx+dlgtemplate.y]
  196.         add     ecx, [ebx+dlgtemplate.height]
  197.         add     ecx, [ebx+dlgtemplate.border_size_y]
  198.         cmp     ecx, [cur_height]
  199.         jb      @f
  200.         mov     ecx, [cur_height]
  201. @@:
  202.         sub     ecx, edx
  203.         mov     edx, ecx
  204.         mov     al, ' '
  205.         mov     ah, [ebx+dlgtemplate.border_color]
  206. .1:
  207.         mov     ecx, esi
  208.         push    edi
  209.         rep     stosw
  210.         pop     edi
  211.         add     edi, [cur_width]
  212.         add     edi, [cur_width]
  213.         dec     edx
  214.         jnz     .1
  215. ; draw border
  216.         mov     eax, [ebx+dlgtemplate.x]
  217.         dec     eax
  218.         mov     edx, [ebx+dlgtemplate.y]
  219.         dec     edx
  220.         call    get_console_ptr
  221.         mov     edx, [ebx+dlgtemplate.height]
  222.         inc     edx
  223.         inc     edx
  224.         mov     ah, [ebx+dlgtemplate.border_color]
  225.         push    ebx
  226.         mov     ebx, [ebx+dlgtemplate.width]
  227.         inc     ebx
  228.         inc     ebx
  229.         call    draw_border
  230.         pop     ebx
  231. ; draw header
  232.         mov     esi, [ebx+dlgtemplate.title]
  233.         test    esi, esi
  234.         jz      .noheader
  235.         cmp     byte [esi], 0
  236.         jz      .noheader
  237.         push    esi
  238. @@:     lodsb
  239.         test    al, al
  240.         jnz     @b
  241.         mov     eax, esi
  242.         pop     esi
  243.         sub     eax, esi
  244.         inc     eax     ; eax = длина заголовка + 2
  245.         mov     ecx, [ebx+dlgtemplate.width]
  246.         cmp     eax, ecx
  247.         jbe     .fullhea
  248.         sub     ecx, 5
  249.         jb      .noheader
  250.         xor     edx, edx
  251.         jmp     .drawhea
  252. .fullhea:
  253.         mov     edx, ecx
  254.         sub     edx, eax
  255.         shr     edx, 1
  256. .drawhea:
  257.         mov     eax, [ebx+dlgtemplate.x]
  258.         add     eax, edx
  259.         mov     edx, [ebx+dlgtemplate.y]
  260.         dec     edx
  261.         call    get_console_ptr
  262.         mov     ah, [ebx+dlgtemplate.header_color]
  263.         mov     al, ' '
  264.         stosw
  265. .2:
  266.         dec     ecx
  267.         jz      .3
  268.         lodsb
  269.         test    al, al
  270.         jz      .4
  271.         stosw
  272.         jmp     .2
  273. .3:
  274.         mov     al, '.'
  275.         stosw
  276.         stosw
  277.         stosw
  278. .4:
  279.         mov     al, ' '
  280.         stosw
  281. .noheader:
  282. ; draw window background
  283.         mov     eax, [ebx+dlgtemplate.x]
  284.         mov     edx, [ebx+dlgtemplate.y]
  285.         call    get_console_ptr
  286.         mov     ah, [ebx+dlgtemplate.main_color]
  287.         mov     al, ' '
  288.         mov     edx, [ebx+dlgtemplate.height]
  289. @@:
  290.         mov     ecx, [ebx+dlgtemplate.width]
  291.         push    edi
  292.         rep     stosw
  293.         pop     edi
  294.         add     edi, [cur_width]
  295.         add     edi, [cur_width]
  296.         dec     edx
  297.         jnz     @b
  298. ; send redraw message
  299.         mov     eax, [esp+20h+8]
  300.         push    ebx ebp
  301.         push    0
  302.         push    0
  303.         push    1
  304.         push    ebx
  305.         call    eax
  306.         call    draw_image
  307.         pop     ebp ebx
  308. ; message loop
  309. .event:
  310.         push    10
  311.         pop     eax
  312.         int     40h
  313.         dec     eax
  314.         jz      .redraw
  315.         dec     eax
  316.         jz      .key
  317.         or      eax, -1
  318.         int     40h
  319. .redraw:
  320.         push    ebx ebp
  321.         call    draw_window
  322.         pop     ebp ebx
  323.         jmp     .event
  324. .key:
  325.         mov     al, 2
  326.         int     40h
  327.         shr     eax, 8
  328.         cmp     al, 0xE0
  329.         jnz     @f
  330.         mov     [bWasE0], 1
  331.         jmp     .event
  332. @@:
  333.         xchg    ah, [bWasE0]
  334.         cmp     al, 0x1D
  335.         jz      .ctrl_down
  336.         cmp     al, 0x9D
  337.         jz      .ctrl_up
  338.         cmp     al, 0x2A
  339.         jz      .lshift_down
  340.         cmp     al, 0xAA
  341.         jz      .lshift_up
  342.         cmp     al, 0x36
  343.         jz      .rshift_down
  344.         cmp     al, 0xB6
  345.         jz      .rshift_up
  346.         cmp     al, 0x38
  347.         jz      .alt_down
  348.         cmp     al, 0xB8
  349.         jz      .alt_up
  350.         mov     ecx, [esp+20h+8]
  351.         push    ebx ebp
  352.         push    0
  353.         push    eax
  354.         push    2
  355.         push    ebx
  356.         call    ecx
  357.         pop     ebp ebx
  358.         test    eax, eax
  359.         jz      .event
  360.         mov     [esp+28], eax
  361.         jmp     .exit
  362. .ctrl_down:
  363.         test    ah, ah
  364.         jnz     .rctrl_down
  365.         or      [ctrlstate], 4
  366.         jmp     .event
  367. .rctrl_down:
  368.         or      [ctrlstate], 8
  369.         jmp     .event
  370. .ctrl_up:
  371.         test    ah, ah
  372.         jnz     .rctrl_up
  373.         and     [ctrlstate], not 4
  374.         jmp     .event
  375. .rctrl_up:
  376.         and     [ctrlstate], not 8
  377.         jmp     .event
  378. .lshift_down:
  379.         test    ah, ah
  380.         jnz     @f
  381.         or      [ctrlstate], 1
  382. @@:     jmp     .event
  383. .lshift_up:
  384.         test    ah, ah
  385.         jnz     @b
  386.         and     [ctrlstate], not 1
  387.         jmp     @b
  388. .rshift_down:
  389.         or      [ctrlstate], 2
  390.         jmp     .event
  391. .rshift_up:
  392.         and     [ctrlstate], not 2
  393.         jmp     .event
  394. .alt_down:
  395.         test    ah, ah
  396.         jnz     .ralt_down
  397.         or      [ctrlstate], 0x10
  398.         jmp     .event
  399. .ralt_down:
  400.         or      [ctrlstate], 0x20
  401.         jmp     .event
  402. .alt_up:
  403.         test    ah, ah
  404.         jnz     .ralt_up
  405.         and     [ctrlstate], not 0x10
  406.         jmp     .event
  407. .ralt_up:
  408.         and     [ctrlstate], not 0x20
  409.         jmp     .event
  410. .exit:
  411. ; restore data
  412.         mov     eax, [ebx+dlgtemplate.y]
  413.         add     eax, [ebx+dlgtemplate.height]
  414.         add     eax, [ebx+dlgtemplate.border_size_y]
  415.         inc     eax
  416.         push    eax
  417.         mov     eax, [ebx+dlgtemplate.x]
  418.         add     eax, [ebx+dlgtemplate.width]
  419.         add     eax, [ebx+dlgtemplate.border_size_x]
  420.         inc     eax
  421.         inc     eax
  422.         push    eax
  423.         mov     eax, [ebx+dlgtemplate.y]
  424.         sub     eax, [ebx+dlgtemplate.border_size_y]
  425.         push    eax
  426.         mov     eax, [ebx+dlgtemplate.x]
  427.         sub     eax, [ebx+dlgtemplate.border_size_x]
  428.         push    eax
  429.         call    restore_console_data
  430.         call    draw_keybar
  431.         cmp     ebx, nomem_dlgdata
  432.         jz      @f
  433.         mov     eax, ebp
  434.         call    mf_free
  435. @@:
  436.         or      [cursor_x], -1
  437.         or      [cursor_y], -1
  438.         call    draw_image
  439.         popad
  440.         ret     8
  441.  
  442. save_console_data:
  443.         cmp     dword [esp+4], 0
  444.         jge     @f
  445.         and     dword [esp+4], 0
  446. @@:
  447.         cmp     dword [esp+8], 0
  448.         jge     @f
  449.         and     dword [esp+8], 0
  450. @@:
  451.         mov     eax, [esp+12]
  452.         cmp     eax, [cur_width]
  453.         jbe     @f
  454.         mov     eax, [cur_width]
  455. @@:
  456.         sub     eax, [esp+4]
  457.         ja      @f
  458.         ret     16
  459. @@:
  460.         mov     [esp+12], eax
  461.         mov     eax, [esp+16]
  462.         cmp     eax, [cur_height]
  463.         jbe     @f
  464.         mov     eax, [cur_height]
  465. @@:
  466.         sub     eax, [esp+8]
  467.         ja      @f
  468.         ret     16
  469. @@:
  470.         mov     [esp+16], eax
  471.         mov     eax, [esp+4]
  472.         mov     edx, [esp+8]
  473.         call    get_console_ptr
  474.         mov     esi, edi
  475.         mov     edi, ebp
  476. .l:
  477.         mov     ecx, [esp+12]
  478.         push    esi
  479.         shr     ecx, 1
  480.         rep     movsd
  481.         adc     ecx, ecx
  482.         rep     movsw
  483.         pop     esi
  484.         add     esi, [cur_width]
  485.         add     esi, [cur_width]
  486.         dec     dword [esp+16]
  487.         jnz     .l
  488.         ret     16
  489.  
  490. restore_console_data:
  491.         cmp     dword [esp+4], 0
  492.         jge     @f
  493.         and     dword [esp+4], 0
  494. @@:
  495.         cmp     dword [esp+8], 0
  496.         jge     @f
  497.         and     dword [esp+8], 0
  498. @@:
  499.         mov     eax, [esp+12]
  500.         cmp     eax, [cur_width]
  501.         jbe     @f
  502.         mov     eax, [cur_width]
  503. @@:
  504.         sub     eax, [esp+4]
  505.         ja      @f
  506.         ret     16
  507. @@:
  508.         mov     [esp+12], eax
  509.         mov     eax, [esp+16]
  510.         cmp     eax, [cur_height]
  511.         jbe     @f
  512.         mov     eax, [cur_height]
  513. @@:
  514.         sub     eax, [esp+8]
  515.         ja      @f
  516.         ret     16
  517. @@:
  518.         mov     [esp+16], eax
  519.         mov     eax, [esp+4]
  520.         mov     edx, [esp+8]
  521.         call    get_console_ptr
  522.         mov     esi, ebp
  523. .l:
  524.         mov     ecx, [esp+12]
  525.         push    edi
  526.         shr     ecx, 1
  527.         rep     movsd
  528.         adc     ecx, ecx
  529.         rep     movsw
  530.         pop     edi
  531.         add     edi, [cur_width]
  532.         add     edi, [cur_width]
  533.         dec     dword [esp+16]
  534.         jnz     .l
  535.         ret     16
  536.  
  537. ; int __stdcall menu(void* variants, const char* title, unsigned flags);
  538. ; variants указывает на текущий элемент в двусвязном линейном списке
  539. menu:
  540.         pop     eax
  541.         push    [cur_height]
  542.         push    [cur_width]
  543.         push    0
  544.         push    0
  545.         push    eax
  546.  
  547. ; int __stdcall menu_centered_in(unsigned left, unsigned top, unsigned width, unsigned height,
  548. ;       void* variants, const char* title, unsigned flags);
  549. menu_centered_in:
  550.         pushad
  551.         mov     eax, 56
  552. ; 36 bytes for dlgtemplate + additional:
  553. ; +36: dd cur_variant
  554. ; +40: dd num_variants
  555. ; +44: dd begin_variant
  556. ; +48: dd end_variant
  557. ; +52: dd cur_variant_idx
  558.         call    xmalloc
  559.         test    eax, eax
  560.         jnz     @f
  561. .ret_bad:
  562.         popad
  563.         or      eax, -1
  564.         ret     28
  565. @@:
  566.         mov     ebx, eax
  567.         mov     eax, 1
  568.         test    byte [esp+20h+28], 1
  569.         jz      @f
  570.         mov     al, 3
  571. @@:
  572.         mov     [ebx+dlgtemplate.border_size_x], eax
  573.         inc     eax
  574.         shr     eax, 1
  575.         mov     [ebx+dlgtemplate.border_size_y], eax
  576. ; Находим ширину и высоту окна
  577.         xor     eax, eax
  578.         xor     ecx, ecx
  579.         mov     esi, [esp+20h+20]
  580.         mov     [ebx+36], esi
  581.         and     dword [ebx+52], 0
  582. @@:
  583.         cmp     dword [esi+4], 0
  584.         jz      .find_width
  585.         mov     esi, [esi+4]
  586.         inc     dword [ebx+52]
  587.         jmp     @b
  588. .find_width:
  589.         mov     [ebx+44], esi
  590.         add     esi, 8
  591.         push    esi
  592.         xor     edx, edx
  593. .fw1:
  594.         cmp     byte [esi], '&'
  595.         jnz     @f
  596.         mov     dl, 1
  597. @@:
  598.         inc     esi
  599.         cmp     byte [esi-1], 0
  600.         jnz     .fw1
  601.         sub     esi, [esp]
  602.         sub     esi, edx
  603.         dec     esi
  604.         cmp     eax, esi
  605.         ja      @f
  606.         mov     eax, esi
  607. @@:
  608.         inc     ecx
  609.         pop     esi
  610.         mov     esi, [esi-8]
  611.         test    esi, esi
  612.         jnz     .find_width
  613.         add     eax, 3
  614.         add     eax, [ebx+dlgtemplate.border_size_x]
  615.         add     eax, [ebx+dlgtemplate.border_size_x]
  616.         cmp     eax, [cur_width]
  617.         jb      @f
  618.         mov     eax, [cur_width]
  619. @@:
  620.         sub     eax, [ebx+dlgtemplate.border_size_x]
  621.         sub     eax, [ebx+dlgtemplate.border_size_x]
  622.         mov     [ebx+dlgtemplate.width], eax
  623.         mov     [ebx+dlgtemplate.height], ecx
  624.         mov     [ebx+40], ecx
  625.         sub     eax, [esp+20h+12]
  626.         neg     eax
  627.         sar     eax, 1
  628.         add     eax, [esp+20h+4]
  629.         cmp     eax, [ebx+dlgtemplate.border_size_x]
  630.         jge     @f
  631.         mov     eax, [ebx+dlgtemplate.border_size_x]
  632. @@:
  633.         push    eax
  634.         add     eax, [ebx+dlgtemplate.width]
  635.         add     eax, [ebx+dlgtemplate.border_size_x]
  636.         cmp     eax, [cur_width]
  637.         jbe     @f
  638.         pop     eax
  639.         mov     eax, [cur_width]
  640.         sub     eax, [ebx+dlgtemplate.width]
  641.         sub     eax, [ebx+dlgtemplate.border_size_x]
  642.         push    eax
  643. @@:
  644.         pop     [ebx+dlgtemplate.x]
  645.         sub     ecx, [esp+20h+16]
  646.         neg     ecx
  647.         sar     ecx, 1
  648.         add     ecx, [esp+20h+8]
  649.         cmp     ecx, [ebx+dlgtemplate.border_size_y]
  650.         jge     @f
  651.         mov     ecx, [ebx+dlgtemplate.border_size_y]
  652. @@:
  653.         push    ecx
  654.         add     ecx, [ebx+dlgtemplate.height]
  655.         add     ecx, [ebx+dlgtemplate.border_size_y]
  656.         cmp     ecx, [cur_height]
  657.         jbe     @f
  658.         pop     ecx
  659.         mov     ecx, [cur_height]
  660.         sub     ecx, [ebx+dlgtemplate.height]
  661.         sub     ecx, [ebx+dlgtemplate.border_size_y]
  662.         push    ecx
  663. @@:
  664.         pop     [ebx+dlgtemplate.y]
  665.         mov     eax, [cur_height]
  666.         sub     eax, 6
  667.         cmp     [ebx+dlgtemplate.height], eax
  668.         jbe     .small_height
  669.         mov     [ebx+dlgtemplate.height], eax
  670.         mov     [ebx+dlgtemplate.y], 3
  671. .small_height:
  672.         mov     ecx, [ebx+dlgtemplate.height]
  673.         mov     eax, [ebx+36]
  674.         mov     [ebx+44], eax
  675.         dec     ecx
  676.         jz      .skip
  677.         push    ecx
  678. @@:
  679.         cmp     dword [eax+4], 0
  680.         jz      @f
  681.         mov     eax, [eax+4]
  682.         loop    @b
  683. @@:
  684.         mov     [ebx+44], eax
  685.         pop     ecx
  686. .loop:
  687.         mov     eax, [eax]
  688.         loop    .loop
  689. .skip:
  690.         mov     [ebx+48], eax
  691.         mov     eax, [esp+20h+24]
  692.         mov     [ebx+dlgtemplate.title], eax
  693.         mov     al, [menu_normal_color]
  694.         mov     [ebx+dlgtemplate.main_color], al
  695.         mov     al, [menu_border_color]
  696.         mov     [ebx+dlgtemplate.border_color], al
  697.         mov     al, [menu_header_color]
  698.         mov     [ebx+dlgtemplate.header_color], al
  699.         push    MenuDlgProc
  700.         push    ebx
  701.         call    GenericBox
  702.         mov     [esp+28], eax
  703.         mov     eax, ebx
  704.         call    mf_free
  705.         popad
  706.         ret     28
  707.  
  708. MenuDlgProc:
  709.         mov     eax, [esp+8]
  710.         cmp     al, 1
  711.         jz      .draw
  712.         cmp     al, 2
  713.         jz      .key
  714.         ret     16
  715. .draw:
  716.         call    .dodraw
  717.         ret     16
  718. .key:
  719.         mov     al, [esp+12]
  720.         cmp     al, 0x48
  721.         jz      .prev
  722.         cmp     al, 0x4B
  723.         jz      .prev
  724.         cmp     al, 0x4D
  725.         jz      .next
  726.         cmp     al, 0x50
  727.         jz      .next
  728.         cmp     al, 0x1C
  729.         jz      .enter
  730.         cmp     al, 1
  731.         jz      .esc
  732.         cmp     al, 0x47
  733.         jz      .home
  734.         cmp     al, 0x4F
  735.         jz      .end
  736.         cmp     al, 0x51
  737.         jz      .pgdn
  738.         cmp     al, 0x49
  739.         jz      .pgup
  740.         mov     edx, [ebx+36]
  741. @@:
  742.         cmp     dword [edx+4], 0
  743.         jz      @f
  744.         mov     edx, [edx+4]
  745.         jmp     @b
  746. @@:
  747. .l:
  748.         lea     esi, [edx+7]
  749. @@:
  750.         inc     esi
  751.         cmp     byte [esi], 0
  752.         jz      .n
  753.         cmp     byte [esi], '&'
  754.         jnz     @b
  755.         movzx   ecx, byte [esi+1]
  756.         cmp     [ascii2scan+ecx], al
  757.         jnz     .n
  758.         mov     eax, edx
  759.         ret     16
  760. .n:
  761.         mov     edx, [edx]
  762.         test    edx, edx
  763.         jnz     .l
  764. .ret:
  765.         xor     eax, eax
  766.         ret     16
  767. .pgup:
  768.         mov     eax, [ebx+36]
  769.         mov     ecx, [ebx+dlgtemplate.height]
  770. .pgupl:
  771.         cmp     dword [eax+4], 0
  772.         jz      .posret
  773.         call    .line_prev
  774.         loop    .pgupl
  775.         jmp     .posret
  776. .prev:
  777.         mov     eax, [ebx+36]
  778.         cmp     dword [eax+4], 0
  779.         jz      .end
  780.         call    .line_prev
  781. .posret:
  782.         mov     [ebx+36], eax
  783. .redraw:
  784.         call    .dodraw
  785.         call    draw_image
  786.         xor     eax, eax
  787.         ret     16
  788. .next:
  789.         mov     eax, [ebx+36]
  790.         cmp     dword [eax], 0
  791.         jz      .home
  792.         call    .line_next
  793.         jmp     .posret
  794. .pgdn:
  795.         mov     eax, [ebx+36]
  796.         mov     ecx, [ebx+dlgtemplate.height]
  797. .pgdnl:
  798.         cmp     dword [eax], 0
  799.         jz      .posret
  800.         call    .line_next
  801.         loop    .pgdnl
  802.         jmp     .posret
  803. .home:
  804.         mov     eax, [ebx+36]
  805. @@:
  806.         cmp     dword [eax+4], 0
  807.         jz      @f
  808.         mov     eax, [eax+4]
  809.         jmp     @b
  810. @@:
  811.         mov     [ebx+44], eax
  812.         push    eax
  813.         mov     ecx, [ebx+dlgtemplate.height]
  814.         dec     ecx
  815.         jz      .h1
  816. .h2:
  817.         mov     eax, [eax]
  818.         loop    .h2
  819. .h1:
  820.         mov     [ebx+48], eax
  821.         pop     eax
  822.         and     dword [ebx+52], 0
  823.         jmp     .posret
  824. .end:
  825.         mov     eax, [ebx+36]
  826. @@:
  827.         cmp     dword [eax], 0
  828.         jz      @f
  829.         mov     eax, [eax]
  830.         jmp     @b
  831. @@:
  832.         mov     [ebx+48], eax
  833.         push    eax
  834.         mov     ecx, [ebx+dlgtemplate.height]
  835.         dec     ecx
  836.         jz      .e1
  837. .e2:
  838.         mov     eax, [eax+4]
  839.         loop    .e2
  840. .e1:
  841.         mov     [ebx+44], eax
  842.         mov     eax, [ebx+40]
  843.         dec     eax
  844.         mov     [ebx+52], eax
  845.         pop     eax
  846.         jmp     .posret
  847. .esc:
  848.         or      eax, -1
  849.         ret     16
  850. .enter:
  851.         mov     eax, [ebx+36]
  852.         ret     16
  853.  
  854. .line_prev:
  855.         cmp     eax, [ebx+44]
  856.         jnz     @f
  857.         mov     edx, [ebx+44]
  858.         mov     edx, [edx+4]
  859.         mov     [ebx+44], edx
  860.         mov     edx, [ebx+48]
  861.         mov     edx, [edx+4]
  862.         mov     [ebx+48], edx
  863. @@:
  864.         mov     eax, [eax+4]
  865.         dec     dword [ebx+52]
  866.         ret
  867. .line_next:
  868.         cmp     eax, [ebx+48]
  869.         jnz     @f
  870.         mov     edx, [ebx+44]
  871.         mov     edx, [edx]
  872.         mov     [ebx+44], edx
  873.         mov     edx, [ebx+48]
  874.         mov     edx, [edx]
  875.         mov     [ebx+48], edx
  876. @@:
  877.         mov     eax, [eax]
  878.         inc     dword [ebx+52]
  879.         ret
  880.  
  881. .dodraw:
  882.         mov     eax, [ebx+dlgtemplate.x]
  883.         mov     edx, [ebx+dlgtemplate.y]
  884.         call    get_console_ptr
  885.         mov     esi, [ebx+44]
  886. .0:
  887.         xor     edx, edx
  888.         mov     ah, [menu_selected_color]
  889.         cmp     esi, [ebx+36]
  890.         jz      @f
  891.         mov     ah, [menu_normal_color]
  892. @@:
  893.         push    edi
  894.         mov     ecx, [ebx+dlgtemplate.width]
  895.         mov     al, ' '
  896.         stosw
  897.         dec     ecx
  898.         stosw
  899.         dec     ecx
  900.         dec     ecx
  901.         push    esi
  902.         add     esi, 8
  903. @@:
  904.         lodsb
  905.         test    al, al
  906.         jz      @f
  907.         cmp     al, '&'
  908.         jnz     .noamp
  909.         test    dl, dl
  910.         jnz     .noamp
  911.         mov     dl, 1
  912.         lodsb
  913.         push    eax
  914.         mov     ah, [menu_selected_highlight_color]
  915.         push    ecx
  916.         mov     ecx, [esp+8]
  917.         cmp     ecx, [ebx+36]
  918.         pop     ecx
  919.         jz      .amp1
  920.         mov     ah, [menu_highlight_color]
  921. .amp1:
  922.         stosw
  923.         pop     eax
  924.         jmp     .amp2
  925. .noamp:
  926.         stosw
  927. .amp2:
  928.         loop    @b
  929.         mov     al, ' '
  930.         cmp     byte [esi], 0
  931.         jnz     .1
  932.         lodsb
  933.         jmp     .1
  934. @@:
  935.         mov     al, ' '
  936. .1:
  937.         stosw
  938.         mov     al, ' '
  939.         rep     stosw
  940.         pop     esi edi
  941.         add     edi, [cur_width]
  942.         add     edi, [cur_width]
  943.         cmp     esi, [ebx+48]
  944.         jz      @f
  945.         mov     esi, [esi]
  946.         test    esi, esi
  947.         jnz     .0
  948. @@:
  949. ; Линейка прокрутки
  950.         mov     ecx, [ebx+dlgtemplate.height]
  951.         cmp     ecx, [ebx+40]
  952.         jz      .noscrollbar
  953.         sub     ecx, 2
  954.         jbe     .noscrollbar
  955.         mov     eax, [ebx+52]
  956.         mul     ecx
  957.         div     dword [ebx+40]
  958.         push    eax
  959.         mov     eax, [ebx+dlgtemplate.x]
  960.         add     eax, [ebx+dlgtemplate.width]
  961.         mov     edx, [ebx+dlgtemplate.y]
  962.         call    get_console_ptr
  963.         pop     edx
  964.         inc     edx
  965.         mov     al, 0x1E
  966.         mov     ah, [menu_scrollbar_color]
  967.         mov     [edi], ax
  968.         add     edi, [cur_width]
  969.         add     edi, [cur_width]
  970. .2:
  971.         mov     al, 0xB2
  972.         dec     edx
  973.         jz      @f
  974.         mov     al, 0xB0
  975. @@:
  976.         mov     [edi], ax
  977.         add     edi, [cur_width]
  978.         add     edi, [cur_width]
  979.         loop    .2
  980.         mov     al, 0x1F
  981.         stosw
  982. .noscrollbar:
  983.         ret
  984.  
  985. virtual at 0
  986. dlgitemtemplate:
  987. ; Элементы:
  988. ;       1 = статический текст
  989. ;       2 = кнопка
  990. ;       3 = поле редактирования
  991. .type           dd      ?
  992. .x1             dd      ?
  993. .y1             dd      ?
  994. .x2             dd      ?
  995. .y2             dd      ?
  996. ; Данные:
  997. ; для текста: const char* data - ASCIIZ-строка
  998. ; для кнопки: const char* data - заголовок
  999. ; для редактора: struct {unsigned maxlength; unsigned pos; unsigned start;
  1000. ;                        char data[maxlength+1];}* data;
  1001. .data           dd      ?
  1002. .flags          dd      ?
  1003. ; Флаги:
  1004. ;       0 = выравнивание влево
  1005. ;       1 = выравнивание по центру
  1006. ;       2 = выравнивание вправо
  1007. ;       4 = элемент имеет фокус ввода
  1008. ;       8 = элемент может иметь фокус ввода
  1009. ;       10h: для кнопки = кнопка по умолчанию (Enter на не-кнопке)
  1010. ;            для поля ввода = данные были модифицированы
  1011. .size = $
  1012. end virtual
  1013. ;       struct DLGDATA
  1014. ;       {
  1015. ;               DLGTEMPLATE dialog;     /* window description */
  1016. ;               void* DlgProc;          /* dialog procedure */
  1017. ; /* int __stdcall DlgProc(DLGDATA* dlg, int msg, int param1, int param2); */
  1018. ;               void* user_data;        /* arbitrary user data */
  1019. ;               unsigned num_items;     /* number of items in the following array */
  1020. ;               DLGITEMTEMPLATE items[]; /* array of dialog items */
  1021. ;       }
  1022. ; int __stdcall DialogBox(DLGDATA* dlg);
  1023. DialogBox:
  1024.         push    ManagerDlgProc
  1025.         push    dword [esp+8]
  1026.         call    GenericBox
  1027.         ret     4
  1028.  
  1029. ManagerDlgProc:
  1030.         mov     ebp, ebx
  1031.         mov     eax, [esp+8]
  1032.         dec     eax
  1033.         jz      .draw
  1034.         dec     eax
  1035.         jz      .key
  1036.         xor     eax, eax
  1037.         ret     16
  1038. .draw:
  1039.         call    .dodraw
  1040.         ret     16
  1041. .key:
  1042. ; find item with focus
  1043.         add     ebx, dlgtemplate.size+12
  1044.         mov     ecx, [ebx-4]
  1045.         jecxz   .nobtns
  1046. @@:
  1047.         test    [ebx+dlgitemtemplate.flags], 4
  1048.         jnz     @f
  1049.         add     ebx, dlgitemtemplate.size
  1050.         loop    @b
  1051. @@:
  1052. .nobtns:
  1053.         mov     al, [esp+12]
  1054.         cmp     al, 1
  1055.         jz      .esc
  1056.         cmp     al, 0x1C
  1057.         jz      .enter
  1058.         cmp     al, 0xF
  1059.         jz      .tab
  1060.         cmp     al, 0x48
  1061.         jz      .up
  1062.         cmp     al, 0x50
  1063.         jz      .down
  1064.         jecxz   @f
  1065.         cmp     [ebx+dlgitemtemplate.type], 3
  1066.         jz      .key_edit
  1067. @@:
  1068.         cmp     al, 0x4B
  1069.         jz      .left
  1070.         cmp     al, 0x4D
  1071.         jz      .right
  1072. .ret0:
  1073.         xor     eax, eax
  1074.         ret     16
  1075. .esc:
  1076.         or      eax, -1
  1077.         ret     16
  1078. .enter:
  1079.         cmp     [ebx+dlgitemtemplate.type], 2
  1080.         jnz     @f
  1081. .enter_found:
  1082.         mov     eax, ebx
  1083.         ret     16
  1084. @@:
  1085.         lea     ebx, [ebp+dlgtemplate.size+12]
  1086. .enter_find:
  1087.         cmp     [ebx+dlgitemtemplate.type], 2
  1088.         jnz     @f
  1089.         test    [ebx+dlgitemtemplate.flags], 0x10
  1090.         jnz     .enter_found
  1091. @@:
  1092.         add     ebx, dlgitemtemplate.size
  1093.         jmp     .enter_find
  1094. .tab:
  1095.         test    [ctrlstate], 3
  1096.         jnz     .shift_tab
  1097. .right:
  1098. .down:
  1099.         jecxz   .ret0
  1100.         and     byte [ebx+dlgitemtemplate.flags], not 4
  1101.         dec     ecx
  1102.         jz      .find_first_btn
  1103. @@:
  1104.         add     ebx, dlgitemtemplate.size
  1105.         test    [ebx+dlgitemtemplate.flags], 8
  1106.         jnz     .btn_found
  1107.         loop    @b
  1108. .find_first_btn:
  1109.         lea     ebx, [ebp+dlgtemplate.size+12]
  1110. @@:
  1111.         test    [ebx+dlgitemtemplate.flags], 8
  1112.         jnz     .btn_found
  1113.         add     ebx, dlgitemtemplate.size
  1114.         jmp     @b
  1115. .btn_found:
  1116.         or      byte [ebx+dlgitemtemplate.flags], 4
  1117. .ret_draw:
  1118.         mov     ebx, ebp
  1119.         call    .dodraw
  1120.         call    draw_image
  1121.         xor     eax, eax
  1122.         ret     16
  1123. .shift_tab:
  1124. .left:
  1125. .up:
  1126.         jecxz   .ret0
  1127.         and     byte [ebx+dlgitemtemplate.flags], not 4
  1128.         sub     ecx, [ebp+dlgtemplate.size+8]
  1129.         neg     ecx
  1130.         jz      .find_last_btn
  1131. @@:
  1132.         sub     ebx, dlgitemtemplate.size
  1133.         test    [ebx+dlgitemtemplate.flags], 8
  1134.         loopz   @b
  1135.         jnz     .btn_found
  1136. .find_last_btn:
  1137.         mov     ebx, [ebp+dlgtemplate.size+8]
  1138.         imul    ebx, dlgitemtemplate.size
  1139.         lea     ebx, [ebx+ebp+dlgtemplate.size+12]
  1140. @@:
  1141.         sub     ebx, dlgitemtemplate.size
  1142.         test    [ebx+dlgitemtemplate.flags], 8
  1143.         jz      @b
  1144.         jmp     .btn_found
  1145. .key_edit:
  1146. ; обработка клавиш в поле ввода
  1147.         test    al, 0x80
  1148.         jnz     .ret0
  1149.         or      [ebx+dlgitemtemplate.flags], 0x10
  1150.         mov     edx, [ebx+dlgitemtemplate.data]
  1151.         cmp     al, 0x4B
  1152.         jz      .editor_left
  1153.         cmp     al, 0x4D
  1154.         jz      .editor_right
  1155.         cmp     al, 0x47
  1156.         jz      .editor_home
  1157.         cmp     al, 0x4F
  1158.         jz      .editor_end
  1159.         cmp     al, 0x0E
  1160.         jz      .editor_backspace
  1161.         cmp     al, 0x53
  1162.         jz      .editor_del
  1163.         test    [ctrlstate], 0x3C
  1164.         jnz     .ret_draw
  1165. ; query keyboard layout
  1166.         pushad
  1167.         push    26
  1168.         pop     eax
  1169.         push    2
  1170.         pop     ebx
  1171.         xor     ecx, ecx
  1172.         cmp     [ctrlstate], 1
  1173.         sbb     ecx, -2
  1174.         mov     edx, layout
  1175.         int     0x40
  1176.         popad
  1177. ; translate scancode to ASCII
  1178.         movzx   eax, al
  1179.         movzx   eax, byte [layout+eax]
  1180.         push    eax
  1181. ; insert entered symbol
  1182.         xor     eax, eax
  1183.         lea     edi, [edx+12]
  1184.         or      ecx, -1
  1185.         repnz   scasb
  1186.         not     ecx
  1187.         pop     eax
  1188.         cmp     ecx, [edx]
  1189.         ja      .ret_test       ; buffer capacity exceeded
  1190.         lea     edi, [edx+ecx+12-1]
  1191.         mov     esi, [edx+4]
  1192.         lea     esi, [edx+esi+12]
  1193. @@:
  1194.         mov     cl, [edi]
  1195.         mov     [edi+1], cl
  1196.         dec     edi
  1197.         cmp     edi, esi
  1198.         jae     @b
  1199.         mov     [esi], al
  1200.         inc     dword [edx+4]
  1201. @@:     jmp     .ret_test
  1202. .editor_left:
  1203.         mov     ecx, [edx+4]
  1204.         jecxz   @f
  1205.         dec     dword [edx+4]
  1206. @@:     jmp     .ret_test
  1207. .editor_right:
  1208.         mov     ecx, [edx+4]
  1209.         cmp     byte [edx+ecx+12], 0
  1210.         jz      @b
  1211.         inc     dword [edx+4]
  1212.         jmp     @b
  1213. .editor_home:
  1214.         and     dword [edx+4], 0
  1215.         jmp     @b
  1216. .editor_end:
  1217.         lea     edi, [edx+12]
  1218.         xor     eax, eax
  1219.         or      ecx, -1
  1220.         repnz   scasb
  1221.         not     ecx
  1222.         dec     ecx
  1223.         mov     [edx+4], ecx
  1224. .ret_test:
  1225.         mov     eax, [edx+4]
  1226.         cmp     [edx+8], eax
  1227.         jl      .ret_test.l1
  1228.         mov     [edx+8], eax
  1229.         jmp     .ret_test.l2
  1230. .ret_test.l1:
  1231.         add     eax, [ebx+dlgitemtemplate.x1]
  1232.         sub     eax, [ebx+dlgitemtemplate.x2]
  1233.         cmp     [edx+8], eax
  1234.         jge     .ret_test.l2
  1235.         mov     [edx+8], eax
  1236. .ret_test.l2:
  1237.         jmp     .ret_draw
  1238. .editor_backspace:
  1239.         mov     ecx, [edx+4]
  1240.         jecxz   .ret_test
  1241.         dec     dword [edx+4]
  1242.         lea     esi, [edx+ecx+12]
  1243.         lea     edi, [esi-1]
  1244. .copy_and_ret_test:
  1245. @@:
  1246.         lodsb
  1247.         stosb
  1248.         test    al, al
  1249.         jnz     @b
  1250.         jmp     .ret_test
  1251. .editor_del:
  1252.         mov     ecx, [edx+4]
  1253.         lea     edi, [ecx+edx+12]
  1254.         lea     esi, [edi+1]
  1255.         cmp     byte [edi], 0
  1256.         jz      .ret_test
  1257.         jmp     .copy_and_ret_test
  1258.  
  1259. .dodraw:
  1260.         or      [cursor_x], -1
  1261.         or      [cursor_y], -1
  1262.         add     ebx, dlgtemplate.size+8
  1263.         mov     ecx, [ebx]
  1264.         add     ebx, 4
  1265.         jecxz   .done_draw
  1266. .draw_loop:
  1267.         push    ecx
  1268.         mov     eax, [ebx+dlgitemtemplate.type]
  1269.         dec     eax
  1270.         jz      .draw_text
  1271.         dec     eax
  1272.         jz      .draw_button
  1273.         dec     eax
  1274.         jnz     .draw_loop_continue
  1275.         call    draw_editbox
  1276.         jmp     .draw_loop_continue
  1277. .draw_button:
  1278.         call    draw_button
  1279.         jmp     .draw_loop_continue
  1280. .draw_text:
  1281.         call    draw_static_text
  1282. .draw_loop_continue:
  1283.         pop     ecx
  1284.         add     ebx, dlgitemtemplate.size
  1285.         loop    .draw_loop
  1286. .done_draw:
  1287.         ret
  1288.  
  1289. draw_static_text:
  1290. ; рисуем статический текст
  1291.         mov     ah, [dialog_main_color]
  1292.         test    byte [ebp+dlgtemplate.flags], 2
  1293.         jz      draw_text
  1294.         mov     ah, [warning_main_color]
  1295. draw_text:
  1296. ; определяем длину строки
  1297.         mov     esi, [ebx+dlgitemtemplate.data]
  1298. draw_text_esi:
  1299.         test    esi, esi
  1300.         jz      .ret
  1301.         or      ecx, -1
  1302. @@:
  1303.         inc     ecx
  1304.         cmp     byte [ecx+esi], 0
  1305.         jnz     @b
  1306. ; в ecx длина строки
  1307.         push    eax
  1308.         xor     eax, eax
  1309.         mov     edx, [ebx+dlgitemtemplate.x2]
  1310.         sub     edx, [ebx+dlgitemtemplate.x1]
  1311.         inc     edx
  1312.         cmp     ecx, edx
  1313.         jae     .text_draw
  1314.         mov     al, byte [ebx+dlgitemtemplate.flags]
  1315.         and     al, 3
  1316.         jz      .text_align_left
  1317.         cmp     al, 1
  1318.         jz      .text_align_center
  1319. ; текст выровнен вправо
  1320.         mov     eax, edx
  1321.         sub     eax, ecx
  1322.         jmp     .text_draw
  1323. .text_align_center:
  1324.         mov     eax, edx
  1325.         sub     eax, ecx
  1326.         shr     eax, 1
  1327.         jmp     .text_draw
  1328. .text_align_left:
  1329.         xor     eax, eax
  1330. .text_draw:
  1331.         push    ecx
  1332.         push    eax
  1333.         mov     eax, [ebx+dlgitemtemplate.x1]
  1334.         add     eax, [ebp+dlgtemplate.x]
  1335.         push    edx
  1336.         mov     edx, [ebx+dlgitemtemplate.y1]
  1337.         add     edx, [ebp+dlgtemplate.y]
  1338.         call    get_console_ptr
  1339.         pop     edx
  1340.         pop     ecx
  1341.         mov     ah, [esp+5]
  1342.         mov     al, ' '
  1343.         rep     stosw
  1344.         pop     ecx
  1345.         cmp     ecx, edx
  1346.         jbe     .text_copy
  1347.         cmp     [ebx+dlgitemtemplate.type], 3
  1348.         jnz     @f
  1349.         mov     ecx, edx
  1350.         jmp     .text_copy
  1351. @@:
  1352.         cmp     edx, 3
  1353.         jb      .ret
  1354.         mov     al, '.'
  1355.         stosw
  1356.         stosw
  1357.         stosw
  1358.         add     esi, ecx
  1359.         mov     ecx, edx
  1360.         sub     ecx, 3
  1361.         sub     esi, ecx
  1362. .text_copy:
  1363.         jecxz   .ret
  1364. @@:
  1365.         lodsb
  1366.         stosw
  1367.         loop    @b
  1368. .ret:
  1369.         mov     eax, [ebp+dlgtemplate.x]
  1370.         mov     edx, [ebp+dlgtemplate.y]
  1371.         add     eax, [ebx+dlgitemtemplate.x2]
  1372.         inc     eax
  1373.         add     edx, [ebx+dlgitemtemplate.y1]
  1374.         mov     ecx, edi
  1375.         call    get_console_ptr
  1376.         xchg    ecx, edi
  1377.         sub     ecx, edi
  1378.         shr     ecx, 1
  1379.         pop     eax
  1380.         mov     al, ' '
  1381.         rep     stosw
  1382.         ret
  1383.  
  1384. draw_button:
  1385.         mov     ecx, dialog_colors
  1386.         test    byte [ebp+dlgtemplate.flags], 2
  1387.         jz      @f
  1388.         mov     ecx, warning_colors
  1389. @@:
  1390.         mov     ah, [dialog_normal_btn_color-dialog_colors+ecx]
  1391.         test    [ebx+dlgitemtemplate.flags], 4
  1392.         jz      @f
  1393.         mov     ah, [dialog_selected_btn_color-dialog_colors+ecx]
  1394. @@:
  1395.         jmp     draw_text
  1396.  
  1397. draw_editbox:
  1398.         mov     edx, [ebx+dlgitemtemplate.data]
  1399.         test    [ebx+dlgitemtemplate.flags], 4
  1400.         jz      @f
  1401.         mov     eax, [ebx+dlgitemtemplate.x1]
  1402.         add     eax, [edx+4]
  1403.         sub     eax, [edx+8]
  1404.         add     eax, [ebp+dlgtemplate.x]
  1405.         mov     [cursor_x], eax
  1406.         mov     eax, [ebx+dlgitemtemplate.y1]
  1407.         add     eax, [ebp+dlgtemplate.y]
  1408.         mov     [cursor_y], eax
  1409. @@:
  1410.         mov     ecx, dialog_colors
  1411.         test    byte [ebp+dlgtemplate.flags], 2
  1412.         jz      @f
  1413.         mov     ecx, warning_colors
  1414. @@:
  1415.         mov     ah, [dialog_edit_color-dialog_colors+ecx]
  1416.         test    [ebx+dlgitemtemplate.flags], 10h
  1417.         jnz     @f
  1418.         mov     ah, [dialog_unmodified_edit_color-dialog_colors+ecx]
  1419. @@:
  1420.         mov     esi, [ebx+dlgitemtemplate.data]
  1421.         add     esi, [edx+8]
  1422.         add     esi, 12
  1423.         jmp     draw_text_esi
  1424.  
  1425. ; void __stdcall SayNoMem(void);
  1426. SayNoMem:
  1427.         or      dword [nomem_dlgdata+4], -1
  1428.         or      dword [nomem_dlgdata+8], -1
  1429.         push    nomem_dlgdata
  1430.         call    DialogBox
  1431.         ret
  1432.  
  1433. ; int __stdcall SayErr(const char* title, int x, int y,
  1434. ;                       int num_strings, const char* strings[],
  1435. ;                       int num_buttons, const char* buttons[]);
  1436. ; may be x=-1 and/or y=-1
  1437. ; [esp+4] = title
  1438. ; [esp+8] = x
  1439. ; [esp+12] = y
  1440. ; [esp+16] = num_strings
  1441. ; [esp+20] = strings
  1442. ; [esp+24] = num_buttons
  1443. ; [esp+28] = buttons
  1444. SayErr:
  1445.         mov     eax, [esp+16]
  1446.         add     eax, [esp+24]
  1447.         imul    eax, dlgitemtemplate.size
  1448.         add     eax, dlgtemplate.size+12
  1449.         call    xmalloc
  1450.         test    eax, eax
  1451.         jnz     @f
  1452.         or      eax, -1
  1453.         ret     28
  1454. @@:
  1455.         pushad
  1456.         mov     ebx, eax
  1457.         mov     edi, eax
  1458.         mov     eax, 2
  1459.         stosd                           ; dlgtemplate.flags
  1460.         mov     eax, [esp+32+8]
  1461.         stosd                           ; dlgtemplate.x
  1462.         mov     eax, [esp+32+12]
  1463.         stosd                           ; dlgtemplate.y
  1464. ; calculate width
  1465.         mov     ecx, [esp+32+16]
  1466.         mov     esi, [esp+32+20]
  1467.         xor     edx, edx
  1468. .calcwidth:
  1469.         lodsd
  1470. @@:
  1471.         inc     eax
  1472.         cmp     byte [eax-1], 0
  1473.         jnz     @b
  1474.         sub     eax, [esi-4]
  1475.         inc     eax
  1476.         cmp     edx, eax
  1477.         ja      @f
  1478.         mov     edx, eax
  1479. @@:
  1480.         loop    .calcwidth
  1481.         mov     ecx, [esp+32+24]
  1482.         mov     esi, [esp+32+28]
  1483.         xor     ebp, ebp
  1484. .calcwidth2:
  1485.         lodsd
  1486. @@:
  1487.         inc     eax
  1488.         cmp     byte [eax-1], 0
  1489.         jnz     @b
  1490.         sub     eax, [esi-4]
  1491.         inc     eax
  1492.         add     ebp, eax
  1493.         loop    .calcwidth2
  1494.         inc     ebp
  1495.         inc     ebp
  1496.         cmp     edx, ebp
  1497.         ja      @f
  1498.         mov     edx, ebp
  1499. @@:
  1500.         mov     eax, [cur_width]
  1501.         sub     eax, 8
  1502.         cmp     edx, eax
  1503.         jb      @f
  1504.         mov     edx, eax
  1505. @@:
  1506.         mov     eax, edx
  1507.         stosd                           ; dlgtemplate.width
  1508.         mov     eax, [esp+32+16]
  1509.         inc     eax
  1510.         stosd                           ; dlgtemplate.height
  1511.         mov     eax, 3
  1512.         stosd                           ; dlgtemplate.border_size_x
  1513.         mov     al, 2
  1514.         stosd                           ; dlgtemplate.border_size_y
  1515.         mov     eax, [esp+32+4]
  1516.         stosd                           ; dlgtemplate.title
  1517.         xor     eax, eax
  1518.         stosd                           ; (ignored)
  1519.         stosd                           ; DlgProc
  1520.         stosd                           ; userdata
  1521.         mov     eax, [esp+32+16]
  1522.         add     eax, [esp+32+24]
  1523.         stosd                           ; num_items
  1524. ; fill strings
  1525.         xor     ecx, ecx
  1526.         mov     esi, [esp+32+20]
  1527. @@:
  1528.         mov     eax, 1
  1529.         stosd                           ; dlgitemtemplate.type
  1530.         dec     eax
  1531.         stosd                           ; dlgitemtemplate.x1
  1532.         mov     eax, ecx
  1533.         stosd                           ; dlgitemtemplate.y1
  1534.         lea     eax, [edx-1]
  1535.         stosd                           ; dlgitemtemplate.x2
  1536.         mov     eax, ecx
  1537.         stosd                           ; dlgitemtemplate.y2
  1538.         movsd                           ; dlgitemtemplate.data
  1539.         mov     eax, 1
  1540.         stosd                           ; dlgitemtemplate.flags
  1541.         inc     ecx
  1542.         cmp     ecx, [esp+32+16]
  1543.         jb      @b
  1544. ; fill buttons
  1545.         mov     ecx, [esp+32+24]
  1546.         mov     esi, [esp+32+28]
  1547.         sub     edx, ebp
  1548.         jc      .big
  1549.         shr     edx, 1
  1550.         inc     edx
  1551.         jmp     .fillbtns
  1552. .big:
  1553.         xor     edx, edx
  1554. .fillbtns:
  1555.         mov     eax, 2
  1556.         stosd                           ; dlgitemtemplate.type
  1557.         mov     eax, edx
  1558.         stosd                           ; dlgitemtemplate.x1
  1559.         mov     eax, [ebx+dlgtemplate.height]
  1560.         dec     eax
  1561.         stosd                           ; dlgitemtemplate.y1
  1562.         push    eax
  1563.         lodsd
  1564.         sub     eax, edx
  1565. @@:
  1566.         inc     edx
  1567.         cmp     byte [eax+edx-1], 0
  1568.         jnz     @b
  1569.         mov     eax, edx
  1570.         inc     edx
  1571.         stosd                           ; dlgitemtemplate.x2
  1572.         pop     eax
  1573.         stosd                           ; dlgitemtemplate.y2
  1574.         mov     eax, [esi-4]
  1575.         stosd                           ; dlgitemtemplate.data
  1576.         mov     eax, 9
  1577.         cmp     ecx, [esp+32+24]
  1578.         jnz     @f
  1579.         or      al, 4
  1580. @@:
  1581.         stosd                           ; dlgitemtemplate.flags
  1582.         loop    .fillbtns
  1583.         push    ebx
  1584.         call    DialogBox
  1585.         cmp     eax, -1
  1586.         jz      @f
  1587.         sub     eax, ebx
  1588.         sub     eax, dlgtemplate.size+12
  1589.         xor     edx, edx
  1590.         mov     ecx, dlgitemtemplate.size
  1591.         div     ecx
  1592.         sub     eax, [esp+32+16]
  1593. @@:
  1594.         mov     [esp+28], eax
  1595.         mov     eax, ebx
  1596.         call    mf_free
  1597.         popad
  1598.         ret     28
  1599.