Subversion Repositories Kolibri OS

Compare Revisions

No changes between revisions

Regard whitespace Rev 30 → Rev 31

/programs/menu/trunk/build_en.bat
0,0 → 1,4
@erase lang.inc
@echo lang fix en >lang.inc
@fasm menu.asm menu
@pause
/programs/menu/trunk/build_ru.bat
0,0 → 1,4
@erase lang.inc
@echo lang fix ru >lang.inc
@fasm menu.asm menu
@pause
/programs/menu/trunk/macros.inc
0,0 → 1,267
; 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 <eax,ebx,ecx,edx,esi,edi,ebp,esp>
 
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)
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
rb (1024-52)
}
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
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/programs/menu/trunk/menu.asm
0,0 → 1,581
;******************************************************************************
; MAIN MENU by lisovin@26.ru
; Some parts of code rewritten by Ivan Poddubny <ivan-yar@bk.ru>
;
; Compile with FASM for Menuet
;******************************************************************************
include "lang.inc"
include "macros.inc"
 
BTN_HEIGHT = 22
TXT_Y = (BTN_HEIGHT)/2-5
 
use32
org 0x0
db 'MENUET01' ; 8 byte id
dd 0x01 ; header version
dd START ; start of code
dd I_END ; size of image
dd 0x20000 ; memory for app
dd 0x20000-1 ; esp
dd 0x0 , 0x0 ; I_Param , I_Icon
;******************************************************************************
;include "DEBUG.INC" ; debug macros
START: ; start of execution
 
mov eax, 48 ; load system colors
mov ebx, 3
mov ecx, sc
mov edx, sizeof.system_colors
int 0x40
 
mov eax, 58 ; load MENU.DAT
mov ebx, fileinfo
int 0x40
test eax, eax ; error ?
jnz close
test ebx, ebx ; length = 0 ?
jz close
mov ecx, ebx
mov edi, mem_end
newsearch:
mov al, '#'
cld
repne scasb
test ecx, ecx ; if not found
jz close
call get_number
test ebx, ebx
jnz .number
cmp al, '#'
je search_end
.number:
shl ebx, 4
add ebx, menu_data ; pointer to process table
mov [ebx], edi
inc [processes]
jmp newsearch
search_end:
mov [end_pointer], edi
mov ebx, [processes]
dec ebx
shl ebx, 4
add ebx, menu_data
newprocess:
xor edx, edx
mov ecx, edi
sub ecx, [ebx]
mov al, 10
newsearch1:
std
repne scasb
test ecx, ecx
je endprocess
cmp [edi], byte 13
jne newsearch1
inc edx
jmp newsearch1
endprocess:
mov esi, ebx
add esi, 4
dec edx
mov [esi], dl
cmp ebx, menu_data
jbe search_end1
sub ebx, 16
jmp newprocess
search_end1:
mov eax, 14
int 0x40
sub ax, 20
mov [menu_data + y_end], ax
mov [menu_data + x_start], 5
mov al, [menu_data + rows]
mov [menu_data + cur_sel], al ; clear selection
mov [menu_data + prev_sel], al
 
mov [buffer], 0
thread:
mov eax, [buffer] ; identifier
shl eax, 4
add eax, menu_data
mov edi, eax
 
mov eax, 40 ; set event mask
mov ebx, 100111b ; mouse + button + key + redraw
int 0x40
 
call draw_window
 
still:
mov eax, 23 ; wait here for event
mov ebx, 5
int 0x40
 
test [close_now], 1 ; is close flag set?
jnz close
 
cmp eax, 1 ; redraw request ?
je red
cmp eax, 2 ; key pressed ?
je key
cmp eax, 3 ; button in buffer ?
je button
cmp eax, 6 ; mouse event ?
je mouse
 
cmp edi, menu_data
je still ; if main process-ignored
 
movzx ebx, [edi + parent] ; parent id
shl ebx, 4
add ebx, menu_data ; ebx = base of parent info
call backconvert ; get my id in al
cmp al, [ebx + child] ; if I'm not child of my parent, I shall die :)
jne close
 
jmp still
 
 
red: ; redraw
call draw_window
jmp still
 
 
key:
; mov eax, 2
int 0x40
 
mov al, [edi + rows] ; number of buttons
 
