diff --git a/programs/develop/examples/radiobutton/trunk/macros.inc b/programs/develop/examples/radiobutton/trunk/macros.inc new file mode 100644 index 0000000000..14185dbfce --- /dev/null +++ b/programs/develop/examples/radiobutton/trunk/macros.inc @@ -0,0 +1,269 @@ +; new application structure +macro meos_app_start + { + use32 + org 0x0 + + db 'MENUET01' + dd 0x01 + dd __start + dd __end + dd __memory + dd __stack + + if used __params & ~defined __params + dd __params + else + dd 0x0 + end if + + dd 0x0 + } +MEOS_APP_START fix meos_app_start + +macro code + { + __start: + } +CODE fix code + +macro data + { + __data: + } +DATA fix data + +macro udata + { + if used __params & ~defined __params + __params: + db 0 + __end: + rb 255 + else + __end: + end if + __udata: + } +UDATA fix udata + +macro meos_app_end + { + align 32 + rb 2048 + __stack: + __memory: + } +MEOS_APP_END fix meos_app_end + + +; macro for defining multiline text data +struc mstr [sstring] + { + forward + local ssize + virtual at 0 + db sstring + ssize = $ + end virtual + dd ssize + db sstring + common + dd -1 + } + + +; strings +macro sz name,[data] { ; from MFAR [mike.dld] + common + if used name + label name + end if + forward + if used name + db data + end if + common + if used name + .size = $-name + end if +} + +macro lsz name,[lng,data] { ; from MFAR [mike.dld] + common + if used name + label name + end if + forward + if (used name)&(lang eq lng) + db data + end if + common + if used name + .size = $-name + end if +} + + + +; easy system call macro +macro mpack dest, hsrc, lsrc +{ + if (hsrc eqtype 0) & (lsrc eqtype 0) + mov dest, (hsrc) shl 16 + lsrc + else + if (hsrc eqtype 0) & (~lsrc eqtype 0) + mov dest, (hsrc) shl 16 + add dest, lsrc + else + mov dest, hsrc + shl dest, 16 + add dest, lsrc + end if + end if +} + +macro __mov reg,a,b { ; mike.dld + if (~a eq)&(~b eq) + mpack reg,a,b + else if (~a eq)&(b eq) + mov reg,a + end if +} + +macro mcall a,b,c,d,e,f { ; mike.dld + __mov eax,a + __mov ebx,b + __mov ecx,c + __mov edx,d + __mov esi,e + __mov edi,f + int 0x40 +} + + + +; optimize the code for size +__regs fix + +macro add arg1,arg2 + { + if (arg2 eqtype 0) + if (arg2) = 1 + inc arg1 + else + add arg1,arg2 + end if + else + add arg1,arg2 + end if + } + +macro sub arg1,arg2 + { + if (arg2 eqtype 0) + if (arg2) = 1 + dec arg1 + else + sub arg1,arg2 + end if + else + sub arg1,arg2 + end if + } + +macro mov arg1,arg2 + { + if (arg1 in __regs) & ((arg2 eqtype 0) | (arg2 eqtype '0')) + if (arg2) = 0 + xor arg1,arg1 + else if (arg2) = 1 + xor arg1,arg1 + inc arg1 + else if (arg2) = -1 + or arg1,-1 + else if (arg2) > -128 & (arg2) < 128 + push arg2 + pop arg1 + else + mov arg1,arg2 + end if + else + mov arg1,arg2 + end if + } + + +macro struct name + { + virtual at 0 + name name + sizeof.#name = $ - name + end virtual + } + +; structures used in MeOS +struc process_information + { + .cpu_usage dd ? ; +0 + .window_stack_position dw ? ; +4 + .window_stack_value dw ? ; +6 + .not_used1 dw ? ; +8 + .process_name rb 12 ; +10 + .memory_start dd ? ; +22 + .used_memory dd ? ; +26 + .PID dd ? ; +30 + .x_start dd ? ; +34 + .y_start dd ? ; +38 + .x_size dd ? ; +42 + .y_size dd ? ; +46 + .slot_state dw ? ; +50 + dw ? ; +52 - reserved + .client_left dd ? ; +54 + .client_top dd ? ; +58 + .client_width dd ? ; +62 + .client_height dd ? ; +66 + .wnd_state db ? ; +70 + rb (1024-71) + } +struct process_information + +struc system_colors + { + .frame dd ? + .grab dd ? + .grab_button dd ? + .grab_button_text dd ? + .grab_text dd ? + .work dd ? + .work_button dd ? + .work_button_text dd ? + .work_text dd ? + .work_graph dd ? + } +struct system_colors + + +; constants + +; events +EV_IDLE = 0 +EV_TIMER = 0 +EV_REDRAW = 1 +EV_KEY = 2 +EV_BUTTON = 3 +EV_EXIT = 4 +EV_BACKGROUND = 5 +EV_MOUSE = 6 +EV_IPC = 7 +EV_STACK = 8 + +; event mask bits for function 40 +EVM_REDRAW = 1b +EVM_KEY = 10b +EVM_BUTTON = 100b +EVM_EXIT = 1000b +EVM_BACKGROUND = 10000b +EVM_MOUSE = 100000b +EVM_IPC = 1000000b +EVM_STACK = 10000000b \ No newline at end of file diff --git a/programs/develop/examples/radiobutton/trunk/optionbox.asm b/programs/develop/examples/radiobutton/trunk/optionbox.asm new file mode 100644 index 0000000000..7177f2c98b --- /dev/null +++ b/programs/develop/examples/radiobutton/trunk/optionbox.asm @@ -0,0 +1,115 @@ +;компонент OptionBox (Основан на Checkbox) +;Огромная благодарность Maxxxx32, Diamond, и другим программистам, и их программам, без +;которых я не смог бы написать этот компонент. +;16.02.2007 +; - Теплов Алексей www.lrz.land.ru + +;заголовок приложения +use32 ; транслятор, использующий 32 разрядных команды + org 0x0 ; базовый адрес кода, всегда 0x0 + db 'MENUET01' ; идентификатор исполняемого файла (8 байт) + dd 0x1 ; версия формата заголовка исполняемого файла + dd start ; адрес, на который система передаёт управление + ; после загрузки приложения в память + dd i_end ; размер приложения + dd (i_end+0x100) and not 3 ; Объем используемой памяти, для стека отведем 0х100 байт и выровним на грницу 4 байта + dd (i_end+0x100) and not 3 ; расположим позицию стека в области памяти, сразу за телом программы. Вершина стека в диапазоне памяти, указанном выше + dd 0x0,0x0 ; указатель на строку с параметрами. + ; если после запуска неравно нулю, приложение было + ; запущено с параметрами из командной строки + + ; указатель на строку, в которую записан путь, + ; откуда запущено приложение +;------------------ + include 'macros.inc' + include 'optionbox.inc' ;включить файл check.inc + use_option_box ;используя макросы внести процедуры для рисования чек бокса +align 16 +;Область кода +start: ;Точка входа в программу + mov eax,48 ;получить системные цвета + mov ebx,3 + mov ecx,sc + mov edx,sizeof.system_colors + int 0x40 + + mov eax,40 ;установить маску для ожидаемых событий + mov ebx,0x25 ;система будет реагировать только на сообщение о перерисовке,нажата кнопка, определённая ранее, событие от мыши (что-то случилось - нажатие на кнопку мыши или перемещение; сбрасывается при прочтении) + int 0x40 +red_win: + call draw_window ;первоначально необходимо нарисовать окно +still: ;основной обработчик + mov eax,10 ;Ожидать события + int 0x40 ;ожидать событие в течение 2 миллисекунд + + cmp al,0x1 ;если изменилось положение окна + jz red_win + cmp al,0x3 ;если нажата кнопка то перейти + jz button + mouse_option_boxes option_boxes,option_boxes_end ;проверка чек бокса + jmp still ;если ничего из перечисленного то снова в цикл +button: + mov eax,17 ;получить идентификатор нажатой клавиши + int 0x40 + test ah,ah ;если в ah 0, то перейти на обработчик событий still + jz still + or eax,-1 ;в eax,-1 - 5 ,байтов у нас же только 3 выйти + int 0x40 ;далее выполняется выход из программы + +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +draw_window: ;рисование окна приложения + mov eax,12 ;в регистр внести значение = 12 + mov ebx,1 ;присвоить 1 + int 0x40 + + xor eax,eax ;обнулить eax + mov ebx,50*65536+180 ;[координата по оси x]*65536 + [размер по оси x] + mov ecx,30*65536+200 ;[координата по оси y]*65536 + [размер по оси y] + mov edx,[sc.work] ; color of work area RRGGBB,8->color gl + or edx,0xb3000000 + mov esi,[sc.work_text] + mov edi,hed;0x005080DD ;0x00RRGGBB - цвет рамки + int 0x40 ;нарисовать окно приложения + draw_option_boxes option_boxes,option_boxes_end ;рисование чекбоксов + + mov eax,12 ;Функция 12 - начать/закончить перерисовку окна. + mov ebx,2 ;Подфункция 2 - закончить перерисовку окна. + int 0x40 + ret + +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +;DATA данные +;Формат данных чек бокса: +;10 - координата чек бокса по х +;30 - координата чек бокса по у +;0xffffff - цвет внутри чек бокса +;0 - цвет рамки чек бокса +;0 - цвет текста надписи +;op_text.1 - указатель на начало строки +;option_group1 - это признак группы, т.е. этот код может обрабатывать много групп из optibox +;op_text.e1-ch_text.1 - длина строки +; +option_boxes: +op1 option_box 10,15,0xffffff,0,0,ch_text.1,ch_text.e1-ch_text.1,option_group1 +op2 option_box 10,30,0xffffff,0,0,ch_text.2,ch_text.e2-ch_text.2,option_group1 +op3 option_box 10,45,0xffffff,0,0,ch_text.3,ch_text.e3-ch_text.3,option_group1 +op11 option_box 10,80,0xffffff,0,0,ch_text.1,ch_text.e1-ch_text.1,option_group2 +op12 option_box 10,95,0xffffff,0,0,ch_text.2,ch_text.e2-ch_text.2,option_group2 +op13 option_box 10,110,0xffffff,0,0,ch_text.3,ch_text.e3-ch_text.3,option_group2 +option_boxes_end: + +ch_text: ; Сопровождающий текст для чек боксов +.1 db 'Option_Box #1' +.e1: +.2 db 'Option_Box #2' +.e2: +.3 db 'Option_Box #3' +.e3: + +option_group1 dd op1 ;указатели, они отображаются по умолчанию, когда выводится +option_group2 dd op11 ;приложение + +hed db 'Optionbox [16.02.2007]',0 ;заголовок приложения +sc system_colors +i_end: ;конец кода \ No newline at end of file diff --git a/programs/develop/examples/radiobutton/trunk/optionbox.bat b/programs/develop/examples/radiobutton/trunk/optionbox.bat new file mode 100644 index 0000000000..b49ee6b60e --- /dev/null +++ b/programs/develop/examples/radiobutton/trunk/optionbox.bat @@ -0,0 +1,2 @@ +@fasm.exe optionbox.asm optionbox +@mtappack.exe optionbox diff --git a/programs/develop/examples/radiobutton/trunk/optionbox.inc b/programs/develop/examples/radiobutton/trunk/optionbox.inc new file mode 100644 index 0000000000..07659f6755 --- /dev/null +++ b/programs/develop/examples/radiobutton/trunk/optionbox.inc @@ -0,0 +1,216 @@ +;компонент OptionBox (Основан на Checkbox) +;Огромная благодарность Maxxxx32, Diamond, и другим программистам, и их программам, без +;которых я не смог бы написать этот компонент. +;16.02.2007 +; - Теплов Алексей www.lrz.land.ru + +macro use_option_box +{ +op_text_margin=4 ;расстояние от прямоугольника чек бокса до надписи +op_size=10 ;размер квадрата чек бокса +op_left equ [edi] ;координата начала рисования по х +op_top equ [edi+2] ;координата начала рисования по у +op_color equ [edi+4] ;цвет внутри optionbox +op_border_color equ [edi+8] ;цвет рамки optionbox +op_text_color equ [edi+12] ;цвет текста +op_text_ptr equ [edi+16] ;указатель на начало текстовой строки +op_text_length equ [edi+20] ;длина надписи (2^64 такой длины может быть текст) +op_optibox_gr equ [edi+22] +option_box: +.draw: +pusha ;сохраним все регистры + mov eax,38 ;рисование линии + movzx ebx,word op_left ;положение по х + mov ecx,ebx ;сохраним в регистре cx значение bx 1 микрооперация + ;push bx ;3 - микрооперации используя стек можно выиграть в размере, используя регистры - в скорости + shl ebx,16 ;сдвинем на 16 разрядов в лево (умножим на 65536) + ;pop bx ;2 - микрооперации на данный момент сформирована [координата начала по оси x]*65536 + [координата начала по оси x] + mov bx,cx ;восстановим значение bx + movzx ecx,word op_top ;загрузим в cx значение y + mov esi,ecx ;сохраним значение регистра cx в регистр указатель si + ;push cx + shl ecx,16 ; сдвинем на 16 разрядов в лево (умножим на 65536) mov cx,si ;восстановим значение регистра cx + mov cx,si ;восстановим значение регистра cx + ;pop cx ;[координата начала по оси y]*65536 + [координата начала по оси y] + ;push cx + add ecx,op_size ;[координата начала по оси y]*65536 + [координата конца по оси y] + mov edx,op_border_color ;Цвет линии + int 0x40 ;рисование вертикальной левой линии квадрата (прямоугольника) +; + mov ebp,ebx ;сохраним регистр bx в регистре указателя базы + ;push bx ;втолкнуть в bx [координата начала по оси х]*65536 + [координата начала по оси x] + add ebx,op_size ;[координата начала + длина стороны по оси х] + ror ebx,16 ;[координата начала + дина стороны по оси х]*65536 + add ebx,op_size ;[координата начала+длина стороны по оси х]*65536 + [координата начала+длина стороны по оси x] + int 0x40 + + mov bx,bp ;восстановим значение регистра bx + ;pop bx + mov cx,si ;сохраним значение регистра cx в регистр указатель + ;pop cx + int 0x40 + add ecx,op_size ;добавим размер стороны + mov esi,ecx ;сохраним значение регистра cx в регистр указатель si + ;push cx + shl ecx,16 + mov cx,si + ;pop cx + int 0x40 ;нарисовали прямоугольник + + mov eax,13 ;закрашиваем его. Функция 13 - нарисовать полосу + movzx ebx,word op_left ;загрузить в bx, положение по х + add ebx,1 ;сдвинем на 1 т.е. прибавим 1 иначе затрется рамка + shl ebx,16 ;сдвинем на 16 разрядов в лево (умножим на 65536) + mov bx,op_size ;прибавим длину стороны прямоугольника + sub ebx,1 ;вычтем 1 т.к. иначе затрется рамка + mov bp,bx ;сохраним регистр bx в регистре указателя базы + ;push bx + movzx ecx,word op_top ;загрузим координаты по y + add ecx,1 ;сдвинем на 1 т.е. прибавим 1 иначе затрется рамка + shl ecx,16 ;сдвинем на 16 разрядов в лево (умножим на 65536) + mov cx,bp ;восстановим значение регистра cx + ;pop cx + mov edx,op_color ;загрузим цвет полосы + int 0x40 ;закрасили + + mov eax,op_optibox_gr + mov dword eax,[eax] + cmp eax,edi + jne @f + call .draw_op ;нарисовать включенный чек бокс +;---------------------------- +;расчет куда будет произведен вывод текста +;---------------------------- +@@: movzx ebx,word op_left ;загрузить значение х для чек бокса + add ebx,(op_size+op_text_margin) ;добавить размер стороны и расстояние на котором начнется вывод текста + shl ebx,16 ;сдвинем на 16 разрядов в лево (умножим на 65536) + mov bx,op_top ;загрузим значение по y + add ebx,(op_size-9+2) ;добавим значение длины стороны -9+2 + mov ecx,op_text_color ;загрузим цвет надписи + + mov edx,op_text_ptr ;укажем адрес от куда нужно выводить строку + movzx esi,word op_text_length ;Загрузим длину надписи в esi + ;внесем в eax значение вывода надписи на канву + mov eax,4 + int 0x40 ;Вывод +popa ;восстановить значения регистров из стека +ret ;выйдем из процедуры + +.clear_op: ;очистка чек бокса + mov edx,op_color ;цвет внутри чек бокса + jmp @f ;безусловный прыжок на нижнюю метку @@ + +.draw_op: ;нарисовать включенный чек бокс + mov edx,op_border_color ;загрузить цвет +@@: + movzx ebx,word op_left ;загрузить координату по х + add ebx,(op_size/3) ;добавить (сторона прямоугольника/3) + shl ebx,16 ;сдвинем на 16 разрядов в лево (умножим на 65536) + mov bx,(op_size/2) ;загрузить (сторона прямоугольника/2) + mov bp,bx ;сохраним регистр bx в регистре указателя базы + ;push bx + movzx ecx,word op_top ;загрузить координату по у + mov eax,13 ;в eax - значения функции для вывода полосы т.е. по сути прямоугольника, который отображает включенный компонент чек бокс + add ecx,(op_size/3) ;добавить (сторона прямоугольника/3) + shl ecx,16 ;сдвинем на 16 разрядов в лево (умножим на 65536) + mov cx,bp ;загрузим значения регистра указателя базы в cx + ;pop cx + int 0x40 ;вывод +ret ;выйти из процедуры + +.mouse: ;обработка мыши +pusha + mov eax,37 ;будем что то делать если у нас что - нить нажато + mov ebx,2 ;внести в регистр значение 2 + int 0x40 ;проверка не нажал ли пользователь кнопку мышки + test eax,eax ;проверка если у нас в eax=0, то установим флаг и выйдем + jnz @f ;перейти на нижнюю метку @@ + popa ;если ничего не произошло, то восстановим значения регистров из стека + ret ;выход +@@: + movzx esi,word op_text_length ;загрузить кол-во символов в текстовой строке + ;Умножение на 6 Быстрое умножение можно воспользоваться любым мз методов, но на старых Процессорах (386,486,P1)быстрее будет с инструкцией Lea + ;lea esi,[eax*2+eax] + ;shl eax,1 + imul esi,6 ; или можно и так умножить на 6 + add esi,op_text_margin ;добавить 3 - расстояние от чек бокса до надписи + + mov eax,37 ;получим координаты мышки + mov ebx,1 ;добавить 1 + int 0x40 ;получить координаты курсора относительно окна + + movzx ebx,word op_top ;загрузить в bx значение координаты у + cmp ax,bx ;сравнить с с координатой курсора + jl .mouse_end ;SF <> OF если меньше + add ebx,op_size ;добавить размер + cmp ax,bx ;сравнить + jg .mouse_end ;ZF = 0 и SF = OF если больше + + shr eax,16 ;разделим на 65536 или просто сдвинем биты на 16 значений + movzx ebx,word op_left ;произведем аналогичное сравнение + cmp ax,bx ;сравнить регистры + jl .mouse_end ;если меньше + add ebx,op_size ;добавить длину стороны прямоугольника + add ebx,esi ;Учесть в значении по х еще и длину надписи к чекбоксу + cmp ax,bx ;стравнить регистры + jg .mouse_end ;если больше + mov eax,op_optibox_gr + mov [eax],edi + +.mouse_end: +popa ;восстановить регистры из стека +ret ;выйти +} + +struc option_box left,top,color,border_color,text_color,text,text_length,point_gr,flags +{ ;структура параметров для чек бокса +.left: dw left ;+0 ;положение по х +.top: dw top ;+2 ;положение по у +.color: dd color ;+4 ;цвет внутри чек бокса +.border_color: dd border_color ;+8 цвет рамки +.text_color: dd text_color ;+12 цвет текста надписи +.text: dd text ;+16 адрес в коде программы где расположен текстр +.text_length: dw text_length ; +20 длина текста +.option_group: dd point_gr ;указатель на размещение edi - идентификатора optibox +} +op_struc_size=26 ;общая структура 24 байт +op_flag_en=10b +macro draw_option_boxes start,end ;рисовать чек боксы +{ + mov edi,start ;Указатель на начало данных чек боксов т.е. на начало данных первого чекбокса + mov ecx,((end-start)/op_struc_size) ;Количество чек боксов +@@: + call option_box.draw ;Отобразить чек бокс + add edi,op_struc_size ;Указатель на последующие чек боксы т.е. +28 + loop @b ;прыгнуть если в ecx/cx значение не 0 на верхнюю @@ +} +macro mouse_option_boxes start,end ;установка чек боксов, в зависимости от события +{ + mov edi,start ; Указатель на начало данных чек боксов т.е. на начало данных первого чекбокса + mov ecx,((end-start)/op_struc_size) ;Количество чек боксов +@@: + call option_box.mouse ;проверка мышки и обработка событий + add edi,op_struc_size ;Указатель на последующие чек боксы + loop @b ;прыгнуть если в ecx/cx значение не 0 на верхнюю @@ + + mov edi,start ; Указатель на начало данных чек боксов т.е. на начало данных первого чекбокса + mov ecx,((end-start)/op_struc_size) ;Количество чек боксов + +.home: + mov eax,[edi+22] ;op_optibox_gr + mov dword eax,[eax] + + pusha + + cmp eax,edi + jne @f + + call option_box.draw_op + jmp .nxtm +@@: call option_box.clear_op + +.nxtm: popa + add edi,op_struc_size ;Указатель на последующие чек боксы т.е. +28 + loop .home + +} \ No newline at end of file