Rev 360 | Rev 383 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
144 | Lrz | 1 | ;Оптимизированный компонент CheckBox (Исходный вариант от Maxxxx32) |
2 | ;Оптимизирован вывод строки надписи для CheckBox'a + теперь, при проверке не происходит подсчет кол-ва символов в строке |
||
3 | ;Оптимизация команд - отказался от сохранения регистров в стеке. |
||
366 | Lrz | 4 | ;21.02.2007 добавил код от Heavyiron, дописал макросы для использования системных цветов |
360 | Lrz | 5 | ;19.02.2007 общее улучшение кода, уменьшение размера и использование системных цветов для отображения checkbox |
144 | Lrz | 6 | ;17.07.2006 произведена оптимизация, при установке чек бокса в положение включено последующие чек боксы в тот же промежуток времени не проверяются |
7 | ;22.08.2006 произведена оптимизация команд, приняты во внимание замечания DIAMOND'а. |
||
360 | Lrz | 8 | ; |
144 | Lrz | 9 | |
366 | Lrz | 10 | macro version_ch ;для совместимости со старыми версиями checkbox все цвета задаются ручками |
144 | Lrz | 11 | { |
366 | Lrz | 12 | ch_struc_size=24 |
144 | Lrz | 13 | ch_left equ [edi] ;координата начала рисования по х |
14 | ch_top equ [edi+2] ;координата начала рисования по у |
||
366 | Lrz | 15 | ch_color equ [edi+4] |
16 | ch_border_color equ [edi+8] ; or [edi+4] ;цвет рамки checkbox ее можно задать самостоятельно |
||
17 | ch_text_color equ [edi+12];[edi+4] ;цвет текста |
||
18 | ch_text_ptr equ [edi+16] ;указатель на начало текстовой строки |
||
19 | ch_text_length equ [edi+20] ;длина надписи (2^64 такой длины может быть текст) |
||
20 | ch_flags equ [edi+22] ;флаги |
||
21 | } |
||
22 | |||
23 | macro version_ch1 ;продвинутая версия, использует цвета скина. |
||
24 | { |
||
25 | ch_struc_size=12 |
||
26 | ch_left equ [edi] ;координата начала рисования по х |
||
27 | ch_top equ [edi+2] ;координата начала рисования по у |
||
28 | ch_color equ [sc.work] ; |
||
360 | Lrz | 29 | ch_border_color equ [sc.work_graph] ; or [edi+4] ;цвет рамки checkbox ее можно задать самостоятельно |
30 | ch_text_color equ [sc.work_text];[edi+4] ;цвет текста |
||
31 | ch_text_ptr equ [edi+4] ;указатель на начало текстовой строки |
||
32 | ch_text_length equ [edi+8] ;длина надписи (2^64 такой длины может быть текст) |
||
33 | ch_flags equ [edi+10] ;флаги |
||
366 | Lrz | 34 | } |
35 | |||
36 | macro use_check_box |
||
37 | { |
||
38 | ch_text_margin=4 ;расстояние от прямоугольника чек бокса до надписи |
||
39 | ch_size=12 ;размер квадрата чек бокса |
||
144 | Lrz | 40 | check_box: |
41 | .draw: |
||
366 | Lrz | 42 | pusha ;сохраним все регистры |
43 | mov eax,13 |
||
44 | mov ebx,ch_left |
||
45 | shl ebx,16 |
||
46 | add ebx,ch_size |
||
47 | mov ecx,ch_top |
||
48 | shl ecx,16 |
||
49 | add ecx,ch_size |
||
50 | mov edx,ch_border_color |
||
51 | int 0x40 ;рисуем рамку |
||
144 | Lrz | 52 | |
366 | Lrz | 53 | mov edx,ch_color |
54 | add ebx,1 shl 16 - 2 |
||
55 | add ecx,1 shl 16 - 2 |
||
56 | int 0x40 ;закрашиваем внутренности чекбокса |
||
360 | Lrz | 57 | |
366 | Lrz | 58 | test word ch_flags,2 ;достать значение бита из переменной и поместить в флаг CF |
59 | jz @f ;в если CF=1, то выполним следующую процедуру иначе перейти на нижнюю @@ |
||
60 | call .draw_ch ;нарисовать включенный чек бокс |
||
144 | Lrz | 61 | @@: |
62 | ;---------------------------- |
||
63 | ;расчет куда будет произведен вывод текста |
||
64 | ;---------------------------- |
||
366 | Lrz | 65 | movzx ebx,word ch_left ;загрузить значение х для чек бокса |
66 | add ebx,(ch_size+ch_text_margin) ;добавить размер стороны и расстояние на котором начнется вывод текста |
||
67 | shl ebx,16 ;сдвинем на 16 разрядов в лево (умножим на 65536) |
||
68 | mov bx,ch_top ;загрузим значение по y |
||
69 | add ebx,(ch_size-9+2) ;добавим значение длины стороны -9+2 |
||
70 | mov ecx,ch_text_color ;загрузим цвет надписи |
||
71 | |||
72 | mov edx,ch_text_ptr ;укажем адрес от куда нужно выводить строку |
||
73 | movzx esi,word ch_text_length ;Загрузим длину надписи в esi |
||
74 | ;внесем в eax значение вывода надписи на канву |
||
75 | mov eax,4 |
||
76 | int 0x40 ;Вывод |
||
77 | popa ;восстановить значения регистров из стека |
||
78 | ret ;выйдем из процедуры |
||
144 | Lrz | 79 | |
366 | Lrz | 80 | .clear_ch: ;очистка чек бокса |
81 | mov edx,ch_color ;цвет внутри чек бокса |
||
82 | jmp @f ;безусловный прыжок на нижнюю метку @@ |
||
144 | Lrz | 83 | |
84 | .draw_ch: ;нарисовать включенный чек бокс |
||
366 | Lrz | 85 | mov edx,ch_border_color ;загрузить цвет |
144 | Lrz | 86 | @@: |
366 | Lrz | 87 | movzx ebx,word ch_left ;загрузить координату по х |
88 | add ebx,(ch_size/4) ;добавить (сторона прямоугольника/3) |
||
89 | shl ebx,16 ;сдвинем на 16 разрядов в лево (умножим на 65536) |
||
90 | mov bx,(ch_size/2) ;загрузить (сторона прямоугольника/2) |
||
91 | mov bp,bx ;сохраним регистр bx в регистре указателя базы |
||
92 | ;push bx |
||
93 | movzx ecx,word ch_top ;загрузить координату по у |
||
94 | mov eax,13 ;в eax - значения функции для вывода полосы т.е. по сути прямоугольника, который отображает включенный компонент чек бокс |
||
95 | add ecx,(ch_size/4) ;добавить (сторона прямоугольника/3) |
||
96 | shl ecx,16 ;сдвинем на 16 разрядов в лево (умножим на 65536) |
||
97 | mov cx,bp ;загрузим значения регистра указателя базы в cx |
||
98 | ;pop cx |
||
99 | int 0x40 ;вывод |
||
100 | ret ;выйти из процедуры |
||
101 | .mouse: ;обработка мыши |
||
144 | Lrz | 102 | pusha |
366 | Lrz | 103 | mov eax,37 ;будем что то делать если у нас что - нить нажато |
104 | mov ebx,2 ;внести в регистр значение 2 |
||
105 | int 0x40 ;проверка не нажал ли пользователь кнопку мышки |
||
106 | test eax,eax ;проверка если у нас в eax=0, то установим флаг и выйдем |
||
107 | jnz @f ;перейти на нижнюю метку @@ |
||
108 | btr word ch_flags,2 ;извлечение значения заданного бита в флаг cf и изменение его значения на нулевое. |
||
109 | popa ;если ничего не произошло, то восстановим значения регистров из стека |
||
110 | ret ;выход |
||
144 | Lrz | 111 | @@: |
366 | Lrz | 112 | bts word ch_flags,2 ;проверка флага т.е. перенос в cf значение бита и установка бита в состояние включено |
113 | jc .mouse_end ;если CF=1 то перейти в конец т.е. это выход |
||
114 | movzx esi,word ch_text_length ;загрузить кол-во символов в текстовой строке |
||
115 | ;Умножение на 6 Быстрое умножение можно воспользоваться любым мз методов, но на старых Процессорах (386,486,P1)быстрее будет с инструкцией Lea |
||
116 | ;lea esi,[eax*2+eax] |
||
117 | ;shl eax,1 |
||
118 | imul esi,6 ; или можно и так умножить на 6 |
||
119 | add esi,ch_text_margin ;добавить 3 - расстояние от чек бокса до надписи |
||
144 | Lrz | 120 | |
366 | Lrz | 121 | mov eax,37 ;получим координаты мышки |
122 | mov ebx,1 ;добавить 1 |
||
123 | int 0x40 ;получить координаты курсора относительно окна |
||
124 | |||
125 | movzx ebx,word ch_top ;загрузить в bx значение координаты у |
||
126 | cmp ax,bx ;сравнить с с координатой курсора |
||
127 | jl .mouse_end ;SF <> OF если меньше |
||
128 | add ebx,ch_size ;добавить размер |
||
129 | cmp ax,bx ;сравнить |
||
130 | jg .mouse_end ;ZF = 0 и SF = OF если больше |
||
131 | |||
132 | shr eax,16 ;разделим на 65536 или просто сдвинем биты на 16 значений |
||
133 | movzx ebx,word ch_left ;произведем аналогичное сравнение |
||
134 | cmp ax,bx ;сравнить регистры |
||
135 | jl .mouse_end ;если меньше |
||
136 | add ebx,ch_size ;добавить длину стороны прямоугольника |
||
137 | add ebx,esi ;Учесть в значении по х еще и длину надписи к чекбоксу |
||
138 | cmp ax,bx ;стравнить регистры |
||
139 | jg .mouse_end ;если больше |
||
140 | |||
141 | bts word ch_flags,1 ;извлечение значения заданного бита в флаг cf и изменение его значения на 1. |
||
142 | jc @f ;CF=1 то перейти на нижнюю @@ |
||
143 | |||
144 | call .draw_ch ;отобразить включенный чек бокс |
||
145 | mov dword [esp+24],1 ;дальнейшая проверка чек боксов бесмыслена, по этому в стек, где располагается ecx поместитм 0 |
||
146 | jmp .mouse_end ;выйти |
||
144 | Lrz | 147 | @@: |
366 | Lrz | 148 | btr word ch_flags,1 ;извлечение значения заданного бита в флаг cf и изменение его значения на нулевое. |
149 | call .clear_ch ;выключить чек бокс т.е. на месте закрашенного прямоугольника отобразить цвет фона. |
||
144 | Lrz | 150 | .mouse_end: |
366 | Lrz | 151 | popa ;восстановить регистры из стека |
152 | ret ;выйти |
||
144 | Lrz | 153 | } |
154 | |||
366 | Lrz | 155 | struc check_box1 left,top,text,text_length,flags |
156 | { ;структура параметров для чек бокса |
||
157 | .left: dw left ;+0 положение по х |
||
158 | .top: dw top ;+2 положение по у |
||
159 | .text: dd text ;+16 адрес в коде программы где расположен текстр |
||
160 | .text_length: dw text_length ;+20 длина текста |
||
161 | .flags: dw flags+0 ;+22 флаги |
||
144 | Lrz | 162 | } |
366 | Lrz | 163 | struc check_box left,top,color,border_color,text_color,text,text_length,flags |
164 | { ;структура параметров для чек бокса |
||
165 | .left: dw left ;+0 ;положение по х |
||
166 | .top: dw top ;положение по у |
||
167 | .color: dd color ;цвет внутри чекбокса |
||
168 | .border_color: dd border_color ;цвет рамки |
||
169 | .text_color: dd text_color ;цвет надписи |
||
170 | .text: dd text ;адрес в коде программы где расположен текст |
||
171 | .text_length: dw text_length ;длина текста |
||
172 | .flags: dw flags+0 ;+22 |
||
173 | } |
||
360 | Lrz | 174 | ch_flag_en=10b |
366 | Lrz | 175 | |
176 | macro draw_check_boxes start,end ;рисовать чек боксы |
||
144 | Lrz | 177 | { |
366 | Lrz | 178 | mov edi,start ;Указатель на начало данных чек боксов т.е. на начало данных первого чекбокса |
179 | mov ecx,((end-start)/ch_struc_size) ;Количество чек боксов |
||
144 | Lrz | 180 | @@: |
366 | Lrz | 181 | call check_box.draw ;Отобразить чек бокс |
182 | add edi,ch_struc_size ;Указатель на последующие чек боксы т.е. +28 |
||
183 | loop @b ;прыгнуть если в ecx/cx значение не 0 на верхнюю @@ |
||
144 | Lrz | 184 | } |
366 | Lrz | 185 | macro mouse_check_boxes start,end ;установка чек боксов, в зависимости от события |
144 | Lrz | 186 | { |
366 | Lrz | 187 | mov edi,start ; Указатель на начало данных чек боксов т.е. на начало данных первого чекбокса |
188 | mov ecx,((end-start)/ch_struc_size) ;Количество чек боксов |
||
189 | @@: |
||
190 | call check_box.mouse ;проверка мышки и обработка событий |
||
191 | add edi,ch_struc_size ;Указатель на последующие чек боксы |
||
192 | loop @b ;прыгнуть если в ecx/cx значение не 0 на верхнюю @@ |
||
193 | } |
||
194 | ;Если нужно отобразить один чекер |
||
195 | macro draw_check_box start ;рисовать чек боксы |
||
196 | { |
||
197 | mov edi,start ;Указатель на начало данных чек боксов т.е. на начало данных первого чекбокса |
||
198 | call check_box.draw ;Отобразить чек бокс |
||
199 | } |
||
200 | macro mouse_check_box start ;установка чек боксов, в зависимости от события |
||
201 | { |
||
202 | mov edi,start ; Указатель на начало данных чек боксов т.е. на начало данных первого чекбокса |
||
203 | call check_box.mouse ;проверка мышки и обработка событий |
||
144 | Lrz | 204 | }> |