cmp ah, 178 ; KEY_UP
jne .noup
 
mov ah, [edi+cur_sel]
mov [edi+prev_sel], ah
dec byte [edi+cur_sel]
jnz redrawbut
mov [edi+cur_sel], al
jmp redrawbut
 
 
.noup:
cmp ah, 177 ; KEY_DOWN
jne .nodn
 
mov ah, [edi + cur_sel]
mov [edi + prev_sel], ah
inc [edi + cur_sel]
cmp [edi + cur_sel], al
jna redrawbut
mov [edi + cur_sel], 1
jmp redrawbut
 
.nodn:
cmp ah, 13 ; ENTER
jne .noenter
mov ah, [edi + cur_sel]
jmp button1
 
.noenter:
cmp ah, 27 ; ESC
jne still
jmp close
 
; include "DEBUG.INC"
 
button: ; BUTTON HANDLER
mov eax, 17 ; get id
int 0x40
 
button1:
mov esi, edi
push edi
mov edi, [edi + pointer]
 
; print "hello"
mov al, [esi + cur_sel]
mov [esi + prev_sel], al
mov [esi + cur_sel], ah
pushad
mov edi, esi
; dph eax
call draw_only_needed_buttons
popad
 
; look for the next line <ah> times; <ah> = button_id
push eax
.next_string:
call searchstartstring
dec ah
jnz .next_string
pop eax
 
mov ecx, 40
mov al, '/'
cld
repne scasb
test ecx, ecx ; if '/' not found
je searchexit
 
cmp [edi], byte '@' ; check for submenu
je runthread
 
dec edi
push edi ; pointer to start of filename
call searchstartstring ; search for next string
sub edi, 2 ; to last byte of string
 
mov ecx, edi
pop esi
sub ecx, esi
inc ecx ; length of filename
mov edi, fileinfo_start.name
rep movsb ; copy string
mov byte [edi], 0 ; store terminator
 
; mov eax,fileinfo_start.name
; cmp eax,'/rd/'
; jne run_hd
; mov ebx,fileinfo_start.name+6
; mov eax,19
; xor ecx,ecx
; jmp run_for_all
;run_hd:
mov eax, 58 ; start program
mov ebx, fileinfo_start
;run_for_all:
int 0x40
mcall 5,100
; mov eax,5
; mov ebx,100
; int 0x40
 
or [close_now], 1 ; set close flag
 
pop edi
mov [mousemask], 0
jmp close
 
searchexit:
pop edi
jmp still
 
 
runthread:
inc edi
 
push eax
call get_number ; get number of this process
pop eax
 
test ebx, ebx ; returned zero - main menu or not number
jz searchexit
 
mov al, bl
 
mov ebx, [processes]
dec bl
cmp al, bl
ja searchexit ; such process doesnt exist
cmp al, [esi + child]
je searchexit ; such process already exists
 
mov [esi + child], al ; this is my child
mov cx, [esi + x_start]
add cx, 141 ; new x_start in cx
movzx edx, al
shl edx, 4
add edx, menu_data ; edx points to child's base address
mov [edx + x_start], cx ; xstart for new thread
mov cx, [esi + y_end] ; y_end in cx
mov bl, [esi + rows] ; number of buttons in bl
sub bl, ah ; number of btn from bottom
movzx eax, al
mov [buffer], eax ; thread id in buffer
movzx ebx, bl
push edx
mov eax, BTN_HEIGHT
mul ebx
sub cx, ax ; new y_end for new thread
pop edx
mov [edx + y_end], cx ; store y_end
mov edi, esi
call backconvert ; get number of this process (al)
mov [edx + parent], al ; store number of parent process
mov al, [edx + rows]
mov [edx + cur_sel], al ; clear current selected element
mov [edx + prev_sel], al ; clear previous selected element
mov [edx + child], 0
 
cmp [thread_stack], 0x1e000
jne thread_stack_not_full
mov [thread_stack], 0xc000
 
thread_stack_not_full:
add [thread_stack], 0x2000 ; start new thread
mov eax, 51
mov ebx, 1
mov ecx, thread
mov edx, [thread_stack]
int 0x40
 
