More fixes to the new menu engine. Should hopefully be pretty solid now.

This commit is contained in:
mysticbbs 2012-07-24 17:54:01 -04:00
parent d806eec5cf
commit 1292933785
4 changed files with 143 additions and 111 deletions

View File

@ -4313,7 +4313,8 @@
+ Added new ANSI menu editor to replace the old outdated crap. The new + Added new ANSI menu editor to replace the old outdated crap. The new
editor has references to all of the menu commands as well as the special editor has references to all of the menu commands as well as the special
functional hotkeys. functional hotkeys. It still maintains the ability to "simulate" menus
as well.
+ Revamped the entire menu system. Menu files must be converted if you are + Revamped the entire menu system. Menu files must be converted if you are
any version pre 1.10 alpha 15 using the CvtMenus program. Simply copy any version pre 1.10 alpha 15 using the CvtMenus program. Simply copy
@ -4336,7 +4337,9 @@
approach this way, and it allows for more options! approach this way, and it allows for more options!
+ Each menu command now has the option to redraw the menu or not after its + Each menu command now has the option to redraw the menu or not after its
command list executes. command list executes. This defaults to on to mimic previous menu system
however for some advanced stuff, like TIMER, you may will to turn them
off.
+ Menus can now be internally generated from 1 to 4 columns (up from 3) + Menus can now be internally generated from 1 to 4 columns (up from 3)
@ -4423,10 +4426,21 @@
counter used to fire off TIMER commands. It represents the number of counter used to fire off TIMER commands. It represents the number of
seconds that have passed since the menu was loaded. seconds that have passed since the menu was loaded.
+ TIMER commands also have 3 types, configurable per each menu option:
Interval - Always execute at the configured timed interval
OnlyOnce - Execute at interval ONLY ONCE per menu being loaded
PerRedraw - Execute after each menu redraw as per timer interval
+ When using hotkey-style menu input, extended hotkeys are no longer + When using hotkey-style menu input, extended hotkeys are no longer
required to have a / first. You can make a hotkey command named QUIT required to have a / first. You can make a hotkey command named QUIT
for example, and it will execute immediately when QUIT is entered. for example, and it will execute immediately when QUIT is entered.
Keep in mind it is still a hot-key styled input. So you cannot have
one hotkey named QUIT and one named QUITNOW. The QUIT command will
always get the hotkey. If you need functionality like that, hotkeys
can be disabled on the menu.
+ Similar to the display file and menu systems, the MPL scripts directory + Similar to the display file and menu systems, the MPL scripts directory
will now also fallback from the theme scripts path to the default will now also fallback from the theme scripts path to the default
scripts directory if the feature is enabled in the selected theme. scripts directory if the feature is enabled in the selected theme.

View File

