Rev 355 | Rev 362 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
355 | Lrz | 1 | ;компонент OptionBox (Основан на Checkbox) |
356 | Lrz | 2 | ;Огромная благодарность Maxxxx32, Diamond, Heavyiron, и другим программистам, и их программам, без |
355 | Lrz | 3 | ;которых я не смог бы написать этот компонент. |
4 | ;16.02.2007 |
||
5 | ; |
||
6 | |||
7 | macro use_option_box |
||
8 | { |
||
9 | op_text_margin=4 ;расстояние от прямоугольника чек бокса до надписи |
||
10 | op_size=10 ;размер квадрата чек бокса |
||
11 | op_left equ [edi] ;координата начала рисования по х |
||
12 | op_top equ [edi+2] ;координата начала рисования по у |
||
356 | Lrz | 13 | op_border_color equ [edi+4] ;цвет рамки optionbox |
14 | op_text_color equ [edi+8] ;цвет текста |
||
15 | op_text_ptr equ [edi+12] ;указатель на начало текстовой строки |
||
16 | op_text_length equ [edi+16] ;длина надписи (2^64 такой длины может быть текст) |
||
17 | op_optibox_gr equ [edi+18] |
||
355 | Lrz | 18 | option_box: |
19 | .draw: |
||
20 | pusha ;сохраним все регистры |
||
21 | mov eax,38 ;рисование линии |
||
22 | movzx ebx,word op_left ;положение по х |
||
23 | mov ecx,ebx ;сохраним в регистре cx значение bx 1 микрооперация |
||
24 | ;push bx ;3 - микрооперации используя стек можно выиграть в размере, используя регистры - в скорости |
||
25 | shl ebx,16 ;сдвинем на 16 разрядов в лево (умножим на 65536) |
||
26 | ;pop bx ;2 - микрооперации на данный момент сформирована [координата начала по оси x]*65536 + [координата начала по оси x] |
||
27 | mov bx,cx ;восстановим значение bx |
||
28 | movzx ecx,word op_top ;загрузим в cx значение y |
||
29 | mov esi,ecx ;сохраним значение регистра cx в регистр указатель si |
||
30 | ;push cx |
||
31 | shl ecx,16 ; сдвинем на 16 разрядов в лево (умножим на 65536) mov cx,si ;восстановим значение регистра cx |
||
32 | mov cx,si ;восстановим значение регистра cx |
||
33 | ;pop cx ;[координата начала по оси y]*65536 + [координата начала по оси y] |
||
34 | ;push cx |
||
35 | add ecx,op_size ;[координата начала по оси y]*65536 + [координата конца по оси y] |
||
356 | Lrz | 36 | mov edx,dword op_border_color ;Цвет линии |
355 | Lrz | 37 | int 0x40 ;рисование вертикальной левой линии квадрата (прямоугольника) |
38 | ; |
||
39 | mov ebp,ebx ;сохраним регистр bx в регистре указателя базы |
||
40 | ;push bx ;втолкнуть в bx [координата начала по оси х]*65536 + [координата начала по оси x] |
||
41 | add ebx,op_size ;[координата начала + длина стороны по оси х] |
||
42 | ror ebx,16 ;[координата начала + дина стороны по оси х]*65536 |
||
43 | add ebx,op_size ;[координата начала+длина стороны по оси х]*65536 + [координата начала+длина стороны по оси x] |
||
44 | int 0x40 |
||
45 | |||
46 | mov bx,bp ;восстановим значение регистра bx |
||
47 | ;pop bx |
||
48 | mov cx,si ;сохраним значение регистра cx в регистр указатель |
||
49 | ;pop cx |
||
50 | int 0x40 |
||
51 | add ecx,op_size ;добавим размер стороны |
||
52 | mov esi,ecx ;сохраним значение регистра cx в регистр указатель si |
||
53 | ;push cx |
||
54 | shl ecx,16 |
||
55 | mov cx,si |
||
56 | ;pop cx |
||
57 | int 0x40 ;нарисовали прямоугольник |
||
58 | |||
59 | mov eax,13 ;закрашиваем его. Функция 13 - нарисовать полосу |
||
60 | movzx ebx,word op_left ;загрузить в bx, положение по х |
||
61 | add ebx,1 ;сдвинем на 1 т.е. прибавим 1 иначе затрется рамка |
||
62 | shl ebx,16 ;сдвинем на 16 разрядов в лево (умножим на 65536) |
||
63 | mov bx,op_size ;прибавим длину стороны прямоугольника |
||
64 | sub ebx,1 ;вычтем 1 т.к. иначе затрется рамка |
||
65 | mov bp,bx ;сохраним регистр bx в регистре указателя базы |
||
66 | ;push bx |
||
67 | movzx ecx,word op_top ;загрузим координаты по y |
||
68 | add ecx,1 ;сдвинем на 1 т.е. прибавим 1 иначе затрется рамка |
||
69 | shl ecx,16 ;сдвинем на 16 разрядов в лево (умножим на 65536) |
||
70 | mov cx,bp ;восстановим значение регистра cx |
||
71 | ;pop cx |
||
356 | Lrz | 72 | mov edx,dword [sc.work] ;загрузим цвет полосы |
355 | Lrz | 73 | int 0x40 ;закрасили |
74 | |||
356 | Lrz | 75 | mov eax,dword op_optibox_gr |
355 | Lrz | 76 | mov dword eax,[eax] |
77 | cmp eax,edi |
||
78 | jne @f |
||
79 | call .draw_op ;нарисовать включенный чек бокс |
||
80 | ;---------------------------- |
||
81 | ;расчет куда будет произведен вывод текста |
||
82 | ;---------------------------- |
||
83 | @@: movzx ebx,word op_left ;загрузить значение х для чек бокса |
||
84 | add ebx,(op_size+op_text_margin) ;добавить размер стороны и расстояние на котором начнется вывод текста |
||
85 | shl ebx,16 ;сдвинем на 16 разрядов в лево (умножим на 65536) |
||
86 | mov bx,op_top ;загрузим значение по y |
||
87 | add ebx,(op_size-9+2) ;добавим значение длины стороны -9+2 |
||
88 | mov ecx,op_text_color ;загрузим цвет надписи |
||
89 | |||
90 | mov edx,op_text_ptr ;укажем адрес от куда нужно выводить строку |
||
91 | movzx esi,word op_text_length ;Загрузим длину надписи в esi |
||
92 | ;внесем в eax значение вывода надписи на канву |
||
93 | mov eax,4 |
||
94 | int 0x40 ;Вывод |
||
95 | popa ;восстановить значения регистров из стека |
||
96 | ret ;выйдем из процедуры |
||
97 | |||
98 | .clear_op: ;очистка чек бокса |
||
356 | Lrz | 99 | mov edx,dword [sc.work] ;цвет внутри чек бокса |
355 | Lrz | 100 | jmp @f ;безусловный прыжок на нижнюю метку @@ |
101 | |||
102 | .draw_op: ;нарисовать включенный чек бокс |
||
103 | mov edx,op_border_color ;загрузить цвет |
||
104 | @@: |
||
105 | movzx ebx,word op_left ;загрузить координату по х |
||
106 | add ebx,(op_size/3) ;добавить (сторона прямоугольника/3) |
||
107 | shl ebx,16 ;сдвинем на 16 разрядов в лево (умножим на 65536) |
||
108 | mov bx,(op_size/2) ;загрузить (сторона прямоугольника/2) |
||
109 | mov bp,bx ;сохраним регистр bx в регистре указателя базы |
||
110 | ;push bx |
||
111 | movzx ecx,word op_top ;загрузить координату по у |
||
112 | mov eax,13 ;в eax - значения функции для вывода полосы т.е. по сути прямоугольника, который отображает включенный компонент чек бокс |
||
113 | add ecx,(op_size/3) ;добавить (сторона прямоугольника/3) |
||
114 | shl ecx,16 ;сдвинем на 16 разрядов в лево (умножим на 65536) |
||
115 | mov cx,bp ;загрузим значения регистра указателя базы в cx |
||
116 | ;pop cx |
||
117 | int 0x40 ;вывод |
||
118 | ret ;выйти из процедуры |
||
119 | |||
120 | .mouse: ;обработка мыши |
||
121 | pusha |
||
122 | mov eax,37 ;будем что то делать если у нас что - нить нажато |
||
123 | mov ebx,2 ;внести в регистр значение 2 |
||
124 | int 0x40 ;проверка не нажал ли пользователь кнопку мышки |
||
125 | test eax,eax ;проверка если у нас в eax=0, то установим флаг и выйдем |
||
126 | jnz @f ;перейти на нижнюю метку @@ |
||
127 | popa ;если ничего не произошло, то восстановим значения регистров из стека |
||
128 | ret ;выход |
||
129 | @@: |
||
130 | movzx esi,word op_text_length ;загрузить кол-во символов в текстовой строке |
||
131 | ;Умножение на 6 Быстрое умножение можно воспользоваться любым мз методов, но на старых Процессорах (386,486,P1)быстрее будет с инструкцией Lea |
||
132 | ;lea esi,[eax*2+eax] |
||
133 | ;shl eax,1 |
||
134 | imul esi,6 ; или можно и так умножить на 6 |
||
356 | Lrz | 135 | xor ebx,ebx |
355 | Lrz | 136 | add esi,op_text_margin ;добавить 3 - расстояние от чек бокса до надписи |
137 | |||
138 | mov eax,37 ;получим координаты мышки |
||
356 | Lrz | 139 | inc ebx ;добавить 1 |
355 | Lrz | 140 | int 0x40 ;получить координаты курсора относительно окна |
141 | |||
142 | movzx ebx,word op_top ;загрузить в bx значение координаты у |
||
143 | cmp ax,bx ;сравнить с с координатой курсора |
||
144 | jl .mouse_end ;SF <> OF если меньше |
||
145 | add ebx,op_size ;добавить размер |
||
146 | cmp ax,bx ;сравнить |
||
147 | jg .mouse_end ;ZF = 0 и SF = OF если больше |
||
148 | |||
149 | shr eax,16 ;разделим на 65536 или просто сдвинем биты на 16 значений |
||
150 | movzx ebx,word op_left ;произведем аналогичное сравнение |
||
151 | cmp ax,bx ;сравнить регистры |
||
152 | jl .mouse_end ;если меньше |
||
153 | add ebx,op_size ;добавить длину стороны прямоугольника |
||
356 | Lrz | 154 | add ebx,esi ;Учесть в значении по х еще и длину надписи к чекбоксу |
355 | Lrz | 155 | cmp ax,bx ;стравнить регистры |
156 | jg .mouse_end ;если больше |
||
356 | Lrz | 157 | mov eax,dword op_optibox_gr |
355 | Lrz | 158 | mov [eax],edi |
159 | |||
160 | .mouse_end: |
||
161 | popa ;восстановить регистры из стека |
||
162 | ret ;выйти |
||
163 | } |
||
164 | |||
356 | Lrz | 165 | struc option_box left,top,border_color,text_color,text,text_length,point_gr,flags |
355 | Lrz | 166 | { ;структура параметров для чек бокса |
167 | .left: dw left ;+0 ;положение по х |
||
168 | .top: dw top ;+2 ;положение по у |
||
169 | .border_color: dd border_color ;+8 цвет рамки |
||
170 | .text_color: dd text_color ;+12 цвет текста надписи |
||
171 | .text: dd text ;+16 адрес в коде программы где расположен текстр |
||
172 | .text_length: dw text_length ; +20 длина текста |
||
173 | .option_group: dd point_gr ;указатель на размещение edi - идентификатора optibox |
||
174 | } |
||
356 | Lrz | 175 | op_struc_size=22 ;общая структура 24 байт |
355 | Lrz | 176 | op_flag_en=10b |
177 | macro draw_option_boxes start,end ;рисовать чек боксы |
||
178 | { |
||
179 | mov edi,start ;Указатель на начало данных чек боксов т.е. на начало данных первого чекбокса |
||
180 | mov ecx,((end-start)/op_struc_size) ;Количество чек боксов |
||
181 | @@: |
||
182 | call option_box.draw ;Отобразить чек бокс |
||
183 | add edi,op_struc_size ;Указатель на последующие чек боксы т.е. +28 |
||
184 | loop @b ;прыгнуть если в ecx/cx значение не 0 на верхнюю @@ |
||
185 | } |
||
186 | macro mouse_option_boxes start,end ;установка чек боксов, в зависимости от события |
||
187 | { |
||
188 | mov edi,start ; Указатель на начало данных чек боксов т.е. на начало данных первого чекбокса |
||
189 | mov ecx,((end-start)/op_struc_size) ;Количество чек боксов |
||
190 | @@: |
||
191 | call option_box.mouse ;проверка мышки и обработка событий |
||
192 | add edi,op_struc_size ;Указатель на последующие чек боксы |
||
193 | loop @b ;прыгнуть если в ecx/cx значение не 0 на верхнюю @@ |
||
194 | |||
195 | mov edi,start ; Указатель на начало данных чек боксов т.е. на начало данных первого чекбокса |
||
196 | mov ecx,((end-start)/op_struc_size) ;Количество чек боксов |
||
197 | |||
198 | .home: |
||
356 | Lrz | 199 | mov eax,[edi+18] ;op_optibox_gr |
355 | Lrz | 200 | mov dword eax,[eax] |
201 | |||
202 | pusha |
||
203 | |||
204 | cmp eax,edi |
||
205 | jne @f |
||
206 | |||
207 | call option_box.draw_op |
||
208 | jmp .nxtm |
||
209 | @@: call option_box.clear_op |
||
210 | |||
211 | .nxtm: popa |
||
212 | add edi,op_struc_size ;Указатель на последующие чек боксы т.е. +28 |
||
213 | loop .home |
||
214 | |||
215 | }> |