jmp searchexit
 
 
mouse: ; MOUSE EVENT HANDLER
mov eax, 37
mov ebx, 2
int 0x40
test eax, eax ; check buttons state
jnz click
mov eax, 37
mov ebx, 1
int 0x40
ror eax, 16 ; eax = [ Y | X ] relative to window
cmp ax, 140 ; pointer in window?
ja noinwindow
;  in window 
 
shr eax, 16 ; eax = [ 0 | Y ]
xor edx, edx
mov ebx, BTN_HEIGHT
div ebx
inc eax ; number of "button" in eax
movzx ebx, [edi + rows] ; total strings in ebx
cmp eax, ebx
ja noinwindow
cmp [edi + cur_sel], al
je noredrawbut
mov bl, [edi + cur_sel]
 
;;;;;;
cmp [edi + child], 0
jne noredrawbut
;;;;;;
 
mov [edi + cur_sel], al
mov [edi + prev_sel], bl
redrawbut:
call draw_only_needed_buttons
noredrawbut:
call backconvert
bts [mousemask], eax
jmp still
noinwindow:
call backconvert
btr [mousemask], eax
jmp still
click:
cmp [mousemask], 0 ; not in a window (i.e. menu)
je close
jmp still
 
 
close:
or eax, -1 ; close this thread
mov [edi + child], al ; my child is not mine
int 0x40
 
 
backconvert: ; convert from pointer to process id
mov eax, edi
sub eax, menu_data
shr eax, 4
ret
 
 
;==================================
; get_number
; load number from [edi] to ebx
;==================================
get_number:
push edi
 
xor eax, eax
xor ebx, ebx
 
.get_next_char:
mov al, [edi]
inc edi
cmp al, '0'
jb .finish
cmp al, '9'
ja .finish
sub al, '0'
imul ebx, 10
add ebx, eax
jmp .get_next_char
 
.finish:
pop edi
ret
 
 
; *********************************************
; ******* WINDOW DEFINITIONS AND DRAW ********
; *********************************************
 
 
draw_window:
 
mov eax, 12 ; function 12:tell os about windowdraw
mov ebx, 1 ; 1, start of draw
int 0x40
 
movzx ebx, [edi + rows]
imul eax, ebx, BTN_HEIGHT ; eax = height of window
movzx ecx, [edi + y_end]
sub ecx, eax ; ecx = Y_START
shl ecx, 16
add ecx, eax ; ecx = [ Y_START | Y_SIZE ]
dec ecx
movzx ebx, [edi + x_start]
shl ebx, 16
mov bx, 140 ; ebx = [ X_START | X_SIZE ]
xor eax, eax ; function 0 : define and draw window
mov edx, 0x01000000 ; color of work area RRGGBB,8->color gl
mov esi, edx ; unmovable window
int 0x40
 
call draw_all_buttons
 
mov eax,12
mov ebx,2
int 0x40
 
ret
 
 
draw_all_buttons:
xor edx, edx
.new_button:
call draw_one_button
inc edx
cmp dl, [edi + rows]
jb .new_button
 
ret
 
 
draw_only_needed_buttons:
xor edx, edx
mov dl, [edi + cur_sel]
dec dl
call draw_one_button
mov dl, [edi + prev_sel]
dec dl
call draw_one_button
ret
 
 
draw_one_button:
; receives number of button in dl
push edx;ad
 
mov eax, 8
mov ebx, 140
movzx ecx, dl
imul ecx, BTN_HEIGHT
shl ecx, 16
add ecx, BTN_HEIGHT-1
; edx = button identifier
mov esi, [sc.work_button]
inc dl
cmp [edi + cur_sel], dl
jne .nohighlight
add esi, 0x202020
.nohighlight:
or edx, 0x20000000
int 0x40
movzx edx, dl
 
dec dl
imul ebx, edx, BTN_HEIGHT
add ebx, (4 shl 16) + TXT_Y
 
movzx ecx, dl
inc ecx
mov edx, [edi + pointer]
.findline:
cmp byte [edx], 13
je .linefound
inc edx
jmp .findline
.linefound:
inc edx
cmp byte [edx], 10
jne .findline
dec ecx
jnz .findline
 
mov ecx, [sc.work_button_text]
mov eax, 4
mov esi, 21
int 0x40
 
pop edx;ad
ret
 
 
searchstartstring:
mov ecx, 40
mov al, 13
cld
repne scasb
cmp byte [edi], 10
jne searchstartstring
ret
 
 
;*** DATA AREA ****************************************************************
 