@ -307,6 +307,7 @@ Procedure EditItem (Num: Word);
Const Const
Status1 = ' (TAB) to edit menu commands '; Status1 = ' (TAB) to edit menu commands ';
Status2 = ' (TAB) Switch (/) Commands '; Status2 = ' (TAB) Switch (/) Commands ';
Grid = '(Grid) Item # to jump to on keypress ';
Var Var
Box : TAnsiMenuBox; Box : TAnsiMenuBox;
List : TAnsiMenuList; List : TAnsiMenuList;
@ -357,30 +358,30 @@ Begin
List.Picked := 0; List.Picked := 0;
List.Update; List.Update;
Form.AddPipe ('D', ' Display Text ' , 4, 6, 20, 6, 14, 58, 160, @Menu.Item[Num]^.Text, Topic + 'Text displayed on generated menus'); Form.AddPipe ('D', ' Display Text' , 4, 6, 20, 6, 14, 58, 160, @Menu.Item[Num]^.Text, Topic + 'Text displayed on generated menus');
Form.AddPipe ('O', ' LightBar Low ' , 4, 7, 20, 7, 14, 58, 160, @Menu.Item[Num]^.TextLo, Topic + 'Normal text in lightbar menu'); Form.AddPipe ('O', ' LightBar Low' , 4, 7, 20, 7, 14, 58, 160, @Menu.Item[Num]^.TextLo, Topic + 'Normal text in lightbar menu');
Form.AddPipe ('I', ' LightBar High ', 3, 8, 20, 8, 15, 58, 160, @Menu.Item[Num]^.TextHi, Topic + 'Highlighted text in lightbar menu'); Form.AddPipe ('I', ' LightBar High' , 3, 8, 20, 8, 15, 58, 160, @Menu.Item[Num]^.TextHi, Topic + 'Highlighted text in lightbar menu');
Form.AddCaps ('H', ' Hot Key ' , 9, 9, 20, 9, 9, 12, mysMaxMenuInput, @Menu.Item[Num]^.HotKey, Topic + 'Key to run this command (CTRL-L/Extended Key List)'); Form.AddCaps ('H', ' Hot Key' , 9, 9, 20, 9, 9, 12, mysMaxMenuInput, @Menu.Item[Num]^.HotKey, Topic + 'Key to run this command (CTRL-L/Extended Key List)');
Form.AddStr ('A', ' Access ' , 10, 10, 20, 10, 8, 30, 30, @Menu.Item[Num]^.Access, Topic + 'ACS level required to access this command'); Form.AddStr ('A', ' Access' , 10, 10, 20, 10, 8, 30, 30, @Menu.Item[Num]^.Access, Topic + 'ACS level required to access this command');
Form.AddTog ('S', ' Display Type ' , 4, 11, 20, 11, 14, 6, 0, 2, 'Access Always Never', @Menu.Item[Num]^.ShowType, Topic + 'How should this command be displayed?'); Form.AddTog ('S', ' Display Type' , 4, 11, 20, 11, 14, 6, 0, 2, 'Access Always Never', @Menu.Item[Num]^.ShowType, Topic + 'How should this command be displayed?');
Form.AddByte ('X', 'X' , 14, 12, 20, 12, 1, 2, 0, 80, @Menu.Item[Num]^.X, Topic + 'X coordinate of lightbar'); Form.AddByte ('X', 'X' , 14, 12, 20, 12, 1, 2, 0, 80, @Menu.Item[Num]^.X, Topic + 'X coordinate of lightbar');
Form.AddByte ('Y', 'Y' , 16, 12, 23, 12, 1, 2, 0, 50, @Menu.Item[Num]^.Y, Topic + 'Y coordinate of lightbar'); Form.AddByte ('Y', 'Y' , 16, 12, 23, 12, 1, 2, 0, 50, @Menu.Item[Num]^.Y, Topic + 'Y coordinate of lightbar');
Form.AddWord ('M', ' Timer ' , 11, 13, 20, 13, 7, 5, 0, 65535, @Menu.Item[Num]^.Timer, Topic + 'Timer interval (seconds)'); Form.AddWord ('M', ' Timer' , 11, 13, 20, 13, 7, 5, 0, 65535, @Menu.Item[Num]^.Timer, Topic + 'Timer interval (seconds)');
Form.AddTog ('X', ' Exec Type' , 7, 14, 20, 14, 11, 9, 0, 2, 'Interval OnlyOnce PerRedraw', @Menu.Item[Num]^.TimerType, Topic + 'TIMER event execution type'); Form.AddTog ('X', ' Timer Type' , 6, 14, 20, 14, 12, 9, 0, 2, 'Interval OnlyOnce PerRedraw', @Menu.Item[Num]^.TimerType, Topic + 'TIMER event execution type');
Form.AddBol ('W', ' Redraw ' , 33, 14, 43, 14, 8, 3, @Menu.Item[Num]^.ReDraw, Topic + 'Redraw menu after running this command?'); Form.AddBol ('W', ' Redraw' , 33, 14, 43, 14, 8, 3, @Menu.Item[Num]^.ReDraw, Topic + 'Redraw menu after running this command?');
Form.AddByte ('U', ' Up ' , 56, 10, 62, 10, 4, 3, 0, 255, @Menu.Item[Num]^.JumpUp, Topic + '(Grid) Item # to jump to when UP is pressed'); Form.AddByte ('U', ' Up' , 56, 10, 62, 10, 4, 3, 0, 255, @Menu.Item[Num]^.JumpUp, Topic + Grid + 'UP');
Form.AddByte ('D', ' Down ' , 54, 11, 62, 11, 6, 3, 0, 255, @Menu.Item[Num]^.JumpDown, Topic + '(Grid) Item # to jump to when DOWN is pressed'); Form.AddByte ('D', ' Down' , 54, 11, 62, 11, 6, 3, 0, 255, @Menu.Item[Num]^.JumpDown, Topic + Grid + 'DOWN');
Form.AddByte ('L', ' Left ' , 54, 12, 62, 12, 6, 3, 0, 255, @Menu.Item[Num]^.JumpLeft, Topic + '(Grid) Item # to jump to when LEFT is pressed'); Form.AddByte ('L', ' Left' , 54, 12, 62, 12, 6, 3, 0, 255, @Menu.Item[Num]^.JumpLeft, Topic + Grid + 'LEFT');
Form.AddByte ('R', ' Right ' , 53, 13, 62, 13, 7, 3, 0, 255, @Menu.Item[Num]^.JumpRight, Topic + '(Grid) Item # to jump to when RIGHT is pressed'); Form.AddByte ('R', ' Right' , 53, 13, 62, 13, 7, 3, 0, 255, @Menu.Item[Num]^.JumpRight, Topic + Grid + 'RIGHT');
Form.AddByte ('E', ' Home ' , 54, 14, 62, 14, 6, 3, 0, 255, @Menu.Item[Num]^.JumpHome, Topic + '(Grid) Item # to jump to when HOME is pressed'); Form.AddByte ('E', ' Home' , 54, 14, 62, 14, 6, 3, 0, 255, @Menu.Item[Num]^.JumpHome, Topic + Grid + 'HOME');
Form.AddByte ('C', ' Escape ' , 65, 10, 75, 10, 8, 3, 0, 255, @Menu.Item[Num]^.JumpEscape, Topic + '(Grid) Item # to jump to when ESCAPE is pressed'); Form.AddByte ('C', ' Escape' , 65, 10, 75, 10, 8, 3, 0, 255, @Menu.Item[Num]^.JumpEscape, Topic + Grid + 'ESCAPE');
Form.AddByte ('T', ' Tab ' , 68, 11, 75, 11, 5, 3, 0, 255, @Menu.Item[Num]^.JumpTab, Topic + '(Grid) Item # to jump to when TAB is pressed'); Form.AddByte ('T', ' Tab' , 68, 11, 75, 11, 5, 3, 0, 255, @Menu.Item[Num]^.JumpTab, Topic + Grid + 'TAB');
Form.AddByte ('P', ' PageUp ' , 65, 12, 75, 12, 8, 3, 0, 255, @Menu.Item[Num]^.JumpPgUp, Topic + '(Grid) Item # to jump to when PGUP is pressed'); Form.AddByte ('P', ' PageUp' , 65, 12, 75, 12, 8, 3, 0, 255, @Menu.Item[Num]^.JumpPgUp, Topic + Grid + 'PGUP');
Form.AddByte ('G', ' PageDn ' , 65, 13, 75, 13, 8, 3, 0, 255, @Menu.Item[Num]^.JumpPgDn, Topic + '(Grid) Item # to jump to when PGDN is pressed'); Form.AddByte ('G', ' PageDn' , 65, 13, 75, 13, 8, 3, 0, 255, @Menu.Item[Num]^.JumpPgDn, Topic + Grid + 'PGDN');
Form.AddByte ('N', ' End ' , 68, 14, 75, 14, 5, 3, 0, 255, @Menu.Item[Num]^.JumpEnd, Topic + '(Grid) Item # to jump to when END is pressed'); Form.AddByte ('N', ' End' , 68, 14, 75, 14, 5, 3, 0, 255, @Menu.Item[Num]^.JumpEnd, Topic + Grid + 'END');
WriteXY (26, 21, 120, Status1); WriteXY (26, 21, 120, Status1);
@ -453,19 +454,19 @@ Begin
VerticalLine (22, 7, 19); VerticalLine (22, 7, 19);
Form.AddStr ('D', ' Description ' , 9, 7, 24, 7, 13, 30, 30, @Menu.Info.Description, Topic + 'Description of menu'); Form.AddStr ('D', ' Description' , 9, 7, 24, 7, 13, 30, 30, @Menu.Info.Description, Topic + 'Description of menu');
Form.AddStr ('A', ' Access ' , 14, 8, 24, 8, 8, 30, 30, @Menu.Info.Access, Topic + 'Security requirements to access this menu'); Form.AddStr ('A', ' Access' , 14, 8, 24, 8, 8, 30, 30, @Menu.Info.Access, Topic + 'Security requirements to access this menu');
Form.AddTog ('T', ' Menu Type ' , 11, 9, 24, 9, 11, 13, 0, 2, 'Standard Lightbar Lightbar/Grid', @Menu.Info.MenuType, Topic + 'Type of menu'); Form.AddTog ('T', ' Menu Type' , 11, 9, 24, 9, 11, 13, 0, 2, 'Standard Lightbar Lightbar/Grid', @Menu.Info.MenuType, Topic + 'Type of menu');
Form.AddTog ('I', ' Input Type ' , 10, 10, 24, 10, 12, 12, 0, 2, 'User_Defined HotKey LongKey', @Menu.Info.InputType, Topic + 'Input type for this menu'); Form.AddTog ('I', ' Input Type' , 10, 10, 24, 10, 12, 12, 0, 2, 'User_Defined HotKey LongKey', @Menu.Info.InputType, Topic + 'Input type for this menu');
Form.AddTog ('C', ' Input Chars ' , 9, 11, 24, 11, 13, 9, 0, 2, 'Uppercase Lowercase Hidden', @Menu.Info.CharType, Topic + 'Input format display'); Form.AddTog ('C', ' Input Chars' , 9, 11, 24, 11, 13, 9, 0, 2, 'Uppercase Lowercase Hidden', @Menu.Info.CharType, Topic + 'Input format display');
Form.AddBol ('G', ' Use Global ' , 10, 12, 24, 12, 12, 3, @Menu.Info.Global, Topic + 'Include global menu options in this menu?'); Form.AddBol ('G', ' Use Global' , 10, 12, 24, 12, 12, 3, @Menu.Info.Global, Topic + 'Include global menu options in this menu?');
Form.AddStr ('N', ' Node Status ' , 9, 13, 24, 13, 13, 30, 30, @Menu.Info.NodeStatus, Topic + 'Node/User status set when this menu is loaded'); Form.AddStr ('N', ' Node Status' , 9, 13, 24, 13, 13, 30, 30, @Menu.Info.NodeStatus, Topic + 'Node/User status set when this menu is loaded');
Form.AddStr ('F', ' Display File ', 8, 14, 24, 14, 14, 20, 20, @Menu.Info.DispFile, Topic + 'Display file shown instead of generated menu'); Form.AddStr ('F', ' Display File', 8, 14, 24, 14, 14, 20, 20, @Menu.Info.DispFile, Topic + 'Display file shown instead of generated menu');
Form.AddTog ('L', ' Display Cols ', 8, 15, 24, 15, 14, 1, 1, 4, '1 2 3 4', @Menu.Info.DispCols, Topic + 'Number of columns in generated menu'); Form.AddTog ('L', ' Display Cols', 8, 15, 24, 15, 14, 1, 1, 4, '1 2 3 4', @Menu.Info.DispCols, Topic + 'Number of columns in generated menu');
Form.AddPipe ('H', ' Menu Header ' , 9, 16, 24, 16, 13, 50, 160, @Menu.Info.Header, Topic + 'Menu header displayed in generated menu'); Form.AddPipe ('H', ' Menu Header' , 9, 16, 24, 16, 13, 50, 160, @Menu.Info.Header, Topic + 'Menu header displayed in generated menu');
Form.AddPipe ('P', ' Menu Prompt ' , 9, 17, 24, 17, 13, 50, 160, @Menu.Info.Footer, Topic + 'Menu prompt displayed in generated menu'); Form.AddPipe ('P', ' Menu Prompt' , 9, 17, 24, 17, 13, 50, 160, @Menu.Info.Footer, Topic + 'Menu prompt displayed in generated menu');
Form.AddByte ('X', ' X ' , 19, 18, 24, 18, 3, 2, 0, 80, @Menu.Info.DoneX, Topic + 'Locate to X coordinate after lightbar menu'); Form.AddByte ('X', ' X' , 19, 18, 24, 18, 3, 2, 0, 80, @Menu.Info.DoneX, Topic + 'Locate to X coordinate after lightbar menu');
Form.AddByte ('Y', ' Y ' , 19, 19, 24, 19, 3, 2, 0, 50, @Menu.Info.DoneY, Topic + 'Locate to Y coordinate after lightbar menu'); Form.AddByte ('Y', ' Y' , 19, 19, 24, 19, 3, 2, 0, 50, @Menu.Info.DoneY, Topic + 'Locate to Y coordinate after lightbar menu');
Form.Execute; Form.Execute;

