diff --git a/programs/develop/libraries/box_lib/branch/box_lib.mac b/programs/develop/libraries/box_lib/branch/box_lib.mac index 490daac4f8..a7440fc3b2 100644 --- a/programs/develop/libraries/box_lib/branch/box_lib.mac +++ b/programs/develop/libraries/box_lib/branch/box_lib.mac @@ -103,9 +103,9 @@ macro edit_boxes_set_sys_color start,end,color_table } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Basic macros for use CheckBox ; -;Last change 03.10.2010 +;Last change 11.10.2010 ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -ch_struc_size=36 ;размер структуры +ch_struc_size=32 ;размер структуры ch_flag_en=10b ;флаг установленного чек бокса. ch_left_s equ [ebp] ;кордината начала рисования по х @@ -115,10 +115,9 @@ ch_color equ [ebp+12] ; ch_border_color equ [ebp+16] ; or [edi+4] ;цвет рамки checkbox ее можно задать самостоятельно ch_text_color equ [ebp+20] ;[edi+4] ;цвет текста ch_text_ptr equ [ebp+24] ;указатель на начало текстовой строки -ch_text_length equ [ebp+28] ;длинна строки -ch_flags equ [ebp+32] ;флаги +ch_flags equ [ebp+28] ;флаги -struc check_box left_s,top_s,ch_text_margin,color,border_color,text_color,text,ch_text_length,flags +struc check_box left_s,top_s,ch_text_margin,color,border_color,text_color,text,flags { ;структура параметров для чек бокса .left_s: dd left_s ;+0 положение по х dw + размер dw .top_s: dd top_s ;+4 положение по у dw + размер dw @@ -127,7 +126,6 @@ struc check_box left_s,top_s,ch_text_margin,color,border_color,text_color,text,c .border_color: dd border_color ;цвет рамки .text_color: dd text_color ;цвет надписи .text: dd text ;адрес в коде программы где расположен текст -.ch_text_length: dd ch_text_length ;длинна строки с символами .flags: dd flags+0 ; флаги } diff --git a/programs/develop/libraries/box_lib/branch/checkbox.asm b/programs/develop/libraries/box_lib/branch/checkbox.asm index 4298d551aa..8c38198688 100644 --- a/programs/develop/libraries/box_lib/branch/checkbox.asm +++ b/programs/develop/libraries/box_lib/branch/checkbox.asm @@ -129,14 +129,14 @@ aCheck_box_draw db 'check_box_draw',0 aCheck_box_mouse db 'check_box_mouse',0 aVersion_ch db 'version_ch',0 ;--------------------------------------------------------------------- -check1 check_box (10 shr 16 + 12),(45 shr 16 + 12),6,0x80AABBCC,0,0,check_text,14,ch_flag_en -check2 check_box (10 shr 16 + 12),(60 shr 16 + 12),6,0x80AABBCC,0,0,check_text2,15 +check1 check_box (10 shr 16 + 12),(45 shr 16 + 12),6,0x80AABBCC,0,0,check_text,ch_flag_en +check2 check_box (10 shr 16 + 12),(60 shr 16 + 12),6,0x80AABBCC,0,0,check_text2 ;--------------------------------------------------------------------- hed db 'CheckBox Exemples date 03.10.2010',0 hed_end: ;--------------------------------------------------------------------- -check_text db 'First checkbox' -check_text2 db 'Second checkbox' +check_text db 'First checkbox',0 +check_text2 db 'Second checkbox',0 ;--------------------------------------------------------------------- MEM_END: cur_dir_path rb 1024 diff --git a/programs/develop/libraries/box_lib/branch/checkbox.mac b/programs/develop/libraries/box_lib/branch/checkbox.mac index 7d85d8bd61..b81591b421 100644 --- a/programs/develop/libraries/box_lib/branch/checkbox.mac +++ b/programs/develop/libraries/box_lib/branch/checkbox.mac @@ -6,71 +6,88 @@ macro use_checkbox_draw { check_box_draw: - pusha ;сохраним все регистры -; mov edi,dword [esp+36] + pushad ;сохраним все регистры + mov ebp,dword [esp+36] ;загружаем указатель на структуру, указатель мы передаем в стеке ; mov ebx,ch_left_s ; mov ecx,ch_top_s ; mov edx,dword ch_border_color ; mov eax,13 ; mcall ;рисуем рамку - mcall 13,ch_left_s,ch_top_s,ch_border_color + mcall 13,ch_left_s,ch_top_s,ch_border_color ;рисуем рамку чек бокса, фактически рисуем прямоугольник и закрашиваем фон внутри цветом рамки бокса - mov edx,dword ch_color + mov edx,dword ch_color ;загружаем цвет фона add ebx,1 shl 16 - 2 add ecx,1 shl 16 - 2 - mcall ;закрашиваем внутренности чекбокса + mcall ;закрашиваем внутренности чекбокса фоном - test dword ch_flags,2 ;достать значение бита из переменной и поместить в флаг CF - jz @f ;в если CF=1, то выполним следующую процедуру иначе перейти на нижнюю @@ - call check_box_draw_ch ;нарисовать включенный чек бокс + test dword ch_flags,2 ;достать значение бита из переменной и поместить в флаг CF + jz @f ;в если CF=1, то выполним следующую процедуру иначе перейти на нижнюю @@ + call check_box_draw_ch ;нарисовать включенный чек бокс @@: ;---------------------------- ;расчет куда будет произведен вывод текста ;---------------------------- - mov ebx,ch_left ;загрузить значение х для чек бокса - add ebx,dword ch_size - add ebx,dword ch_text_margin ;добавить размер стороны и расстояние на котором начнется вывод текста +; mov ebx,dword ch_left_s ;загрузить значение (х shl 16 + длинна) для чек бокса +; add ebx,dword ch_text_margin ;добавим размер стороны и расстояние на котором начнется вывод текста +; shl ebx,16 ;сдвинем на 16 разрядов в лево (умножим на 65536) +; add ebx,dword ch_left_s ;cкорректируем позицию Х. Т.е. сейчас в верхней части ebx у нас точка начала вывода текста по Х + +; mov eax,word ch_top_s ;загрузим значение по (y shl 16 + длинна) для чек бокса +; shl eax,16 ;сдвинем на 16 разрядов в лево (умножим на 65536) +; add eax,dword ch_top_s ;cкорректируем позицию Х. Т.е. сейчас в верхней части ebx у нас точка начала вывода текста по Y + +; Оптимизация для ЦП + mov ebx,dword ch_left_s ;загрузить значение (х shl 16 + длинна) для чек бокса + mov eax,dword ch_top_s ;загрузим значение по (y shl 16 + длинна) для чек бокса + add ebx,dword ch_text_margin ;добавим размер стороны и расстояние на котором начнется вывод текста + shl eax,16 ;сдвинем на 16 разрядов в лево (умножим на 65536) shl ebx,16 ;сдвинем на 16 разрядов в лево (умножим на 65536) - mov bx,word ch_top ;загрузим значение по y - add ebx,ch_size - mov ecx,dword ch_text_color ;загрузим цвет надписи + flags - sub ebx,7 ;добавим значение длины стороны -9+2 - + add eax,dword ch_top_s ;cкорректируем позицию Х. Т.е. сейчас в верхней части ebx у нас точка начала вывода текста по Y + add ebx,dword ch_left_s ;cкорректируем позицию Х. Т.е. сейчас в верхней части ebx у нас точка начала вывода текста по Х + shr eax,16 ;для y поместим в младшую часть + mov bx,ax ;внесем смещение для y + + mov ecx,dword ch_text_color ;загрузим цвет надписи + flags mov edx,dword ch_text_ptr ;укажем адрес от куда нужно выводить строку - mov esi,dword ch_text_length mov eax,4 ;внесем в eax значение вывода надписи на канву mcall ;Вывод - popa ;восстановить значения регистров из стека - ret 4 ;выйдем из процедуры + popad ;восстановить значения регистров из стека + ret 4 ;выйдем из процедуры и удалим из стека указатель на структуру (4 байта) -check_box_clear_ch: ;очистка чек бокса - mov edx,dword ch_color ;цвет внутри чек бокса - jmp @f ;безусловный прыжок на нижнюю метку @@ -check_box_draw_ch: ;нарисовать включенный чек бокс - mov edx,dword ch_border_color ;загрузить цвет +check_box_clear_ch: ;очистка чек бокса + mov edx,dword ch_color ;цвет внутри чек бокса + jmp @f ;безусловный прыжок на нижнюю метку @@ +check_box_draw_ch: ;нарисовать включенный чек бокс + mov edx,dword ch_border_color ;загрузить цвет @@: - movzx ebx,word ch_left ;загрузить координату по х - mov eax,dword ch_size - mov di,ax - shr eax,2 - push ax - - push ax - add ebx,eax - shl ebx,16 ;сдвинем на 16 разрядов в лево (умножим на 65536) - pop ax - lea eax,[eax*2] - sub bp,ax ;сохраним регистр bx в регистре указателя базы - mov bx,bp +; movzx ebx,word ch_left ;загрузить координату по х +; mov eax,dword ch_size +; mov di,ax +; shr eax,2 +; push ax +; +; push ax +; add ebx,eax +; shl ebx,16 ;сдвинем на 16 разрядов в лево (умножим на 65536) +; pop ax +; lea eax,[eax*2] +; sub bp,ax ;сохраним регистр bx в регистре указателя базы +; mov bx,bp - movzx ecx,word ch_top ;загрузить координату по у - pop ax - add cx,ax - shl ecx,16 ;сдвинем на 16 разрядов в лево (умножим на 65536) - mov cx,bp ;загрузим значения регистра указателя базы в cx - mov eax,13 ;в eax - значения функции для вывода полосы т.е. по сути прямоугольника, который отображает включенный компонент чек бокс - mcall ;вывод -ret ;выйти из процедуры +; movzx ecx,word ch_top ;загрузить координату по у +; pop ax +; add cx,ax +; shl ecx,16 ;сдвинем на 16 разрядов в лево (умножим на 65536) +; mov cx,bp ;загрузим значения регистра указателя базы в cx +; mov eax,13 ;в eax - значения функции для вывода полосы т.е. по сути прямоугольника, который отображает включенный компонент чек бокс +; mcall ;вывод + + mov ebx,dword ch_left_s + mov ecx,dword ch_top_s + add ebx,1 shl 16 - 4 + add ecx,1 shl 16 - 4 + mcall 13 + ret } @@ -79,58 +96,105 @@ macro use_checkbox_mouse ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Обработчик mouse +; При попадании мышки + нажата клавиша в область checkbox состояние бокса должно менятся активный - не активный. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; check_box_mouse: ;обработка мыши -pusha - mov edi,dword [esp+36] - mov eax,37 ;будем что то делать если у нас что - нить нажато - mov ebx,2 ;внести в регистр значение 2 - mcall ;проверка не нажал ли пользователь кнопку мышки - test eax,eax ;проверка если у нас в eax=0, то установим флаг и выйдем - jnz @f ;перейти на нижнюю метку @@ - btr dword ch_flags,2 ;извлечение значения заданного бита в флаг cf и изменение его значения на нулевое. - jmp check_box_mouse_end - +pushad + mov ebp,dword [esp+36] ;загружаем указатель на структуру, указатель мы передаем в стеке + mcall 37,2 ;проверяем состояние клавиш мышки. Было ли событие нажатая клавиша на мышке. + test eax,eax ;проверка если у нас в eax=0, то установим флаг и выйдем + jnz @f ;перейти на нижнюю метку @@, если в eax не 0. +; and dword ch_flags,eax ;извлечение значения заданного бита в флаг cf и изменение его значения на нулевое. + jmp .check_box_mouse_end ;обработка закончилась +; Да событие: нажатие клавиши мышки произошло. @@: - bts dword ch_flags,2 ;проверка флага т.е. перенос в cf значение бита и установка бита в состояние включено - jc check_box_mouse_end ;если CF=1 то перейти в конец т.е. это выход - mov esi,dword ch_text_length ;загрузить кол-во символов в текстовой строке + mcall 37,1 ;получить координаты курсора относительно окна + ;на выходе в eax x shl 16 + y +;сравнение верхней точки по Y + mov ecx,dword ch_top_s ;y shl 16 +длинна по y + mov ebx,ecx + shr ebx,16 ;bx = координата по y + cmp ax,bx + jb .check_box_mouse_end ;указатель мышки меньше начальной координаты по y чем координата по Y у бокса +;сравнение нижней точки по Y + add cx,bx ;сложим длинну по y и координату верхней точки по y поличим координату нижней точки по Y + cmp ax,cx + ja .check_box_mouse_end ;указатель мышки больше конечной координаты по y чем координата по Y у бокса +;сравнение по начальной точке Х + mov ecx,dword ch_left_s ;загрузить значение (х shl 16 + длинна) для чек бокса + mov ebx,ecx + shr ebx,16 ;bx = координата по X + cmp ax,bx + jb .check_box_mouse_end ;указатель мышки меньше начальной координаты по X чем координата по X у бокса +;сравнение конечной точки по X + add bx,cx ;сложим длинну по y и координату верхней точки по y поличим координату нижней точки по Y + add ebx,dword ch_text_margin ;добавим размер стороны и расстояние на котором начнется вывод текста + mov ecx,dword ch_text_ptr ;укажем адрес строки с терминируещим 0 + push eax + +;подсчет длинны строки и увеличение прямогольника в котором срабатывает щелчок мышки + lodsb + test al,al + jz .ex_loop +@@: + add bx,6 ;ширина символа + lodsb + test al,al + jnz @b +.ex_loop: + pop eax + cmp ax,bx + ja .check_box_mouse_end ;указатель мышки больше конечной координаты по y чем координата по Y у бокса +;если все проверки были успешно пройдены мы обязаны поменять состояние бокса + btc dword ch_flags,2 ;перенос 2-го бита в cf и инверсия его + jc .enable_box ;если CF=1 то отобразим включенный бокс и выйдем + push dword .check_box_mouse_end ;фокус -покус, вернемся после вызова check_box_clear_ch на метку check_box_mouse_end + jmp check_box_clear_ch ;выключить чек бокс т.е. на месте закрашенного прямоугольника отобразить цвет фона. + +.enable_box: + call check_box_draw_ch ;отобразить включенный чек бокс + + + +; bts dword ch_flags,2 ;проверка флага т.е. перенос в cf значение бита и установка бита в состояние включено +; jc check_box_mouse_end ;если CF=1 то перейти в конец т.е. это выход +; mov esi,dword ch_text_length ;загрузить кол-во символов в текстовой строке ;Умножение на 6 Быстрое умножение можно воспользоваться любым мз методов, но на старых Процессорах (386,486,P1)быстрее будет с инструкцией Lea - lea esi,[eax*3] - shl esi,1 +; lea esi,[eax*3] +; shl esi,1 ; imul esi,6 ; или можно и так умножить на 6 - add esi,dword ch_text_margin ;добавить 3 - расстояние от чек бокса до надписи +; add esi,dword ch_text_margin ;добавить 3 - расстояние от чек бокса до надписи - mov eax,37 ;получим координаты мышки - mov ebx,1 ;добавить 1 - mcall ;получить координаты курсора относительно окна +; mov eax,37 ;получим координаты мышки +; mov ebx,1 ;добавить 1 +; mcall ;получить координаты курсора относительно окна - movzx ebx,word ch_top ;загрузить в bx значение координаты у - cmp ax,bx ;сравнить с с координатой курсора - jl check_box_mouse_end ;SF <> OF если меньше - add ebx,dword ch_size ;добавить размер - cmp ax,bx ;сравнить - jg check_box_mouse_end ;ZF = 0 и SF = OF если больше +; movzx ebx,word ch_top ;загрузить в bx значение координаты у +; cmp ax,bx ;сравнить с с координатой курсора +; jl check_box_mouse_end ;SF <> OF если меньше +; add ebx,dword ch_size ;добавить размер +; cmp ax,bx ;сравнить +; jg check_box_mouse_end ;ZF = 0 и SF = OF если больше - shr eax,16 ;разделим на 65536 или просто сдвинем биты на 16 значений - movzx ebx,word ch_left ;произведем аналогичное сравнение - cmp ax,bx ;сравнить регистры - jl check_box_mouse_end ;если меньше - add ebx,dword ch_size ;добавить длину стороны прямоугольника - add ebx,esi ;Учесть в значении по х еще и длину надписи к чекбоксу - cmp ax,bx ;стравнить регистры - jg check_box_mouse_end ;если больше +; shr eax,16 ;разделим на 65536 или просто сдвинем биты на 16 значений +; movzx ebx,word ch_left ;произведем аналогичное сравнение +; cmp ax,bx ;сравнить регистры +; jl check_box_mouse_end ;если меньше +; add ebx,dword ch_size ;добавить длину стороны прямоугольника +; add ebx,esi ;Учесть в значении по х еще и длину надписи к чекбоксу +; cmp ax,bx ;стравнить регистры +; jg check_box_mouse_end ;если больше - bts dword ch_flags,1 ;извлечение значения заданного бита в флаг cf и изменение его значения на 1. - jc @f ;CF=1 то перейти на нижнюю @@ +; bts dword ch_flags,1 ;извлечение значения заданного бита в флаг cf и изменение его значения на 1. +; jc @f ;CF=1 то перейти на нижнюю @@ - call check_box_draw_ch ;отобразить включенный чек бокс +; call check_box_draw_ch ;отобразить включенный чек бокс ; mov dword [esp+24],1 ;дальнейшая проверка чек боксов бесмыслена, по этому в стек, где располагается ecx поместитм 0 - jmp check_box_mouse_end ;выйти -@@: - btr word ch_flags,1 ;извлечение значения заданного бита в флаг cf и изменение его значения на нулевое. - call check_box_clear_ch ;выключить чек бокс т.е. на месте закрашенного прямоугольника отобразить цвет фона. -check_box_mouse_end: -popa ;восстановить регистры из стека +; jmp check_box_mouse_end ;выйти +;@@: +; btr word ch_flags,1 ;извлечение значения заданного бита в флаг cf и изменение его значения на нулевое. +; call check_box_clear_ch ;выключить чек бокс т.е. на месте закрашенного прямоугольника отобразить цвет фона. +.check_box_mouse_end: +popad ;восстановить регистры из стека ret 4 ;выйти } \ No newline at end of file