thread_stack dd 0xc000
processes dd 0
 
fileinfo:
.mode dd 0 ; 0=READ
.start_block dd 0x0 ; 512 block to read 0+
.size dd (0x10000-mem_end)/512 ;0x80; blocks to read (0x10000 bytes max)
.return dd mem_end ; return data pointer
.work dd workarea ; work area for os - 16384 bytes
.name:
db '/RD/1/MENU.DAT',0 ; ASCIIZ dir & filename
 
fileinfo_start:
.mode dd 16 ; 16=START APPLICATION
.start_block dd 0x0 ; nop
.size dd 0x0 ; nop
.return dd 0x0 ; nop
.work dd workarea ; work area for os - 16384 bytes
.name:
times 50 db ' '
 
I_END:
 
close_now dd ? ; close all processes immediately
end_pointer dd ?
buffer dd ?
mousemask dd ? ; mask for mouse pointer location
 
sc system_colors
 
menu_data:
rb 0x4000 ;x10000
 
workarea:
rb 0x4000 ;0x10000
 
virtual at 0 ; PROCESSES TABLE (located at menu_data)
pointer dd ? ; +0 pointer in file
rows db ? ; +4 numer of strings
x_start dw ? ; +5 x start
y_end dw ? ; +7 y end
child db ? ; +9 id of child menu
parent db ? ; +10 id of parent menu
cur_sel db ? ; +11 current selection
prev_sel db ? ; +12 previous selection
rb 16-$+1 ; [16 bytes per element]
end virtual
 
mem_end:
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/programs/menu/trunk/readme.txt
0,0 → 1,73
English text is below
ÍÎÂÎÅ ÃËÀÂÍÎÅ ÌÅÍÞ.
Âíèìàíèå: äëÿ êîððåêòíîé ðàáîòû ðåêîìåíäóåòñÿ MENUET íå íèæå 0.76
è öâåòíîé ìîíèòîð (íà ìîíîõðîìíîì ïîäñâåòêà íå âèäíà)
 
Îòëè÷èÿ îò Âèëëèíîãî ìåíþ:
1.Êîíôèãóðèðóåìîñòü. Ïóíêòû êàê îñíîâíîãî, òàê è äîïîëíèòåëüíûõ
ìåíþøåê çàäàþòñÿ ôàéëîì MENU.DAT.
Ýòî ïîçâîëÿåò:
-äîáàâëÿòü/óáèðàòü ëþáûå ïóíêòû â ìåíþ. Ïðîãðàììà ñàìà àíàëèçèðóåò
èçìåíåíèÿ è ðèñóåò îêíî ñ êíîïêàìè ïî êîëè÷åñòâó ïóíêòîâ. äàëüíåéøåì
èìõî ýòî ïîçâîëèò êîíôèãóðèðîâàòü ìåíþ íå òîëüêî âðó÷íóþ, íî è ïðîã-
ðàììíî. Íèêàêîãî âìåøàòåëüñòâà â êîä, ÷òî ïîçâîëÿåò êîíôèãóðèòü ìåíþ
è ïðîñòûì ïîëüçîâàòåëÿì.
-ïåðåâîäèòü ìåíþ íà ëþáûå ÿçûêè, íå ëàçÿ â êîä.
-ïîñêîëüêó çàïóñê ïðèëîæåíèé ÷åðåç 58-þ ôóíêöèþ, ïðèëîæåíèÿ ìîãóò íàõîäèòü-
ñÿ íå òîëüêî íà ðàìäèñêå.
2.Âåùèöà, ñîâñåì íå èíòåðåñíàÿ äëÿ ïîëüçîâàòåëåé, íî âîçìîæíî
ïðåäñòàâëÿþùàÿ èíòåðåñ äëÿ ïðîãðàììèñòîâ. Ïðèëîæåíèå ìíîãîïîòî÷íîå, íî âñå
ïîòîêè çàïóñêàþòñÿ íà îäíîì è òîì æå êîäå. Ýòî ïîçâîëèëî çàìåíèòü èñïîë-
íÿåìûå ôàéëû MENU, SELECT1, SELECT2 è ò.ä. îäíèì-åäèíñòâåííûì MENU
è ñèëüíî ñýêîíîìèòü ìåñòî íà äèñêå.
3.Ñàìîóíè÷òîæàåìîñòü ìåíþ ïðè êëèêå çà åãî ïðåäåëàìè è ïðè çàïóñêå ïðèëîæåíèÿ
4.Êíîïêè, ïîäñâå÷èâàåìûå ïðè íàâåäåíèè íà íèõ ìûøüþ (íà ìîíîõðîìíîì ìîíèòîðå
ïîäñâåòêà íå âèäíà).
5.Ïîääåðæêà êëàâèàòóðû. Êíîïêè Ââåðõ, Âíèç, Enter è Esc.
 îáùåì, ïîñòàðàëñÿ ïðèáëèçèòüñÿ ê âèíäîâñêîé ìåíþøêå.
 
