Rev 31 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
31 | halyavin | 1 | ; |
2 | ; DESKTOP CONTEXT MENU |
||
3 | ; written by Ivan Poddubny |
||
4 | ; |
||
5 | ; Автор - Иван Поддубный |
||
6 | ; e-mail: ivan-yar@bk.ru |
||
7 | ; |
||
8 | ; Compile with flat assembler |
||
9 | ; |
||
10 | include 'lang.inc' |
||
11 | include 'macros.inc' |
||
12 | |||
13 | meos_app_start |
||
14 | code |
||
15 | |||
16 | mov [start_info.mode], 16 |
||
17 | mov [start_info.params], 0 |
||
18 | mov [start_info.workarea], work_area |
||
19 | |||
20 | mov eax,40 ; установим маску событий |
||
21 | mov ebx,100000b ; нас интересует только мышь |
||
22 | int 0x40 |
||
23 | |||
24 | still: ; главный цикл основного процесса |
||
25 | |||
26 | mov eax,10 ; ждём события |
||
27 | int 0x40 |
||
28 | |||
29 | cmp eax,6 ; мышь? |
||
30 | jne still |
||
31 | |||
32 | mov eax,37 ; какие нажаты кпопки? |
||
33 | mov ebx,2 |
||
34 | int 0x40 |
||
35 | |||
36 | cmp eax,2 ; если не правая, возврат |
||
37 | jne still |
||
38 | |||
39 | ;---поехали!--- |
||
40 | |||
41 | ; mov eax,37 ; это для отладки - если мышь в точке (0;0), закроемся |
||
42 | ; xor ebx,ebx |
||
43 | ; int 0x40 |
||
44 | ; test eax,eax ; курсор в точке (0;0), т.е. eax = 0 |
||
45 | ; je exit |
||
46 | |||
47 | |||
48 | mov eax,9 ; получим число процессов в системе |
||
49 | mov ebx,procinfo |
||
50 | xor ecx,ecx |
||
51 | int 0x40 |
||
52 | |||
53 | inc eax ; теперь в eax содержится число процессов + 1 |
||
54 | mov [processes],eax |
||
55 | mov ecx,1 |
||
56 | |||
57 | new_process: |
||
58 | pushad |
||
59 | mov eax,9 ; получим информацию о процессе; номер - в ecx |
||
60 | mov ebx,procinfo |
||
61 | int 0x40 |
||
62 | mov eax,37 ; координаты курсора |
||
63 | xor ebx,ebx |
||
64 | int 0x40 |
||
65 | mov ebx,eax ; eax = cursor_x |
||
66 | shr eax,16 ; ebx = cursor_y |
||
67 | and ebx,0xffff |
||
68 | mov [curx1],eax ; curx1 = cursor_x |
||
69 | mov [cury1],ebx ; cury1 = cursor_y |
||
70 | mov eax,[procinfo.x_start] ; eax = wnd_x_start |
||
71 | mov ebx,[procinfo.y_start] ; ebx = wnd_y_start |
||
72 | |||
73 | mov ecx,[procinfo.x_size] |
||
74 | add ecx,eax ; ecx = wnd_x_end |
||
75 | mov edx,[procinfo.y_size] |
||
76 | add edx,ebx ; ecx = wnd_y_end |
||
77 | |||
78 | cmp eax,[curx1] ; wnd_x_start > cursor_x => курсор левее окна |
||
79 | jg ne_goden |
||
80 | cmp ecx,[curx1] ; wnd_x_end < cursor_x => курсор правее окна |
||
81 | jl ne_goden |
||
82 | cmp ebx,[cury1] ; wnd_y_start > cursor_y => курсор выше окна |
||
83 | jg ne_goden |
||
84 | cmp edx,[cury1] ; wnd_y_end < cursor_y => курсор ниже окна |
||
85 | jl ne_goden |
||
86 | |||
87 | goden: ; клик был внутри какого-то окна, поэтому ничего не делаем |
||
88 | popad |
||
89 | jmp still |
||
90 | |||
91 | ne_goden: ; клик был снаружи рассматриваемого окна, поэтому |
||
92 | popad |
||
93 | inc ecx |
||
94 | cmp ecx,[processes] |
||
95 | jl new_process ; либо сморим следующее окно, либо запускаем меню |
||
96 | |||
97 | |||
98 | @@: ; подождём, пока пользователь не отпустил правую кнопку мыши |
||
99 | mov eax,37 |
||
100 | mov ebx,2 ; функция 37-2: |
||
101 | int 0x40 ; нажаты ли кнопки мыши? |
||
102 | cmp eax,ebx ; если отпустил, (eax != 2) |
||
103 | jnz @f ; идём в начало главного цикла |
||
104 | |||
105 | mov eax,5 ; иначе |
||
106 | mov ebx,2 ; подождём 2 мс |
||
107 | int 0x40 |
||
108 | |||
109 | jmp @b ; и проверим мышь опять |
||
110 | @@: |
||
111 | |||
112 | ; если уже было открыто меню, нужно подождать, пока оно закроется: |
||
113 | @@: |
||
114 | cmp [menu_opened],0 |
||
115 | je @f |
||
116 | mov eax,5 |
||
117 | mov ebx,3 ; ждём 3 мс |
||
118 | int 0x40 |
||
119 | jmp @b |
||
120 | @@: |
||
121 | |||
122 | mov eax,51 ; а теперь можно смело запускать процесс (поток) меню |
||
123 | mov ebx,1 ; создаём поток (thread) |
||
124 | mov ecx,start_wnd ; точка входа потока |
||
125 | mov edx,stack_wnd ; вершина стэка для потока |
||
126 | int 0x40 |
||
127 | |||
128 | jmp still |
||
129 | |||
130 | |||
131 | |||
132 | exit_menu: ; если выходим из меню, надо записать в [menu_opened] 0 |
||
133 | mov [menu_opened],0 |
||
134 | exit: ; сюда мы идём, когда выходим из основного процесса |
||
135 | or eax,-1 ; eax = -1 |
||
136 | int 0x40 |
||
137 | |||
138 | |||
139 | |||
140 | |||
141 | ; здесь стартует процесс меню |
||
142 | start_wnd: |
||
143 | mov [menu_opened],1 |
||
144 | call draw_window |
||
145 | |||
146 | mov eax,40 ; установим маску желаемых событий для этого процесса |
||
147 | mov ebx,100101b ; меню + кнопки + перерисовка |
||
148 | int 0x40 |
||
149 | |||
150 | still2: ; главный цикл процесса меню |
||
151 | |||
152 | mov eax,10 ; ждём события |
||
153 | int 0x40 |
||
154 | |||
155 | cmp eax,1 ; перерисовка? |
||
156 | je red |
||
157 | cmp eax,3 ; кнопка? |
||
158 | je button |
||
159 | cmp eax,6 ; мышь? |
||
160 | je mouse |
||
161 | |||
162 | jmp still2 ; вернёмся в начало главного цикла |
||
163 | |||
164 | |||
165 | ; ОБРАБОТЧИК МЫШИ |
||
166 | mouse: ; когда пользователь нажмёт кнопку мыши, закроемся |
||
167 | mov eax,37 |
||
168 | mov ebx,2 ; какие кнопки нажаты? |
||
169 | int 0x40 |
||
170 | test eax,eax ; никакие? - тогда прекрасно! вернёмся в гланый цикл |
||
171 | jz still2 |
||
172 | jmp exit_menu ; а если всё-таки нажаты - закроем окно |
||
173 | |||
174 | |||
175 | ; ПЕРЕРИСОВАТЬ ОКНО |
||
176 | red: |
||
177 | call draw_window |
||
178 | jmp still2 |
||
179 | |||
180 | |||
181 | ; НАЖАТА КНОПКА |
||
182 | button: |
||
183 | mov eax,17 ; получить идентификатор нажатой кнопки |
||
184 | int 0x40 |
||
185 | |||
186 | cmp ah,10 ; сравниваем с 10 |
||
187 | jl nofuncbtns ; если меньше - закрываем меню |
||
188 | |||
189 | add ah,-10 ; вычтем из идентификатора кнопки 10 |
||
190 | movzx ebx,ah ; получили номер программы в списке в ebx |
||
191 | lea esi, [startapps + ebx*4] |
||
192 | lea edi, [start_info.path] |
||
193 | mov esi, [esi] |
||
194 | cld |
||
195 | @@: |
||
196 | lodsb |
||
197 | stosb |
||
198 | test al, al |
||
199 | jnz @b |
||
200 | mcall 58, start_info |
||
201 | |||
202 | ; mov eax,5 ; подождём, пока программа запуститься |
||
203 | ; mov ebx,1 ; а то её окно не будет отрисовано (баг в ядре???) |
||
204 | ; int 0x40 ; раскомментируйте эти строки, если у вас проблемы |
||
205 | ; с отрисовкой |
||
206 | |||
207 | nofuncbtns: ; закрываем меню |
||
208 | jmp exit_menu |
||
209 | |||
210 | |||
211 | |||
212 | _BTNS_ = 8 ; количество кнопок ("пунктов меню") |
||
213 | |||
214 | if lang eq ru |
||
215 | font = 0x00000000 |
||
216 | string_length = 20 ; длина строки |
||
217 | wnd_x_size = 133 ; ширина окна |
||
218 | header_pos = 36 shl 16 + 7 |
||
219 | else |
||
220 | font = 0x10000000 |
||
221 | string_length = 12 ; длина строки |
||
222 | wnd_x_size = 105 ; ширина окна |
||
223 | header_pos = 23 shl 16 + 7 |
||
224 | end if |
||
225 | |||
226 | ;******************************* |
||
227 | ;******** РИСУЕМ ОКНО ******** |
||
228 | ;******************************* |
||
229 | |||
230 | draw_window: |
||
231 | |||
232 | mov eax,12 ; начинаем "рисовать" |
||
233 | mov ebx,1 |
||
234 | int 0x40 |
||
235 | |||
236 | mov eax,[curx1] ; текущие координаты курсора |
||
237 | mov [curx],eax ; запишем в координаты окна |
||
238 | mov eax,[cury1] |
||
239 | mov [cury],eax |
||
240 | |||
241 | ; теперь будем считать координаты окна, чтобы оно за край экрана не вылезло |
||
242 | mov eax,14 ; получим размер экрана |
||
243 | int 0x40 |
||
244 | mov ebx,eax |
||
245 | shr eax,16 ; в eax - x_screen |
||
246 | and ebx,0xffff ; в ebx - y_screen |
||
247 | add eax,-wnd_x_size ; eax = [x_screen - ширина окна] |
||
248 | add ebx,-_BTNS_*15-21 ; ebx = [y_screen - высота окна] |
||
249 | |||
250 | cmp eax,[curx] |
||
251 | jg .okx ; если окно слишком близко к правому краю, |
||
252 | add [curx],-wnd_x_size ; сдвинем его влево на 100 |
||
253 | .okx: |
||
254 | |||
255 | cmp ebx, [cury] |
||
256 | jg .oky ; по вертикали точно также |
||
257 | add [cury], -_BTNS_*15-21 |
||
258 | .oky: |
||
259 | |||
260 | mov eax, 48 ; получить системные цвета |
||
261 | mov ebx, 3 |
||
262 | mov ecx, sc ; адрес структуры |
||
263 | mov edx, sizeof.system_colors ; и ее размер |
||
264 | int 0x40 |
||
265 | |||
266 | xor eax, eax ; функция 0 - создать окно |
||
267 | mov ebx, [curx] ; ebx = [координата по x] shl 16 + [ширина] |
||
268 | shl ebx, 16 |
||
269 | add ebx, wnd_x_size |
||
270 | mov ecx, [cury] ; ecx = [координата по y] shl 16 + [высота] |
||
271 | shl ecx, 16 |
||
272 | add ecx, _BTNS_*15+21 |
||
273 | mov edx, [sc.work] ; цвет рабочей области |
||
274 | mov esi, [sc.grab] ; цвет заголовка |
||
275 | or esi, 0x81000000 |
||
276 | mov edi, [sc.frame] ; цвет рамки |
||
277 | int 0x40 |
||
278 | |||
279 | mov eax, 4 ; заголовок |
||
280 | mov ebx, header_pos ; [x] shl 16 + [y] |
||
281 | mov ecx, [sc.grab_text]; шрифт и цвет (серый) |
||
282 | add ecx, -0x333333 |
||
283 | or ecx, 0x10000000 |
||
284 | mov edx, header ; адрес заголовка |
||
285 | mov esi, header.size ; длина заголовка ("M E N U") |
||
286 | int 0x40 |
||
287 | add ecx, 0x333333 ; цвет белый |
||
288 | add ebx, 1 shl 16 ; сдвинем вправо на 1 |
||
289 | int 0x40 |
||
290 | |||
291 | mov ebx, 1*65536+wnd_x_size-2 ; начинаем делать кнопки |
||
292 | mov ecx, 20*65536+15 |
||
293 | mov edx, 10 or 0x40000000 ; бит 30 установлен => кнопка не рисуется |
||
294 | |||
295 | mov edi,_BTNS_ ; количество кнопок (счётчик) |
||
296 | |||
297 | newbtn: ; начало цикла |
||
298 | mov eax,8 ; создаём кнопку |
||
299 | int 0x40 |
||
300 | |||
301 | ; пишем текст на кнопке |
||
302 | pushad ; спасаем регистры |
||
303 | shr ecx, 16 |
||
304 | and ebx, 0xffff0000 |
||
305 | add ebx, ecx ; ebx = [x] shl 16 + [y]; |
||
306 | add ebx, 10*65536+4 ; ebx += смещение относительно края кнопки; |
||
307 | mov ecx, [sc.work_text] ; шрифт и цвет |
||
308 | or ecx, font |
||
309 | add edx, -10 ; edx = номер кнопки; |
||
310 | imul edx, string_length ; edx *= длина строки; |
||
311 | add edx, text ; edx += text; теперь в edx адрес строки |
||
312 | mov esi, string_length ; в esi - длина строки |
||
313 | mov eax, 4 ; функция 4 - вывод текста |
||
314 | int 0x40 |
||
315 | popad |
||
316 | |||
317 | inc edx ; номер кнопки++; |
||
318 | add ecx,15*65536 ; увеличим смещение по y |
||
319 | dec edi ; уменьшим счётчик |
||
320 | jnz newbtn ; если не ноль, повторим всё ещё раз |
||
321 | |||
322 | mov eax,12 ; закончили "рисовать" |
||
323 | mov ebx,2 |
||
324 | int 0x40 |
||
325 | |||
326 | ret ; возврат |
||
327 | |||
328 | |||
329 | |||
330 | ; ДАННЫЕ ПРОГРАММЫ |
||
331 | DATA |
||
332 | |||
333 | macro strtbl name, [string] |
||
334 | { |
||
335 | common |
||
336 | label name dword |
||
337 | forward |
||
338 | local str |
||
339 | dd str |
||
340 | forward |
||
341 | str db string |
||
342 | } |
||
343 | |||
344 | strtbl startapps ,\ |
||
345 | <"/RD/1/PIC4",0> ,\ |
||
346 | <"/RD/1/DESKTOP",0> ,\ |
||
347 | <"/RD/1/MV",0> ,\ |
||
348 | <"/RD/1/JPEGVIEW",0> ,\ |
||
349 | <"/RD/1/CPU",0> ,\ |
||
350 | <"/RD/1/SPANEL",0> ,\ |
||
351 | <"/RD/1/ICONMNGR",0> ,\ |
||
352 | <"/RD/1/VRR",0> |
||
353 | |||
354 | ; header: ; заголовок |
||
355 | ; db 'M E N U' |
||
356 | ; header_len = $ - header |
||
357 | |||
358 | ; text: ; текст на кнопках |
||
359 | ; db 'Background '; 12 |
||
360 | ; db 'Colors ' |
||
361 | ; db 'MeView ' |
||
362 | ; db 'Processes ' |
||
363 | ; db 'Panel setup ' |
||
364 | ; db 'Icon manager' |
||
365 | |||
366 | sz header, "MenuetOS" |
||
367 | |||
368 | lsz text,\ |
||
369 | en, 'Background ',\ |
||
370 | en, 'Colors ',\ |
||
371 | en, 'MeView ',\ |
||
372 | en, 'JpegView ',\ |
||
373 | en, 'Processes ',\ |
||
374 | en, 'Panel setup ',\ |
||
375 | en, 'Icon manager',\ |
||
376 | en, 'VRR ',\ |
||
377 | \ |
||
378 | ru, 'Генератор обоев ',\ |
||
379 | ru, 'Системные цвета ',\ |
||
380 | ru, 'Просмотр BMP ',\ |
||
381 | ru, 'Просмотр JPEG ',\ |
||
382 | ru, 'Процессы ',\ |
||
383 | ru, 'Настройка панели ',\ |
||
384 | ru, 'Управление иконками ',\ |
||
385 | ru, 'Настройка монитора ' |
||
386 | |||
387 | |||
388 | |||
389 | ; НЕИНИЦИАЛИЗИРОВАННЫЕ ДАННЫЕ |
||
390 | UDATA |
||
391 | processes dd ? ; количество процессов в системе |
||
392 | curx1 dd ? ; координаты курсора |
||
393 | cury1 dd ? |
||
394 | curx dd ? ; координаты окна меню |
||
395 | cury dd ? |
||
396 | |||
397 | menu_opened db ? ; открыто меню или нет? (1-да, 0-нет) |
||
398 | |||
399 | align 32 |
||
400 | start_info: |
||
401 | .mode dd ? |
||
402 | dd ? |
||
403 | .params dd ? |
||
404 | dd ? |
||
405 | .workarea dd ? |
||
406 | .path: |
||
407 | rb 256 |
||
408 | |||
409 | |||
410 | sc system_colors ; системные цвета |
||
411 | procinfo process_information ; информация о процессе |
||
412 | |||
413 | work_area: |
||
414 | rb 0x1000 |
||
415 | |||
416 | rb 1024 ; стэк для окна меню - хватит и 1 Кб |
||
417 | align 32 |
||
418 | stack_wnd: |
||
419 | |||
420 | |||
421 | MEOS_APP_END |
||
422 | ; КОНЕЦ ПРОГРАММЫ"/RD/1/VRR",0>"/RD/1/ICONMNGR",0>"/RD/1/SPANEL",0>"/RD/1/CPU",0>"/RD/1/JPEGVIEW",0>"/RD/1/MV",0>"/RD/1/DESKTOP",0>"/RD/1/PIC4",0>>> |