View File

@ -95,6 +95,7 @@ Type
Function InXY (X, Y, Field, Max, Mode: Byte; Default: String) : String; Function InXY (X, Y, Field, Max, Mode: Byte; Default: String) : String;
Function InKey (Wait: LongInt) : Char; Function InKey (Wait: LongInt) : Char;
Function GetYNL (Str: String; Yes: Boolean) : Boolean; Function GetYNL (Str: String; Yes: Boolean) : Boolean;
Function DoInputEvents (Var Ch: Char) : Boolean;
Function GetKey : Char; Function GetKey : Char;
Function GetYN (Str: String; Yes: Boolean) : Boolean; Function GetYN (Str: String; Yes: Boolean) : Boolean;
Function GetPW (Str : String; BadStr : String; PW : String) : Boolean; Function GetPW (Str : String; BadStr : String; PW : String) : Boolean;
@ -1258,9 +1259,76 @@ Begin
End; End;
{$ENDIF} {$ENDIF}
Function TBBSIO.GetKey : Char; Function TBBSIO.DoInputEvents (Var Ch: Char) : Boolean;
Var Var
TimeCount : LongInt; TimeCount : LongInt;
Begin
Result := False;
If InMacro Then
If InMacroPos <= Length(InMacroStr) Then Begin
Ch := InMacroStr[InMacroPos];
Result := True;
Inc (InMacroPos);
Exit;
End Else
InMacro := False;
If TBBSCore(Core).CheckTimeOut Then
If TimerSeconds - TBBSCore(Core).TimeOut >= Config.Inactivity Then Begin
TBBSCore(Core).SystemLog('Inactivity timeout');
OutFullLn (TBBSCore(Core).GetPrompt(136));
Halt(0);
End;
If Session.AllowMessages And Not Session.InMessage Then Begin
Dec (Session.MessageCheck);
If Session.MessageCheck = 0 Then Begin
CheckNodeMessages;
Session.MessageCheck := mysMessageThreshold;
End;
End;
TimeCount := TBBSCore(Core).TimeLeft;
If TimeCount <> Session.LastTimeLeft Then Begin
Session.LastTimeLeft := TimeCount;
{$IFNDEF UNIX}
UpdateStatusLine(StatusPtr, '');
{$ENDIF}
If TBBSCore(Core).TimerOn Then Begin
If TimeCount = 5 Then Begin
If Not TBBSCore(Core).TimeChecked Then Begin
TBBSCore(Core).TimeChecked := True;
OutFullLn (TBBSCore(Core).GetPrompt(134));
End;
End Else
If TimeCount < 1 Then Begin
If Not TBBSCore(Core).TimeChecked Then Begin
TBBSCore(Core).TimeChecked := True;
OutFullLn (TBBSCore(Core).GetPrompt(135));
TBBSCore(Core).SystemLog ('User ran out of time');
Halt(0);
End;
End Else
TBBSCore(Core).TimeChecked := False;
End;
If TBBSCore(Core).NextEvent.Active Then
If (TBBSCore(Core).MinutesUntilEvent(TBBSCore(Core).NextEvent.ExecTime) = TBBSCore(Core).NextEvent.Warning) And
(Not TBBSCore(Core).EventWarn) And (TBBSCore(Core).NextEvent.Forced) Then Begin
TBBSCore(Core).EventWarn := True;
OutFullLn (TBBSCore(Core).GetPrompt(133));
End;
End;
End;
Function TBBSIO.GetKey : Char;
Begin Begin
Result := #255; Result := #255;
@ -1270,7 +1338,6 @@ Begin
Repeat Repeat
If LastSecond <> TimerSeconds Then Begin If LastSecond <> TimerSeconds Then Begin
LastSecond := TimerSeconds; LastSecond := TimerSeconds;
If Assigned(GetKeyCallBack) Then If Assigned(GetKeyCallBack) Then
@ -1279,65 +1346,7 @@ Begin
Exit; Exit;
End; End;
If InMacro Then If DoInputEvents(Result) Then Exit;
If InMacroPos <= Length(InMacroStr) Then Begin
Result := InMacroStr[InMacroPos];
Inc (InMacroPos);
Exit;
End Else
InMacro := False;
If TBBSCore(Core).CheckTimeOut Then
If TimerSeconds - TBBSCore(Core).TimeOut >= Config.Inactivity Then Begin
TBBSCore(Core).SystemLog('Inactivity timeout');
OutFullLn (TBBSCore(Core).GetPrompt(136));
Halt(0);
End;
If Session.AllowMessages And Not Session.InMessage Then Begin
Dec (Session.MessageCheck);
If Session.MessageCheck = 0 Then Begin
CheckNodeMessages;
Session.MessageCheck := mysMessageThreshold;
End;
End;
TimeCount := TBBSCore(Core).TimeLeft;
If TimeCount <> Session.LastTimeLeft Then Begin
Session.LastTimeLeft := TimeCount;
{$IFNDEF UNIX}
UpdateStatusLine(StatusPtr, '');
{$ENDIF}
If TBBSCore(Core).TimerOn Then Begin
If TimeCount = 5 Then Begin
If Not TBBSCore(Core).TimeChecked Then Begin
TBBSCore(Core).TimeChecked := True;
OutFullLn (TBBSCore(Core).GetPrompt(134));
End;
End Else
If TimeCount < 1 Then Begin
If Not TBBSCore(Core).TimeChecked Then Begin
TBBSCore(Core).TimeChecked := True;
OutFullLn (TBBSCore(Core).GetPrompt(135));
TBBSCore(Core).SystemLog ('User ran out of time');
Halt(0);
End;
End Else
TBBSCore(Core).TimeChecked := False;
End;
If TBBSCore(Core).NextEvent.Active Then
If (TBBSCore(Core).MinutesUntilEvent(TBBSCore(Core).NextEvent.ExecTime) = TBBSCore(Core).NextEvent.Warning) And
(Not TBBSCore(Core).EventWarn) And (TBBSCore(Core).NextEvent.Forced) Then Begin
TBBSCore(Core).EventWarn := True;
OutFullLn (TBBSCore(Core).GetPrompt(133));
End;
End;
End; End;
Result := InKey(1000); Result := InKey(1000);