Çàìå÷àíèÿ ïî ñèíòàêñèñó ôàéëà MENU.DAT:
Ðàçìåð ôàéëà MENU.DAT-íå áîëåå 2Ê
Ìåíþ #0-âñåãäà ãëàâíîå.
Êîëè÷åñòâî ìåíþ-íå áîëåå 10 - îò #0 äî #9
 êàæäîé ñòðîêå ëèáî ïóòü íà èñïîëíÿåìûé ôàéë, ëèáî ññûëêà íà äî÷åðíåå
ìåíþ, íàïðèìåð /@5
Ìàðêåð êîíöà ## îáÿçàòåëåí (âíèìàíèå! TINYPAD áûâàåò åãî îáðåçàåò)
Ïîä òåêñò íà ìåíþøíûõ êíîïêàõ îòâîäÿòñÿ ïåðâûå 20 ïîçèöèé êàæäîé ñòðîêè
Êàæäàÿ ñòðîêà îòäåëÿåòñÿ ENTERîì, ò.å. äîëæíû ïðèñóòñòâîâàòü çíàêè ïåðå-
âîäà ñòðîêè 0x0d,0x0a
 
Ïðîãà Î×ÅÍÜ ñûðàÿ, ïîýòîìó ïðîñüáà íå óäèâëÿòüñÿ, åñëè ÷òî-íèòü íå áóäåò
ðàáîòàòü. Ñ ôàéëîì MENU.DAT ïðîñüáà îáðàùàòüñÿ î÷åíü îñòîðîæíî. TINYPAD
èíîãäà åãî êàëå÷èò. Îñîáåííî ìàðêåð êîíöà ôàéëà!
Èñïîëíÿåìûé ôàéë î÷åíü ðåêîìåíäóåòñÿ íàçâàòü MENU. (ïðè êîìïèëÿöèè)
Òîãäà îí áóäåò âûçûâàòüñÿ èç ïàíåëè êàê è ïîëîæåíî.
Âñå çàìå÷àíèÿ è ïðåäëîæåíèÿ ñ óäîâîëüñòâèåì ïðèíèìàþòñÿ íà lisovin@26.ru
Ïðèàòòà÷åííûå ôàéëû ñëåäóåò âûñûëàòü íà mutny@rambler.ru
Ñ óâàæåíèåì,
Ìèõàèë Ëèñîâèí
 
NEW MAIN MENU
Requirements: MENUET 0.76, color monitor
WHAT'S NEW?
1.Self-configuring menu. All the configurational data is in MENU.DAT
You may add/remove menu positions, translate menu to any language,
run menu applications from HDD without source code change.
2.Multi-thread application. There're two files only: MENU and MENU.DAT
instead of MENU, SELECT1, SELECT2, SELECT3 etc.
3.Self-closing when running application or clicking out of menu.
4.Button highlight
5.Keyboard support (keys Up, Dn, Enter, Esc.)
So, it's just like Windows menu ;)
NOTES ON MENU.DAT:
Size of MENU.DAT should be not more than 2K
Number of menus-not more than 10 (from #0 to #9). #0 is always main menu
## is an end file marker - always required.
First 20 positions of any string reserved for button text
Any string contains file path or link to submenu, for example /@4.
You may edit MENU.DAT by any text editor, but be careful when using
TINYPAD (sometimes it cuts end marker).
It is recommended to compile MMENU.ASM as MENU. So, you can run it from
standard panel.
All the comments and bugreports send to lisovin@26.ru
Michail Lisovin.
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property