;Макрос для вывода основных функций которые испльзуются боксом macro use_general_func { ;debug_func ;---------------------------------------------------------- ;--- процедура прорисовки выделеной части ----------------- ;---------------------------------------------------------- .draw_shift: test word ed_flags,ed_shift_bac ;установка флага, выделенной области jz @f mov ebp,shift_color mov ebx,dword ed_shift_pos call .sh_cl_ @@: ret ;---------------------------------------------------------- ;--- процедура прорисовки текста -------------------------- ;---------------------------------------------------------- .draw_text: ;--- вычисляем, сколько помещается символов --- ;--- чтобы мусор не рисовать --- call .get_n mov esi,ed_size mov ebx,ed_offset sub esi,ebx cmp eax,esi jae @F mov esi,eax ;чтобы не выходить за пределы экрана ;--- рисуем текст --- @@: mov eax,4 mov ebx,ed_left mov edx,ed_offset add ebx,2 shl ebx,16 mov bx,ed_top add ebx,4 mov ecx,ed_text_color add edx,ed_text mcall ret ;---------------------------------------------------------- ;--- процедура прорисовки фона ---------------------------- ;входные данные ;eax ;edx - color ;---------------------------------------------------------- ;вход только цвет edx .draw_bg: mov ebx,ed_left add ebx,1 shl ebx,16 mov bx,ed_width sub ebx,1 mov edx,ed_color .draw_bg_eax: mov ecx,ed_top mov eax,13 add ecx,1 shl ecx,16 mov cx,ed_height dec ecx mcall ret ;---------------------------------------------------------- ;--- процедура получения количества символов в текущей щирине компонента ;---------------------------------------------------------- .get_n: mov eax,ed_width ;получем ширину компонента xor edx,edx ;результат распологается в паре edx:eax в eax - остаток sub eax,4 ;вычтим 4 mov ebx,6 ;загрузми делитель div ebx ;размделим на 6 ret ;---------------------------------------------------------- ;--- процедура рисования курсора -------------------------- ;---------------------------------------------------------- ;входные ebp- цвет .clear_cursor: mov edx,ebp mov ebx,cl_curs_x mov ecx,cl_curs_y jmp .draw_curs .draw_cursor: mov edx,ed_text_color mov ebx,ed_pos mov ecx,ed_offset sub ebx,ecx lea ebx,[ebx*2+ebx] shl ebx,1 ;imul ebx,6 add bx,ed_left mov ecx,ed_top inc ebx add ecx,2 mov ebp,ebx shl ebx,16 mov bx,bp mov ebp,ecx shl ecx,16 mov cx,bp add cx,ed_height-4 mov cl_curs_x,ebx mov cl_curs_y,ecx .draw_curs: mcall 38 ret ;---------------------------------------------------------- ;--- процедура рисования рамки ---------------------------- ;---------------------------------------------------------- .draw_border: ;--- цвет рамки --- test word ed_flags,ed_focus mov edx,ed_focus_border_color jne @f mov edx,ed_blur_border_color @@: ;--- сверху --- mov eax,38 mov ebx,ed_left mov ecx,ebx shl ebx,16 mov bx,cx add bx,ed_width mov ecx, ed_top mov esi,ecx shl ecx,16 mov cx,si mcall ;--- снизу --- mov esi,ecx add ecx,ed_height mov ebp,ecx shl ecx,16 mov cx,bp mcall ;--- слева --- mov cx,si mov ebp,ebx sub bx,ed_width mcall ;--- справа --- mov ebx,ebp shl ebx,16 mov bx,bp mcall ret ;---------------------------------------------------------- ;--- проверка, зашел ли курсор за границы и, если надо, --- ;--- изменяем смещение ------------------------------------ ;--- если смещение было установка флага ed_offset_cl иначе ; если ничего не изменилось то выставление ed_offset_fl ; в общей битовой маррице состояния компонентов word ed_flags ;---------------------------------------------------------- .check_offset: pusha mov ecx,ed_pos mov ebx,ed_offset cmp ebx,ecx ja .sub_8 push ebx call .get_n ;получим кол-во символов в паре регистров edx:eax pop ebx mov edx,ebx add edx,eax ;ed_offset+width editbox inc edx ;необходимо для номального положения курсора в крайней левой позиции cmp edx,ecx ja @f mov edx,ed_size cmp edx,ecx je .add_end sub edx,ecx cmp edx,8 jbe .add_8 add ebx,8 jmp .chk_d .sub_8: cmp ecx,0 je .sub_min cmp ebx,8 jbe .sub_min sub ebx,8 ;ebx=ed_offset jmp .chk_d .sub_min: xor ebx,ebx jmp .chk_d .add_end:sub edx,eax mov ebx,edx jmp .chk_d .add_8: add ebx,edx .chk_d: mov ed_offset,ebx call .draw_bg and word ed_flags,ed_offset_cl edit_ex @@: or word ed_flags,ed_offset_fl edit_ex } macro use_key_func { ;Обработка Shift для снятия выделения неизвестной области .shift: ;;;;;;;SHIFT test word ed_flags,ed_shift je .f_exit @@: mov ebp,shift_color or word ed_flags,ed_shift_bac ;установка флага, выделенной области mov ebx,dword ed_shift_pos call .sh_cl_ jmp .draw_cursor_text ;;;;;;;;;;;;;;;;;;;;; .f_exit:call .check_offset and word ed_flags,ed_shift_cl call .enable_null jmp .draw_cursor_text .sh_cl_: ;;;;;;SHIFT end ;обработка очистки, при левом - правом движении выделения ;для обработки снятия выделения ;входные параметры ebp=color ebx=ed_shift_pos mov eax,dword ed_pos cmp eax,ebx jae .sh_n push eax ;меньшее в eax push ebx ;большее jmp .sh_n1 ;если иначе .sh_n: push ebx push eax .sh_n1: call .check_offset call .get_n mov edx,eax ;size of ed_box mov ecx,ed_offset add eax,ecx ;eax = w_off= ed_offset+width mov edx,eax ;save pop ebx ;большее pop eax ;меньшее cmp eax,ecx ;сравнение с меньшего с offset. jae .f_f ;если больше xor eax,eax cmp edx,ebx ;cравним размер w_off с большим jb @f sub ebx,ecx jmp .nxt_f @@: mov ebx,edx sub ebx,ecx jmp .nxt_f .f_f: sub eax,ecx cmp edx,ebx ;cравним размер w_off с большим jle @f sub ebx,ecx sub ebx,eax jmp .nxt_f @@: mov ebx,edx sub ebx,ecx sub ebx,eax .nxt_f: mov edx,ebx lea ebx,[eax*2+eax] shl ebx,1 add ebx,ed_left inc ebx shl ebx,16 lea ecx,[edx*2+edx] shl ecx,1 mov bx,cx inc ebx mov edx,ebp;shift_color call .draw_bg_eax @@: call .enable_null ret ;;;;;;;;;;;;;;;;;;;;; ;Установка- снятие выделения в один символ ;;;;;;;;;;;;;;;;;;;;; .drw_sim: mov eax,dword ed_pos call .draw_rectangle ;нарисовать прямоугольник с заданным цветом jmp @b ;;;;;;;;;;;;;;;;;;;;; ;Фукция установки выделения при движения влево и вправо и нажатии shift ;Логика: ;;;;;;;;;; .draw_wigwag: ;функция установки переменных mov ebp,shift_color call .clear_cursor or word ed_flags,ed_shift_bac ;установка флага, выделенной области mov ebp,shift_color mov eax,dword ed_pos test word ed_flags,ed_left_fl jz .low jmp @f ;;;;;;;;;; ;Фукция удаления выделения при движения влево и вправо и нажатии shift ;Логика: ;;;;;;;;;; .draw_wigwag_cl: ;функция установки переменных mov ebp,ed_color call .clear_cursor mov ebp,ed_color mov eax,dword ed_pos test word ed_flags,ed_left_fl jz .low @@: call .draw_rectangle ;нарисовать прямоугольник закрашиваемой области ret .low: dec eax jmp @b ;входной параметр ebx - ed_pos .sh_first_sh: test word ed_flags,ed_shift je @f mov dword ed_shift_pos_old,ebx test word ed_flags,ed_shift_on jne @f mov dword ed_shift_pos,ebx or word ed_flags,ed_shift_on @@: ret ;Обработка крайних положений в editbox при нажатом shift ;производит снятие выделение, если нет shift ;иначе вообще выходит .sh_st_of: test word ed_flags,ed_shift jne @f test word ed_flags,ed_shift_bac je @f mov ebp,ed_color mov ebx,dword ed_shift_pos call .sh_cl_ ;очистка выделеного фрагмента and word ed_flags,ed_shift_cl ; очистка от того что убрали выделение jmp .draw_cursor_text @@: and word ed_flags,ed_shift_off edit_ex ;проверка состояния shift был ли он нажат раньше? .sh_enable: test word ed_flags,ed_shift jne .sh_ext_en ;нарисовать закрашеный прямоугольник test word ed_flags,ed_shift_bac je @f call .check_offset mov ebp,ed_color mov ebx,dword ed_shift_pos call .sh_cl_ ;очистка выделеного фрагмента call .draw_wigwag_cl and word ed_flags,ed_shift_cl ; 1вар не нужно ret @@: mov ebp,ed_color call .clear_cursor call .check_offset ret .sh_ext_en: call .check_offset test word ed_flags,ed_offset_fl je @f ;Рисование закрашеных прямоугольников и очистка их mov eax,dword ed_shift_pos mov ebx,dword ed_pos mov ecx,dword ed_shift_pos_old ;проверка и рисование закрашеных областей cmp eax,ecx je .1_shem jb .smaller cmp ecx,ebx ja .1_shem call .draw_wigwag_cl ;clear jmp .sh_e_end .smaller: cmp ecx,ebx jb .1_shem call .draw_wigwag_cl ;clear jmp .sh_e_end ;alike = .1_shem: call .draw_wigwag .sh_e_end: and word ed_flags,ed_shift_off ret @@: mov ebp,shift_color mov ebx,dword ed_shift_pos call .sh_cl_ jmp .sh_e_end ;функция для обработки shift при нажатии home and end .sh_home_end: mov ebp,ed_color call .clear_cursor test word ed_flags,ed_shift_bac je @f mov ebp,ed_color mov ebx,dword ed_shift_pos_old call .sh_cl_ @@: test word ed_flags,ed_shift je .sh_exit_ ;выйти mov ebp,shift_color mov ebx,dword ed_shift_pos call .sh_cl_ or word ed_flags,ed_shift_bac ;установка флага, выделенной области jmp .sh_e_end .sh_exit_: call .check_offset ret ;функция внесения 0 по адресу ed_size+1 .enable_null: pusha mov eax,ed_size mov ebx,ed_text test eax,eax add eax,ebx jne @f inc eax @@: xor ebx,ebx mov [eax],bl edit_ex ;- удаление символа ;Входные данные edx=ed_size;ecx=ed_pos .del_char: mov esi,ed_text test word ed_flags,ed_shift_on je @f mov eax,dword ed_shift_pos mov ebx,esi cmp eax,ecx jae .dh_n mov ed_pos,eax ;что бы не было убегания курсора mov ebp,ecx sub ebp,eax add ebx,eax ;eax меньше sub edx,ecx add esi,ecx mov dword ed_shift_pos,ebp jmp .del_ch_sh ;если иначе .dh_n: mov ebp,eax sub ebp,ecx add ebx,ecx sub edx,eax add esi,eax mov dword ed_shift_pos,ebp jmp .del_ch_sh @@: add esi,ecx ;указатель + смещение к реальному буфферу mov ebx,esi inc esi cld sub edx,ecx .del_ch_sh: push edi mov edi,ebx @@: lodsb stosb dec edx jns @b pop edi ret ;вычислить закрашиваемую область ;соглашение в ebp - передается ed_size .clear_bg: call .get_n ;получить размер в символах ширины компонента push eax mov ebx,ed_offset add eax,ebx ;eax = w_off= ed_offset+width mov ebx,ebp ;ed_size cmp eax,ebx jb @f mov eax,ed_pos sub ebx,eax mov ecx,ed_offset sub eax,ecx jmp .nxt @@: mov ebx,ed_pos push ebx sub eax,ebx mov ebx,eax ;It is don't optimal pop eax ;ed_pos mov ecx,ed_offset sub eax,ecx .nxt: mov ebp,eax ;проверка на выход закрашиваемой области за пределы длины add ebp,ebx pop edx cmp ebp,edx je @f inc ebx @@: mov edx,ebx lea ebx,[eax*2+eax] shl ebx,1 add ebx,ed_left inc ebx shl ebx,16 lea ecx,[edx*2+edx] shl ecx,1 mov bx,cx mov edx,ed_color call .draw_bg_eax ret ;;;;;;;;;;;;;;;;;;; ;;; Обработка примитивов ;;;;;;;;;;;;;;;;;;;; ;Нарисовать прямоугольник, цвет передается в ebp ;входные параметры: ;eax=dword ed_pos ;ebp=-цвет ed_color or shift_color .draw_rectangle: mov ecx,dword ed_offset sub eax,ecx lea ebx,[eax*2+eax] shl ebx,1 inc ebx add ebx,ed_left shl ebx,16 mov bx,6 mov edx,ebp call .draw_bg_eax ret ;;;;;;;;;;;;;;;;;; ;;Проверка нажат ли shift ;;;;;;;;;;;;;;;;;; .check_shift: pusha ;сохраним все регистры mcall 66,3,1 test al,0x03 je @f or word ed_flags,ed_shift ;установим флаг @@:edit_ex } ;макрос клавиш на которые происходит реакция macro use_key_process backspase,delete,left,right,home,end,insert { if backspase eq else cmp ah,8 jz .backspace end if if delete eq else cmp ah,0xb6 jz .delete end if if left eq else cmp ah,176 jz .left end if if right eq else cmp ah,179 jz .right end if if home eq else cmp ah,180 jz .home end if if home eq else cmp ah,181 jz .end end if if insert eq else cmp ah,185 ;insert jz .insert end if } macro use_key_no_process up,down,esc { if up eq else cmp ah,177 jz .no_figure end if if down eq else cmp ah,178 jz .no_figure end if if esc eq else cmp ah,27 ;ESC - клавиша )) jz .no_figure end if } macro use_key_figures_only { test word ed_flags,ed_figure_only ; только цифры ? jz @f cmp ah,'0' jb .no_figure cmp ah,'9' ja .no_figure } ; Макрос выхода macro edit_ex { popa ret } macro debug { ;----------- отладка pushad ; mov dword [ed_buffer.2],0 ; mov eax,edi mov eax,dword [ed_buffer.2] mov edi,ed_buffer.3 call .str ;рисование фона mov eax,13 mov ebx,178*65536+70 mov ecx,28*65536+10 xor edx,edx int 0x40 ;вывод значения на экран mov eax,4 mov ebx,180*65536+30 mov ecx,0x10DDBBCC mov edx,ed_buffer.3 mov esi,8 int 0x40 popad ;----------- отладка } macro debug_func { .str: mov ecx,0x0a ;задается система счисления изменяются регистры ebx,eax,ecx,edx входные параметры eax - число ;преревод числа в ASCII строку взодные данные ecx=система счисленя edi адрес куда записывать, будем строку, причем конец переменной cmp eax,ecx ;сравнить если в eax меньше чем в ecx то перейти на @@-1 т.е. на pop eax jb @f xor edx,edx ;очистить edx div ecx ;разделить - остаток в edx push edx ;положить в стек ;dec edi ;смещение необходимое для записи с конца строки call .str;перейти на саму себя т.е. вызвать саму себя и так до того момента пока в eax не станет меньше чем в ecx pop eax @@: ;cmp al,10 ;проверить не меньше ли значение в al чем 10 (для системы счисленя 10 данная команда - лишная)) ;sbb al,$69 ;- честно данная инструкция меня заставляет задуматься т.е. я не знаю как это работает ;das ;после данной команды как бы происходит уменьшение al на 66h (в книге написано другое) or al,0x30 ;данная команда короче чем две выше stosb ;записать элемент из регистра al в ячеку памяти es:edi ret ;вернуться чень интересный ход т.к. пока в стеке храниться кол-во вызовов то столько раз мы и будем вызываться }