View File

@ -237,7 +237,10 @@ Begin
MenuName := CmdData; MenuName := CmdData;
Result := True; Result := True;
End; End;
'T' : Session.io.OutFull (CmdData); 'T' : Begin
Session.io.OutFull (CmdData);
Session.io.BufFlush;
End;
'U' : ShowUserList (strUpper(CmdData)); 'U' : ShowUserList (strUpper(CmdData));
'X' : Result := ExecuteMPL(NIL, CmdData) = 2; 'X' : Result := ExecuteMPL(NIL, CmdData) = 2;
'?' : Begin '?' : Begin
@ -625,9 +628,10 @@ End;
Function TMenuEngine.MenuGetKey : Char; Function TMenuEngine.MenuGetKey : Char;
Var Var
Current : LongInt;
LastSec : LongInt; LastSec : LongInt;
Begin Begin
Session.io.BufFlush;
LastSec := TimerSeconds; LastSec := TimerSeconds;
While Not TBBSCore(Owner).ShutDown Do Begin While Not TBBSCore(Owner).ShutDown Do Begin
@ -635,24 +639,28 @@ Begin
If TBBSCore(Owner).ShutDown Then Exit; If TBBSCore(Owner).ShutDown Then Exit;
If UseTimer And (TimerSeconds <> LastSec) Then Begin If TimerSeconds <> LastSec Then Begin
LastSec := TimerSeconds; LastSec := TimerSeconds;
Inc (TimerCount); If Session.io.DoInputEvents(Result) Then Exit;
Case ExecuteByHotkey('TIMER', TimerCount) of If UseTimer Then Begin
1 : If ReDraw Then Begin Inc (TimerCount);
Result := #02;
Exit; Case ExecuteByHotkey('TIMER', TimerCount) of
End; 1 : If ReDraw Then Begin
2 : Begin Result := #02;
TimerReload := True; Exit;
Result := #02; End;
Exit; 2 : Begin
End; TimerReload := True;
Result := #02;
Exit;
End;
End;
If TimerCount = 1000000000 Then TimerCount := 0;
End; End;
If TimerCount = 1000000000 Then TimerCount := 0;
End; End;
If Result <> #255 Then Break; If Result <> #255 Then Break;