mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-11-04 05:39:29 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			2568 lines
		
	
	
		
			66 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
			
		
		
	
	
			2568 lines
		
	
	
		
			66 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
{
 | 
						||
    This file is part of the Free Pascal Integrated Development Environment
 | 
						||
    Copyright (c) 1998 by Berczi Gabor
 | 
						||
 | 
						||
    See the file COPYING.FPC, included in this distribution,
 | 
						||
    for details about the copyright.
 | 
						||
 | 
						||
    This program is distributed in the hope that it will be useful,
 | 
						||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 | 
						||
 | 
						||
 **********************************************************************}
 | 
						||
{$I globdir.inc}
 | 
						||
 | 
						||
unit WViews;
 | 
						||
 | 
						||
interface
 | 
						||
 | 
						||
uses Objects,Drivers,Views,Menus,Dialogs;
 | 
						||
 | 
						||
const
 | 
						||
      evIdle                 = $8000;
 | 
						||
 | 
						||
      cmCopyWin = 240;
 | 
						||
      cmPasteWin = 241;
 | 
						||
      cmSelectAll         = 246;
 | 
						||
      cmUnselect          = 247;
 | 
						||
 | 
						||
      cmLocalMenu            = 54100;
 | 
						||
      cmUpdate               = 54101;
 | 
						||
      cmListFocusChanged     = 54102;
 | 
						||
 | 
						||
      mfUserBtn1             = $00010000;
 | 
						||
      mfUserBtn2             = $00020000;
 | 
						||
      mfUserBtn3             = $00040000;
 | 
						||
      mfUserBtn4             = $00080000;
 | 
						||
      mfCantCancel           = $00100000;
 | 
						||
 | 
						||
      cmUserBtn1             = $fee0;
 | 
						||
      cmUserBtn2             = $fee1;
 | 
						||
      cmUserBtn3             = $fee2;
 | 
						||
      cmUserBtn4             = $fee3;
 | 
						||
 | 
						||
      CPlainCluster          = #7#8#9#9;
 | 
						||
 | 
						||
type
 | 
						||
    longstring = ansistring;
 | 
						||
 | 
						||
    PCenterDialog = ^TCenterDialog;
 | 
						||
    TCenterDialog = object(TDialog)
 | 
						||
      constructor Init(var Bounds: TRect; ATitle: TTitleStr);
 | 
						||
    end;
 | 
						||
 | 
						||
    PAdvancedMenuBox = ^TAdvancedMenuBox;
 | 
						||
    TAdvancedMenuBox = object(TMenuBox)
 | 
						||
      function NewSubView(var Bounds: TRect; AMenu: PMenu;
 | 
						||
                 AParentMenu: PMenuView): PMenuView; virtual;
 | 
						||
      function Execute: Word; virtual;
 | 
						||
    end;
 | 
						||
 | 
						||
    PAdvancedMenuPopUp = ^TAdvancedMenuPopup;
 | 
						||
    TAdvancedMenuPopUp = object(TMenuPopup)
 | 
						||
      function NewSubView(var Bounds: TRect; AMenu: PMenu;
 | 
						||
                 AParentMenu: PMenuView): PMenuView; virtual;
 | 
						||
      function Execute: Word; virtual;
 | 
						||
    end;
 | 
						||
 | 
						||
    PAdvancedMenuBar = ^TAdvancedMenuBar;
 | 
						||
    TAdvancedMenuBar = object(TMenuBar)
 | 
						||
      constructor Init(var Bounds: TRect; AMenu: PMenu);
 | 
						||
      function  NewSubView(var Bounds: TRect; AMenu: PMenu;
 | 
						||
                  AParentMenu: PMenuView): PMenuView; virtual;
 | 
						||
      procedure Update; virtual;
 | 
						||
      function  GetMenuItem(cm : word) : PMenuItem;
 | 
						||
      procedure HandleEvent(var Event: TEvent); virtual;
 | 
						||
      function  Execute: Word; virtual;
 | 
						||
    end;
 | 
						||
 | 
						||
    PAdvancedStaticText = ^TAdvancedStaticText;
 | 
						||
    TAdvancedStaticText = object(TStaticText)
 | 
						||
      procedure SetText(S: string); virtual;
 | 
						||
    end;
 | 
						||
 | 
						||
    PAdvancedListBox = ^TAdvancedListBox;
 | 
						||
    TAdvancedListBox = object(TListBox)
 | 
						||
      Default: boolean;
 | 
						||
      procedure   FocusItem(Item: sw_integer); virtual;
 | 
						||
      procedure   HandleEvent(var Event: TEvent); virtual;
 | 
						||
      constructor Load(var S: TStream);
 | 
						||
      procedure   Store(var S: TStream);
 | 
						||
    end;
 | 
						||
 | 
						||
    PNoUpdateButton = ^TNoUpdateButton;
 | 
						||
    TNoUpdateButton = object(TButton)
 | 
						||
      procedure HandleEvent(var Event: TEvent); virtual;
 | 
						||
    end;
 | 
						||
 | 
						||
    TLocalMenuListBox = object(TAdvancedListBox)
 | 
						||
      procedure   HandleEvent(var Event: TEvent); virtual;
 | 
						||
      procedure   LocalMenu(P: TPoint); virtual;
 | 
						||
      function    GetLocalMenu: PMenu; virtual;
 | 
						||
      function    GetCommandTarget: PView; virtual;
 | 
						||
    private
 | 
						||
      LastLocalCmd: word;
 | 
						||
    end;
 | 
						||
 | 
						||
    PColorStaticText = ^TColorStaticText;
 | 
						||
    TColorStaticText = object(TAdvancedStaticText)
 | 
						||
      Color: word;
 | 
						||
      DontWrap: boolean;
 | 
						||
      Delta: TPoint;
 | 
						||
      constructor Init(var Bounds: TRect; AText: String; AColor: word; AWrap: boolean);
 | 
						||
      function    GetPalette: PPalette; virtual;
 | 
						||
      procedure   Draw; virtual;
 | 
						||
      constructor Load(var S: TStream);
 | 
						||
      procedure   Store(var S: TStream);
 | 
						||
    end;
 | 
						||
 | 
						||
    PHSListBox = ^THSListBox;
 | 
						||
    THSListBox = object(TLocalMenuListBox)
 | 
						||
      constructor Init(var Bounds: TRect; ANumCols: Word; AHScrollBar, AVScrollBar: PScrollBar);
 | 
						||
      function    SaveToFile(const AFileName: string): boolean; virtual;
 | 
						||
      function    SaveAs: Boolean; virtual;
 | 
						||
    end;
 | 
						||
 | 
						||
    PDlgWindow = ^TDlgWindow;
 | 
						||
    TDlgWindow = object(TDialog)
 | 
						||
      constructor Init(var Bounds: TRect; ATitle: TTitleStr; ANumber: Sw_Integer);
 | 
						||
      procedure   HandleEvent(var Event: TEvent); virtual;
 | 
						||
      procedure Update; virtual;
 | 
						||
    end;
 | 
						||
 | 
						||
    PAdvancedStatusLine = ^TAdvancedStatusLine;
 | 
						||
    TAdvancedStatusLine = object(TStatusLine)
 | 
						||
      StatusText: PString;
 | 
						||
      function    GetStatusText: string; virtual;
 | 
						||
      procedure   SetStatusText(const S: string); virtual;
 | 
						||
      procedure   ClearStatusText; virtual;
 | 
						||
      procedure   Draw; virtual;
 | 
						||
    end;
 | 
						||
 | 
						||
    PDropDownListBox = ^TDropDownListBox;
 | 
						||
 | 
						||
    PDDHelperLB = ^TDDHelperLB;
 | 
						||
    TDDHelperLB = object(TLocalMenuListBox)
 | 
						||
      constructor Init(ALink: PDropDownListBox; var Bounds: TRect; ANumCols: Word; AScrollBar: PScrollBar);
 | 
						||
      procedure   HandleEvent(var Event: TEvent); virtual;
 | 
						||
      procedure   SetState(AState: Word; Enable: Boolean); virtual;
 | 
						||
      procedure   SelectItem(Item: Sw_Integer); virtual;
 | 
						||
      function    GetText(Item,MaxLen: Sw_Integer): String; virtual;
 | 
						||
      function    GetLocalMenu: PMenu; virtual;
 | 
						||
      function    GetCommandTarget: PView; virtual;
 | 
						||
    private
 | 
						||
      Link : PDropDownListBox;
 | 
						||
      LastTT: longint;
 | 
						||
      InClose: boolean;
 | 
						||
    end;
 | 
						||
 | 
						||
    TDropDownListBox = object(TView)
 | 
						||
      Text: string;
 | 
						||
      Focused: sw_integer;
 | 
						||
      List: PCollection;
 | 
						||
      constructor Init(var Bounds: TRect; ADropLineCount: Sw_integer; AList: PCollection);
 | 
						||
      procedure   HandleEvent(var Event: TEvent); virtual;
 | 
						||
      function    GetText(Item: pointer; MaxLen: sw_integer): string; virtual;
 | 
						||
      procedure   NewList(AList: PCollection); virtual;
 | 
						||
      procedure   CreateListBox(var R: TRect);
 | 
						||
      procedure   DropList(Drop: boolean); virtual;
 | 
						||
      function    GetItemCount: sw_integer; virtual;
 | 
						||
      procedure   FocusItem(Item: sw_integer); virtual;
 | 
						||
      function    LBGetLocalMenu: PMenu; virtual;
 | 
						||
      function    LBGetCommandTarget: PView; virtual;
 | 
						||
      procedure   SetState(AState: Word; Enable: Boolean); virtual;
 | 
						||
      procedure   Draw; virtual;
 | 
						||
      function    GetPalette: PPalette; virtual;
 | 
						||
      destructor  Done; virtual;
 | 
						||
    private
 | 
						||
      DropLineCount: Sw_integer;
 | 
						||
      ListDropped : boolean;
 | 
						||
      ListBox     : PDDHelperLB;
 | 
						||
      SB          : PScrollBar;
 | 
						||
    end;
 | 
						||
 | 
						||
    PGroupView = ^TGroupView;
 | 
						||
    TGroupView = object(TLabel)
 | 
						||
      constructor Init(var Bounds: TRect; AText: String; ALink: PView);
 | 
						||
      procedure   Draw; virtual;
 | 
						||
    end;
 | 
						||
 | 
						||
    PPlainCheckBoxes = ^TPlainCheckBoxes;
 | 
						||
    TPlainCheckBoxes = object(TCheckBoxes)
 | 
						||
      function GetPalette: PPalette; virtual;
 | 
						||
    end;
 | 
						||
 | 
						||
    PPlainRadioButtons = ^TPlainRadioButtons;
 | 
						||
    TPlainRadioButtons = object(TRadioButtons)
 | 
						||
      function GetPalette: PPalette; virtual;
 | 
						||
    end;
 | 
						||
 | 
						||
    PPanel = ^TPanel;
 | 
						||
    TPanel = object(TGroup)
 | 
						||
      constructor Init(var Bounds: TRect);
 | 
						||
    end;
 | 
						||
 | 
						||
    PAdvMessageBox = ^TAdvMessageBox;
 | 
						||
    TAdvMessageBox = object(TDialog)
 | 
						||
      CanCancel: boolean;
 | 
						||
      procedure HandleEvent(var Event: TEvent); virtual;
 | 
						||
    end;
 | 
						||
 | 
						||
procedure InsertOK(ADialog: PDialog);
 | 
						||
procedure InsertButtons(ADialog: PDialog);
 | 
						||
 | 
						||
procedure Bug(const S: string; Params: pointer);
 | 
						||
procedure ErrorBox(const S: string; Params: pointer);
 | 
						||
procedure WarningBox(const S: string; Params: pointer);
 | 
						||
procedure InformationBox(const S: string; Params: pointer);
 | 
						||
function  OKCancelBox(const S: string; Params: pointer): word;
 | 
						||
function  ConfirmBox(const S: string; Params: pointer; CanCancel: boolean): word;
 | 
						||
function  ChoiceBox(const S: string; Params: pointer; Buttons: array of string; CanCancel: boolean): word;
 | 
						||
 | 
						||
procedure ShowMessage(Msg: string);
 | 
						||
procedure HideMessage;
 | 
						||
 | 
						||
function  SearchMenuItem(Menu: PMenu; Cmd: word): PMenuItem;
 | 
						||
procedure SetMenuItemParam(Menu: PMenuItem; Param: string);
 | 
						||
function  IsSubMenu(P: PMenuItem): boolean;
 | 
						||
function  IsSeparator(P: PMenuItem): boolean;
 | 
						||
function  UpdateMenu(M: PMenu): boolean;
 | 
						||
function  SearchSubMenu(M: PMenu; Index: Sw_integer): PMenuItem;
 | 
						||
procedure AppendMenuItem(M: PMenu; I: PMenuItem);
 | 
						||
procedure RemoveMenuItem(Menu: PMenu; I: PMenuItem);
 | 
						||
function  GetMenuItemBefore(Menu:PMenu; BeforeOf: PMenuItem): PMenuItem;
 | 
						||
 | 
						||
procedure NotImplemented;
 | 
						||
 | 
						||
function ColorIndex(Color: byte): word;
 | 
						||
 | 
						||
var  FormatParams     : array[1..20] of ptrint;
 | 
						||
     FormatParamCount : integer;
 | 
						||
     FormatParamStrs  : array[1..10] of string;
 | 
						||
     FormatParamStrCount: integer;
 | 
						||
 | 
						||
procedure ClearFormatParams;
 | 
						||
procedure AddFormatParam(P: pointer);
 | 
						||
procedure AddFormatParamInt(L: longint);
 | 
						||
procedure AddFormatParamChar(C: char);
 | 
						||
procedure AddFormatParamStr(const S: string);
 | 
						||
function FormatStrF(const Format: string; var Params): string;
 | 
						||
function FormatStrStr(const Format, Param: string): string;
 | 
						||
function FormatStrStr2(const Format, Param1,Param2: string): string;
 | 
						||
function FormatStrStr3(const Format, Param1,Param2,Param3: string): string;
 | 
						||
function FormatStrInt(const Format: string; L: PtrInt): string;
 | 
						||
 | 
						||
const UserButtonName : array[1..4] of string[40] = ('User~1~','User~2~','User~3~','User~4~');
 | 
						||
 | 
						||
procedure InitAdvMsgBox;
 | 
						||
function AdvMessageBox(const Msg: String; Params: Pointer; AOptions: longint): Word;
 | 
						||
function AdvMessageBoxRect(var R: TRect; const Msg: String; Params: Pointer; AOptions: longint): Word;
 | 
						||
procedure DoneAdvMsgBox;
 | 
						||
 | 
						||
procedure RegisterWViews;
 | 
						||
 | 
						||
implementation
 | 
						||
 | 
						||
uses Mouse,
 | 
						||
{     Resource,}
 | 
						||
{$ifdef WinClipSupported}
 | 
						||
     WinClip,
 | 
						||
     FpConst,
 | 
						||
{$endif WinClipSupported}
 | 
						||
     FVConsts,
 | 
						||
     App,MsgBox,StdDlg,
 | 
						||
     WConsts,WUtils;
 | 
						||
 | 
						||
{$ifndef NOOBJREG}
 | 
						||
const
 | 
						||
  RAdvancedListBox: TStreamRec = (
 | 
						||
     ObjType: 1120;
 | 
						||
     VmtLink: Ofs(TypeOf(TAdvancedListBox)^);
 | 
						||
     Load:    @TAdvancedListBox.Load;
 | 
						||
     Store:   @TAdvancedListBox.Store
 | 
						||
  );
 | 
						||
  RColorStaticText: TStreamRec = (
 | 
						||
     ObjType: 1121;
 | 
						||
     VmtLink: Ofs(TypeOf(TColorStaticText)^);
 | 
						||
     Load:    @TColorStaticText.Load;
 | 
						||
     Store:   @TColorStaticText.Store
 | 
						||
  );
 | 
						||
  RHSListBox: TStreamRec = (
 | 
						||
     ObjType: 1122;
 | 
						||
     VmtLink: Ofs(TypeOf(THSListBox)^);
 | 
						||
     Load:    @THSListBox.Load;
 | 
						||
     Store:   @THSListBox.Store
 | 
						||
  );
 | 
						||
  RDlgWindow: TStreamRec = (
 | 
						||
     ObjType: 1123;
 | 
						||
     VmtLink: Ofs(TypeOf(TDlgWindow)^);
 | 
						||
     Load:    @TDlgWindow.Load;
 | 
						||
     Store:   @TDlgWindow.Store
 | 
						||
  );
 | 
						||
{$endif}
 | 
						||
 | 
						||
{$ifdef USERESSTRINGS}
 | 
						||
    resourcestring
 | 
						||
{$else}
 | 
						||
    const
 | 
						||
{$endif}
 | 
						||
      sConfirm='Confirm';
 | 
						||
      sError='Error';
 | 
						||
      sInformation='Information';
 | 
						||
      sWarning='Warning';
 | 
						||
 | 
						||
const
 | 
						||
  MessageDialog  : PCenterDialog = nil;
 | 
						||
  UserButtonCmd  : array[Low(UserButtonName)..High(UserButtonName)] of word = (cmUserBtn1,cmUserBtn2,cmUserBtn3,cmUserBtn4);
 | 
						||
{$ifdef WinClipSupported}
 | 
						||
  FromWinClipCmds    : TCommandSet = ([cmPasteWin]);
 | 
						||
{$endif WinClipSupported}
 | 
						||
 | 
						||
function ColorIndex(Color: byte): word;
 | 
						||
begin
 | 
						||
  ColorIndex:=(Color and $0f)+(Color and $0f) shl 4;
 | 
						||
end;
 | 
						||
 | 
						||
{*****************************************************************************
 | 
						||
                              TCenterDialog
 | 
						||
*****************************************************************************}
 | 
						||
 | 
						||
constructor TCenterDialog.Init(var Bounds: TRect; ATitle: TTitleStr);
 | 
						||
begin
 | 
						||
  inherited Init(Bounds,ATitle);
 | 
						||
  Options:=Options or ofCentered;
 | 
						||
end;
 | 
						||
 | 
						||
function TAdvancedMenuBox.NewSubView(var Bounds: TRect; AMenu: PMenu;
 | 
						||
  AParentMenu: PMenuView): PMenuView;
 | 
						||
begin
 | 
						||
  NewSubView := New(PAdvancedMenuBox, Init(Bounds, AMenu, AParentMenu));
 | 
						||
end;
 | 
						||
 | 
						||
function TAdvancedMenuBox.Execute: word;
 | 
						||
type
 | 
						||
  MenuAction = (DoNothing, DoSelect, DoReturn);
 | 
						||
var
 | 
						||
  AutoSelect: Boolean;
 | 
						||
  Action: MenuAction;
 | 
						||
  Ch: Char;
 | 
						||
  Res: Word;
 | 
						||
  ItemShown, P: PMenuItem;
 | 
						||
{$ifdef WinClipSupported}
 | 
						||
  PPW: PMenuItem;
 | 
						||
  WinClipEmpty: boolean;
 | 
						||
{$endif WinClipSupported}
 | 
						||
  Target: PMenuView;
 | 
						||
  R: TRect;
 | 
						||
  E: TEvent;
 | 
						||
  MouseActive: Boolean;
 | 
						||
function IsDisabled(Item: PMenuItem): boolean;
 | 
						||
var Found: boolean;
 | 
						||
begin
 | 
						||
  Found:=Item^.Disabled or IsSeparator(Item);
 | 
						||
  if (Found=false) and (IsSubMenu(Item)=false) then
 | 
						||
     Found:=CommandEnabled(Item^.Command)=false;
 | 
						||
  IsDisabled:=Found;
 | 
						||
end;
 | 
						||
 | 
						||
procedure TrackMouse;
 | 
						||
var
 | 
						||
  Mouse: TPoint;
 | 
						||
  R: TRect;
 | 
						||
begin
 | 
						||
  MakeLocal(E.Where, Mouse);
 | 
						||
  Current := Menu^.Items;
 | 
						||
  while Current <> nil do
 | 
						||
  begin
 | 
						||
    GetItemRect(Current, R);
 | 
						||
    if R.Contains(Mouse) then
 | 
						||
    begin
 | 
						||
      MouseActive := True;
 | 
						||
      Break;
 | 
						||
    end;
 | 
						||
    Current := Current^.Next;
 | 
						||
  end;
 | 
						||
  if (Current<>nil) and IsDisabled(Current) then
 | 
						||
  begin
 | 
						||
     Current:=nil;
 | 
						||
     MouseActive:=false;
 | 
						||
  end;
 | 
						||
end;
 | 
						||
 | 
						||
procedure TrackKey(FindNext: Boolean);
 | 
						||
 | 
						||
procedure NextItem;
 | 
						||
begin
 | 
						||
  Current := Current^.Next;
 | 
						||
  if Current = nil then Current := Menu^.Items;
 | 
						||
end;
 | 
						||
 | 
						||
procedure PrevItem;
 | 
						||
var
 | 
						||
  P: PMenuItem;
 | 
						||
begin
 | 
						||
  P := Current;
 | 
						||
  if P = Menu^.Items then P := nil;
 | 
						||
  repeat NextItem until Current^.Next = P;
 | 
						||
end;
 | 
						||
 | 
						||
begin
 | 
						||
  if Current <> nil then
 | 
						||
    repeat
 | 
						||
      if FindNext then NextItem else PrevItem;
 | 
						||
    until (Current^.Name <> nil) and (IsDisabled(Current)=false);
 | 
						||
end;
 | 
						||
 | 
						||
function MouseInOwner: Boolean;
 | 
						||
var
 | 
						||
  Mouse: TPoint;
 | 
						||
  R: TRect;
 | 
						||
begin
 | 
						||
  MouseInOwner := False;
 | 
						||
  if (ParentMenu <> nil) and (ParentMenu^.Size.Y = 1) then
 | 
						||
  begin
 | 
						||
    ParentMenu^.MakeLocal(E.Where, Mouse);
 | 
						||
    ParentMenu^.GetItemRect(ParentMenu^.Current, R);
 | 
						||
    MouseInOwner := R.Contains(Mouse);
 | 
						||
  end;
 | 
						||
end;
 | 
						||
 | 
						||
function MouseInMenus: Boolean;
 | 
						||
var
 | 
						||
  P: PMenuView;
 | 
						||
begin
 | 
						||
  P := ParentMenu;
 | 
						||
  while (P <> nil) and (P^.MouseInView(E.Where)=false) do
 | 
						||
        P := P^.ParentMenu;
 | 
						||
  MouseInMenus := P <> nil;
 | 
						||
end;
 | 
						||
 | 
						||
function TopMenu: PMenuView;
 | 
						||
var
 | 
						||
  P: PMenuView;
 | 
						||
begin
 | 
						||
  P := @Self;
 | 
						||
  while P^.ParentMenu <> nil do P := P^.ParentMenu;
 | 
						||
  TopMenu := P;
 | 
						||
end;
 | 
						||
 | 
						||
begin
 | 
						||
  AutoSelect := False; E.What:=evNothing;
 | 
						||
  Res := 0;
 | 
						||
  ItemShown := nil;
 | 
						||
{$ifdef WinClipSupported}
 | 
						||
  PPW:=SearchMenuItem(Menu,cmPasteWin);
 | 
						||
  if Assigned(PPW) then
 | 
						||
    begin
 | 
						||
      WinClipEmpty:=GetTextWinClipboardSize=0;
 | 
						||
      SetCmdState(FromWinClipCmds,Not WinClipEmpty);
 | 
						||
      PPW^.disabled:=WinClipEmpty;
 | 
						||
    end;
 | 
						||
{$endif WinClipSupported}
 | 
						||
  Current := Menu^.Default;
 | 
						||
  MouseActive := False;
 | 
						||
  if UpdateMenu(Menu) then
 | 
						||
 begin
 | 
						||
  if Current<>nil then
 | 
						||
    if Current^.Disabled then
 | 
						||
       TrackKey(true);
 | 
						||
  repeat
 | 
						||
    Action := DoNothing;
 | 
						||
{$ifdef WinClipSupported}
 | 
						||
    If Assigned(PPW) then
 | 
						||
      begin
 | 
						||
        If WinClipEmpty and (GetTextWinClipboardSize>0) then
 | 
						||
          begin
 | 
						||
            WinClipEmpty:=false;
 | 
						||
            SetCmdState(FromWinClipCmds,true);
 | 
						||
            PPW^.disabled:=WinClipEmpty;
 | 
						||
            DrawView;
 | 
						||
          end
 | 
						||
        else if Not WinClipEmpty and (GetTextWinClipboardSize=0) then
 | 
						||
          begin
 | 
						||
            WinClipEmpty:=true;
 | 
						||
            SetCmdState(FromWinClipCmds,false);
 | 
						||
            PPW^.disabled:=WinClipEmpty;
 | 
						||
            DrawView;
 | 
						||
          end;
 | 
						||
      end;
 | 
						||
{$endif WinClipSupported}
 | 
						||
    GetEvent(E);
 | 
						||
    case E.What of
 | 
						||
      evMouseDown:
 | 
						||
        if MouseInView(E.Where) or MouseInOwner then
 | 
						||
        begin
 | 
						||
          TrackMouse;
 | 
						||
          if Size.Y = 1 then AutoSelect := True;
 | 
						||
        end else Action := DoReturn;
 | 
						||
      evMouseUp:
 | 
						||
        begin
 | 
						||
          TrackMouse;
 | 
						||
          if MouseInOwner then
 | 
						||
            Current := Menu^.Default
 | 
						||
          else
 | 
						||
            if (Current <> nil) and (Current^.Name <> nil) then
 | 
						||
              Action := DoSelect
 | 
						||
            else
 | 
						||
              if MouseActive or MouseInView(E.Where) then Action := DoReturn
 | 
						||
              else
 | 
						||
              begin
 | 
						||
                Current := Menu^.Default;
 | 
						||
                if Current = nil then Current := Menu^.Items;
 | 
						||
                Action := DoNothing;
 | 
						||
              end;
 | 
						||
        end;
 | 
						||
      evMouseMove:
 | 
						||
        if E.Buttons <> 0 then
 | 
						||
        begin
 | 
						||
          TrackMouse;
 | 
						||
          if not (MouseInView(E.Where) or MouseInOwner) and
 | 
						||
            MouseInMenus then Action := DoReturn;
 | 
						||
        end;
 | 
						||
      evKeyDown:
 | 
						||
        case CtrlToArrow(E.KeyCode) of
 | 
						||
          kbUp, kbDown:
 | 
						||
            if Size.Y <> 1 then
 | 
						||
              TrackKey(CtrlToArrow(E.KeyCode) = kbDown) else
 | 
						||
              if E.KeyCode = kbDown then AutoSelect := True;
 | 
						||
          kbLeft, kbRight:
 | 
						||
            if ParentMenu = nil then
 | 
						||
              TrackKey(CtrlToArrow(E.KeyCode) = kbRight) else
 | 
						||
              Action := DoReturn;
 | 
						||
          kbHome, kbEnd:
 | 
						||
            if Size.Y <> 1 then
 | 
						||
            begin
 | 
						||
              Current := Menu^.Items;
 | 
						||
              if E.KeyCode = kbEnd then TrackKey(False);
 | 
						||
            end;
 | 
						||
          kbEnter:
 | 
						||
            begin
 | 
						||
              if Size.Y = 1 then AutoSelect := True;
 | 
						||
              Action := DoSelect;
 | 
						||
            end;
 | 
						||
          kbEsc:
 | 
						||
            begin
 | 
						||
              Action := DoReturn;
 | 
						||
              if (ParentMenu = nil) or (ParentMenu^.Size.Y <> 1) then
 | 
						||
                ClearEvent(E);
 | 
						||
            end;
 | 
						||
        else
 | 
						||
          Target := @Self;
 | 
						||
          Ch := GetAltChar(E.KeyCode);
 | 
						||
          if Ch = #0 then Ch := E.CharCode else Target := TopMenu;
 | 
						||
          P := Target^.FindItem(Ch);
 | 
						||
          if P = nil then
 | 
						||
          begin
 | 
						||
            P := TopMenu^.HotKey(E.KeyCode);
 | 
						||
            if (P <> nil) and CommandEnabled(P^.Command) then
 | 
						||
            begin
 | 
						||
              Res := P^.Command;
 | 
						||
              Action := DoReturn;
 | 
						||
            end
 | 
						||
          end else
 | 
						||
            if Target = @Self then
 | 
						||
            begin
 | 
						||
              if Size.Y = 1 then AutoSelect := True;
 | 
						||
              Action := DoSelect;
 | 
						||
              Current := P;
 | 
						||
            end else
 | 
						||
              if (ParentMenu <> Target) or (ParentMenu^.Current <> P) then
 | 
						||
                Action := DoReturn;
 | 
						||
        end;
 | 
						||
      evCommand:
 | 
						||
        if E.Command = cmMenu then
 | 
						||
        begin
 | 
						||
          AutoSelect := False;
 | 
						||
          if ParentMenu <> nil then Action := DoReturn;
 | 
						||
        end else Action := DoReturn;
 | 
						||
    end;
 | 
						||
    if ItemShown <> Current then
 | 
						||
    begin
 | 
						||
      ItemShown := Current;
 | 
						||
      DrawView;
 | 
						||
    end;
 | 
						||
    if (Action = DoSelect) or ((Action = DoNothing) and AutoSelect) then
 | 
						||
      if Current <> nil then with Current^ do if Name <> nil then
 | 
						||
        if Command = 0 then
 | 
						||
        begin
 | 
						||
          if E.What and (evMouseDown + evMouseMove) <> 0 then PutEvent(E);
 | 
						||
          GetItemRect(Current, R);
 | 
						||
          R.A.X := R.A.X + Origin.X;
 | 
						||
          R.A.Y := R.B.Y + Origin.Y;
 | 
						||
          R.B := Owner^.Size;
 | 
						||
          if Size.Y = 1 then Dec(R.A.X);
 | 
						||
          Target := TopMenu^.NewSubView(R, SubMenu, @Self);
 | 
						||
          Res := Owner^.ExecView(Target);
 | 
						||
          Dispose(Target, Done);
 | 
						||
        end else if Action = DoSelect then Res := Command;
 | 
						||
    if (Res <> 0) and CommandEnabled(Res) then
 | 
						||
    begin
 | 
						||
      Action := DoReturn;
 | 
						||
      ClearEvent(E);
 | 
						||
    end
 | 
						||
    else
 | 
						||
      Res := 0;
 | 
						||
  until Action = DoReturn;
 | 
						||
 end;
 | 
						||
  if E.What <> evNothing then
 | 
						||
    if (ParentMenu <> nil) or (E.What = evCommand) then PutEvent(E);
 | 
						||
  if Current <> nil then
 | 
						||
  begin
 | 
						||
    Menu^.Default := Current;
 | 
						||
    Current := nil;
 | 
						||
    DrawView;
 | 
						||
  end;
 | 
						||
  Execute := Res;
 | 
						||
end;
 | 
						||
 | 
						||
function TAdvancedMenuPopup.NewSubView(var Bounds: TRect; AMenu: PMenu;
 | 
						||
  AParentMenu: PMenuView): PMenuView;
 | 
						||
begin
 | 
						||
  NewSubView := New(PAdvancedMenuBox, Init(Bounds, AMenu, AParentMenu));
 | 
						||
end;
 | 
						||
 | 
						||
function TAdvancedMenuPopup.Execute: word;
 | 
						||
type
 | 
						||
  MenuAction = (DoNothing, DoSelect, DoReturn);
 | 
						||
var
 | 
						||
  AutoSelect: Boolean;
 | 
						||
  Action: MenuAction;
 | 
						||
  Ch: Char;
 | 
						||
  Res: Word;
 | 
						||
  ItemShown, P: PMenuItem;
 | 
						||
  Target: PMenuView;
 | 
						||
  R: TRect;
 | 
						||
  E: TEvent;
 | 
						||
  MouseActive: Boolean;
 | 
						||
function IsDisabled(Item: PMenuItem): boolean;
 | 
						||
var Found: boolean;
 | 
						||
begin
 | 
						||
  Found:=Item^.Disabled or IsSeparator(Item);
 | 
						||
  if (Found=false) and (IsSubMenu(Item)=false) then
 | 
						||
     Found:=CommandEnabled(Item^.Command)=false;
 | 
						||
  IsDisabled:=Found;
 | 
						||
end;
 | 
						||
 | 
						||
procedure TrackMouse;
 | 
						||
var
 | 
						||
  Mouse: TPoint;
 | 
						||
  R: TRect;
 | 
						||
begin
 | 
						||
  MakeLocal(E.Where, Mouse);
 | 
						||
  Current := Menu^.Items;
 | 
						||
  while Current <> nil do
 | 
						||
  begin
 | 
						||
    GetItemRect(Current, R);
 | 
						||
    if R.Contains(Mouse) then
 | 
						||
    begin
 | 
						||
      MouseActive := True;
 | 
						||
      Break;
 | 
						||
    end;
 | 
						||
    Current := Current^.Next;
 | 
						||
  end;
 | 
						||
  if (Current<>nil) and IsDisabled(Current) then
 | 
						||
  begin
 | 
						||
     Current:=nil;
 | 
						||
     MouseActive:=false;
 | 
						||
  end;
 | 
						||
end;
 | 
						||
 | 
						||
procedure TrackKey(FindNext: Boolean);
 | 
						||
 | 
						||
procedure NextItem;
 | 
						||
begin
 | 
						||
  Current := Current^.Next;
 | 
						||
  if Current = nil then Current := Menu^.Items;
 | 
						||
end;
 | 
						||
 | 
						||
procedure PrevItem;
 | 
						||
var
 | 
						||
  P: PMenuItem;
 | 
						||
begin
 | 
						||
  P := Current;
 | 
						||
  if P = Menu^.Items then P := nil;
 | 
						||
  repeat NextItem until Current^.Next = P;
 | 
						||
end;
 | 
						||
 | 
						||
begin
 | 
						||
  if Current <> nil then
 | 
						||
    repeat
 | 
						||
      if FindNext then NextItem else PrevItem;
 | 
						||
    until (Current^.Name <> nil) and (IsDisabled(Current)=false);
 | 
						||
end;
 | 
						||
 | 
						||
function MouseInOwner: Boolean;
 | 
						||
var
 | 
						||
  Mouse: TPoint;
 | 
						||
  R: TRect;
 | 
						||
begin
 | 
						||
  MouseInOwner := False;
 | 
						||
  if (ParentMenu <> nil) and (ParentMenu^.Size.Y = 1) then
 | 
						||
  begin
 | 
						||
    ParentMenu^.MakeLocal(E.Where, Mouse);
 | 
						||
    ParentMenu^.GetItemRect(ParentMenu^.Current, R);
 | 
						||
    MouseInOwner := R.Contains(Mouse);
 | 
						||
  end;
 | 
						||
end;
 | 
						||
 | 
						||
function MouseInMenus: Boolean;
 | 
						||
var
 | 
						||
  P: PMenuView;
 | 
						||
begin
 | 
						||
  P := ParentMenu;
 | 
						||
  while (P <> nil) and (P^.MouseInView(E.Where)=false) do
 | 
						||
        P := P^.ParentMenu;
 | 
						||
  MouseInMenus := P <> nil;
 | 
						||
end;
 | 
						||
 | 
						||
function TopMenu: PMenuView;
 | 
						||
var
 | 
						||
  P: PMenuView;
 | 
						||
begin
 | 
						||
  P := @Self;
 | 
						||
  while P^.ParentMenu <> nil do P := P^.ParentMenu;
 | 
						||
  TopMenu := P;
 | 
						||
end;
 | 
						||
 | 
						||
begin
 | 
						||
  AutoSelect := False; E.What:=evNothing;
 | 
						||
  Res := 0;
 | 
						||
  ItemShown := nil;
 | 
						||
  Current := Menu^.Default;
 | 
						||
  MouseActive := False;
 | 
						||
  if UpdateMenu(Menu) then
 | 
						||
 begin
 | 
						||
  if Current<>nil then
 | 
						||
    if Current^.Disabled then
 | 
						||
       TrackKey(true);
 | 
						||
  repeat
 | 
						||
    Action := DoNothing;
 | 
						||
    GetEvent(E);
 | 
						||
    case E.What of
 | 
						||
      evMouseDown:
 | 
						||
        if MouseInView(E.Where) or MouseInOwner then
 | 
						||
        begin
 | 
						||
          TrackMouse;
 | 
						||
          if Size.Y = 1 then AutoSelect := True;
 | 
						||
        end else Action := DoReturn;
 | 
						||
      evMouseUp:
 | 
						||
        begin
 | 
						||
          TrackMouse;
 | 
						||
          if MouseInOwner then
 | 
						||
            Current := Menu^.Default
 | 
						||
          else
 | 
						||
            if (Current <> nil) and (Current^.Name <> nil) then
 | 
						||
              Action := DoSelect
 | 
						||
            else
 | 
						||
              if MouseActive or MouseInView(E.Where) then Action := DoReturn
 | 
						||
              else
 | 
						||
              begin
 | 
						||
                Current := Menu^.Default;
 | 
						||
                if Current = nil then Current := Menu^.Items;
 | 
						||
                Action := DoNothing;
 | 
						||
              end;
 | 
						||
        end;
 | 
						||
      evMouseMove:
 | 
						||
        if E.Buttons <> 0 then
 | 
						||
        begin
 | 
						||
          TrackMouse;
 | 
						||
          if not (MouseInView(E.Where) or MouseInOwner) and
 | 
						||
            MouseInMenus then Action := DoReturn;
 | 
						||
        end;
 | 
						||
      evKeyDown:
 | 
						||
        case CtrlToArrow(E.KeyCode) of
 | 
						||
          kbUp, kbDown:
 | 
						||
            if Size.Y <> 1 then
 | 
						||
              TrackKey(CtrlToArrow(E.KeyCode) = kbDown) else
 | 
						||
              if E.KeyCode = kbDown then AutoSelect := True;
 | 
						||
          kbLeft, kbRight:
 | 
						||
            if ParentMenu = nil then
 | 
						||
              TrackKey(CtrlToArrow(E.KeyCode) = kbRight) else
 | 
						||
              Action := DoReturn;
 | 
						||
          kbHome, kbEnd:
 | 
						||
            if Size.Y <> 1 then
 | 
						||
            begin
 | 
						||
              Current := Menu^.Items;
 | 
						||
              if E.KeyCode = kbEnd then TrackKey(False);
 | 
						||
            end;
 | 
						||
          kbEnter:
 | 
						||
            begin
 | 
						||
              if Size.Y = 1 then AutoSelect := True;
 | 
						||
              Action := DoSelect;
 | 
						||
            end;
 | 
						||
          kbEsc:
 | 
						||
            begin
 | 
						||
              Action := DoReturn;
 | 
						||
              if (ParentMenu = nil) or (ParentMenu^.Size.Y <> 1) then
 | 
						||
                ClearEvent(E);
 | 
						||
            end;
 | 
						||
        else
 | 
						||
          Target := @Self;
 | 
						||
          Ch := GetAltChar(E.KeyCode);
 | 
						||
          if Ch = #0 then Ch := E.CharCode else Target := TopMenu;
 | 
						||
          P := Target^.FindItem(Ch);
 | 
						||
          if P = nil then
 | 
						||
          begin
 | 
						||
            P := TopMenu^.HotKey(E.KeyCode);
 | 
						||
            if (P <> nil) and CommandEnabled(P^.Command) then
 | 
						||
            begin
 | 
						||
              Res := P^.Command;
 | 
						||
              Action := DoReturn;
 | 
						||
            end
 | 
						||
          end else
 | 
						||
            if Target = @Self then
 | 
						||
            begin
 | 
						||
              if Size.Y = 1 then AutoSelect := True;
 | 
						||
              Action := DoSelect;
 | 
						||
              Current := P;
 | 
						||
            end else
 | 
						||
              if (ParentMenu <> Target) or (ParentMenu^.Current <> P) then
 | 
						||
                Action := DoReturn;
 | 
						||
        end;
 | 
						||
      evCommand:
 | 
						||
        if E.Command = cmMenu then
 | 
						||
        begin
 | 
						||
          AutoSelect := False;
 | 
						||
          if ParentMenu <> nil then Action := DoReturn;
 | 
						||
        end else Action := DoReturn;
 | 
						||
    end;
 | 
						||
    if ItemShown <> Current then
 | 
						||
    begin
 | 
						||
      ItemShown := Current;
 | 
						||
      DrawView;
 | 
						||
    end;
 | 
						||
    if (Action = DoSelect) or ((Action = DoNothing) and AutoSelect) then
 | 
						||
      if Current <> nil then with Current^ do if Name <> nil then
 | 
						||
        if Command = 0 then
 | 
						||
        begin
 | 
						||
          if E.What and (evMouseDown + evMouseMove) <> 0 then PutEvent(E);
 | 
						||
          GetItemRect(Current, R);
 | 
						||
          R.A.X := R.A.X + Origin.X;
 | 
						||
          R.A.Y := R.B.Y + Origin.Y;
 | 
						||
          R.B := Owner^.Size;
 | 
						||
          if Size.Y = 1 then Dec(R.A.X);
 | 
						||
          Target := TopMenu^.NewSubView(R, SubMenu, @Self);
 | 
						||
          Res := Owner^.ExecView(Target);
 | 
						||
          Dispose(Target, Done);
 | 
						||
        end else if Action = DoSelect then Res := Command;
 | 
						||
    if (Res <> 0) and CommandEnabled(Res) then
 | 
						||
    begin
 | 
						||
      Action := DoReturn;
 | 
						||
      ClearEvent(E);
 | 
						||
    end
 | 
						||
    else
 | 
						||
      Res := 0;
 | 
						||
  until Action = DoReturn;
 | 
						||
 end;
 | 
						||
  if E.What <> evNothing then
 | 
						||
    if (ParentMenu <> nil) or (E.What = evCommand) then PutEvent(E);
 | 
						||
  if Current <> nil then
 | 
						||
  begin
 | 
						||
    Menu^.Default := Current;
 | 
						||
    Current := nil;
 | 
						||
    DrawView;
 | 
						||
  end;
 | 
						||
  Execute := Res;
 | 
						||
end;
 | 
						||
 | 
						||
constructor TAdvancedMenuBar.Init(var Bounds: TRect; AMenu: PMenu);
 | 
						||
begin
 | 
						||
  inherited Init(Bounds, AMenu);
 | 
						||
  EventMask:=EventMask or evBroadcast;
 | 
						||
  GrowMode:=gfGrowHiX;
 | 
						||
end;
 | 
						||
 | 
						||
function TAdvancedMenuBar.NewSubView(var Bounds: TRect; AMenu: PMenu;
 | 
						||
  AParentMenu: PMenuView): PMenuView;
 | 
						||
begin
 | 
						||
  NewSubView := New(PAdvancedMenuBox, Init(Bounds, AMenu, AParentMenu));
 | 
						||
end;
 | 
						||
 | 
						||
procedure TAdvancedMenuBar.Update;
 | 
						||
begin
 | 
						||
  UpdateMenu(Menu);
 | 
						||
  DrawView;
 | 
						||
end;
 | 
						||
 | 
						||
function  TAdvancedMenuBar.GetMenuItem(cm : word) : PMenuItem;
 | 
						||
type
 | 
						||
   PItemChain = ^TItemChain;
 | 
						||
   TItemChain = record
 | 
						||
     Next : PMenuItem;
 | 
						||
     Up   : PItemChain;
 | 
						||
   end;
 | 
						||
var Cur : PMenuItem;
 | 
						||
    Up,NUp  : PItemChain;
 | 
						||
begin
 | 
						||
  Cur:=Menu^.Items;
 | 
						||
  Up:=nil;
 | 
						||
  if cm=0 then
 | 
						||
    begin
 | 
						||
      GetMenuItem:=nil;
 | 
						||
      exit;
 | 
						||
    end;
 | 
						||
  while assigned(Cur) and (Cur^.Command<>cm) do
 | 
						||
    begin
 | 
						||
      if (Cur^.Command=0) and assigned(Cur^.SubMenu) and
 | 
						||
         assigned(Cur^.Name) and
 | 
						||
         assigned(Cur^.SubMenu^.Items) then
 | 
						||
        {subMenu}
 | 
						||
        begin
 | 
						||
          If assigned(Cur^.Next) then
 | 
						||
            begin
 | 
						||
              New(Nup);
 | 
						||
              Nup^.Up:=Up;
 | 
						||
              Nup^.next:=Cur^.Next;
 | 
						||
              Up:=Nup;
 | 
						||
            end;
 | 
						||
          Cur:=Cur^.SubMenu^.Items;
 | 
						||
        end
 | 
						||
      else
 | 
						||
        { normal item }
 | 
						||
        begin
 | 
						||
          if assigned(Cur^.Next) then
 | 
						||
            Cur:=Cur^.Next
 | 
						||
          else if assigned(Up) then
 | 
						||
            begin
 | 
						||
              Cur:=Up^.next;
 | 
						||
              NUp:=Up;
 | 
						||
              Up:=Up^.Up;
 | 
						||
              Dispose(NUp);
 | 
						||
            end
 | 
						||
          else
 | 
						||
            Cur:=Nil;
 | 
						||
        end;
 | 
						||
    end;
 | 
						||
  GetMenuItem:=Cur;
 | 
						||
  While assigned(Up) do
 | 
						||
    begin
 | 
						||
      NUp:=Up;
 | 
						||
      Up:=Up^.up;
 | 
						||
      Dispose(NUp);
 | 
						||
    end;
 | 
						||
end;
 | 
						||
 | 
						||
procedure TAdvancedMenuBar.HandleEvent(var Event: TEvent);
 | 
						||
begin
 | 
						||
  case Event.What of
 | 
						||
    evBroadcast :
 | 
						||
      case Event.Command of
 | 
						||
        cmCommandSetChanged : Update;
 | 
						||
        cmUpdate            : Update;
 | 
						||
      end;
 | 
						||
  end;
 | 
						||
  inherited HandleEvent(Event);
 | 
						||
end;
 | 
						||
 | 
						||
function TAdvancedMenuBar.Execute: word;
 | 
						||
type
 | 
						||
  MenuAction = (DoNothing, DoSelect, DoReturn);
 | 
						||
var
 | 
						||
  AutoSelect: Boolean;
 | 
						||
  Action: MenuAction;
 | 
						||
  Ch: Char;
 | 
						||
  Res: Word;
 | 
						||
  ItemShown, P: PMenuItem;
 | 
						||
  Target: PMenuView;
 | 
						||
  R: TRect;
 | 
						||
  E: TEvent;
 | 
						||
  MouseActive: Boolean;
 | 
						||
function IsDisabled(Item: PMenuItem): boolean;
 | 
						||
var Dis : boolean;
 | 
						||
begin
 | 
						||
  Dis:=Item^.Disabled or IsSeparator(Item);
 | 
						||
  if (Dis=false) and (IsSubMenu(Item)=false) then
 | 
						||
     Dis:=CommandEnabled(Item^.Command)=false;
 | 
						||
  IsDisabled:=Dis;
 | 
						||
end;
 | 
						||
 | 
						||
procedure TrackMouse;
 | 
						||
var
 | 
						||
  Mouse: TPoint;
 | 
						||
  R: TRect;
 | 
						||
begin
 | 
						||
  MakeLocal(E.Where, Mouse);
 | 
						||
  Current := Menu^.Items;
 | 
						||
  while Current <> nil do
 | 
						||
  begin
 | 
						||
    GetItemRect(Current, R);
 | 
						||
    if R.Contains(Mouse) then
 | 
						||
    begin
 | 
						||
      MouseActive := True;
 | 
						||
      Break;
 | 
						||
    end;
 | 
						||
    Current := Current^.Next;
 | 
						||
  end;
 | 
						||
  if (Current<>nil) and IsDisabled(Current) then
 | 
						||
    Current:=nil;
 | 
						||
end;
 | 
						||
 | 
						||
procedure TrackKey(FindNext: Boolean);
 | 
						||
 | 
						||
procedure NextItem;
 | 
						||
begin
 | 
						||
  Current := Current^.Next;
 | 
						||
  if Current = nil then Current := Menu^.Items;
 | 
						||
end;
 | 
						||
 | 
						||
procedure PrevItem;
 | 
						||
var
 | 
						||
  P: PMenuItem;
 | 
						||
begin
 | 
						||
  P := Current;
 | 
						||
  if P = Menu^.Items then P := nil;
 | 
						||
  repeat NextItem until Current^.Next = P;
 | 
						||
end;
 | 
						||
 | 
						||
begin
 | 
						||
  if Current <> nil then
 | 
						||
    repeat
 | 
						||
      if FindNext then NextItem else PrevItem;
 | 
						||
    until (Current^.Name <> nil) and (IsDisabled(Current)=false);
 | 
						||
end;
 | 
						||
 | 
						||
function MouseInOwner: Boolean;
 | 
						||
var
 | 
						||
  Mouse: TPoint;
 | 
						||
  R: TRect;
 | 
						||
begin
 | 
						||
  MouseInOwner := False;
 | 
						||
  if (ParentMenu <> nil) and (ParentMenu^.Size.Y = 1) then
 | 
						||
  begin
 | 
						||
    ParentMenu^.MakeLocal(E.Where, Mouse);
 | 
						||
    ParentMenu^.GetItemRect(ParentMenu^.Current, R);
 | 
						||
    MouseInOwner := R.Contains(Mouse);
 | 
						||
  end;
 | 
						||
end;
 | 
						||
 | 
						||
function MouseInMenus: Boolean;
 | 
						||
var
 | 
						||
  P: PMenuView;
 | 
						||
begin
 | 
						||
  P := ParentMenu;
 | 
						||
  while (P <> nil) and not P^.MouseInView(E.Where) do P := P^.ParentMenu;
 | 
						||
  MouseInMenus := P <> nil;
 | 
						||
end;
 | 
						||
 | 
						||
function TopMenu: PMenuView;
 | 
						||
var
 | 
						||
  P: PMenuView;
 | 
						||
begin
 | 
						||
  P := @Self;
 | 
						||
  while P^.ParentMenu <> nil do P := P^.ParentMenu;
 | 
						||
  TopMenu := P;
 | 
						||
end;
 | 
						||
 | 
						||
begin
 | 
						||
  AutoSelect := False; E.What:=evNothing;
 | 
						||
  Res := 0;
 | 
						||
  ItemShown := nil;
 | 
						||
  Current := Menu^.Default;
 | 
						||
  MouseActive := False;
 | 
						||
  if UpdateMenu(Menu) then
 | 
						||
 begin
 | 
						||
  if Current<>nil then
 | 
						||
    if Current^.Disabled then
 | 
						||
       TrackKey(true);
 | 
						||
  repeat
 | 
						||
    Action := DoNothing;
 | 
						||
    GetEvent(E);
 | 
						||
    case E.What of
 | 
						||
      evMouseDown:
 | 
						||
        if MouseInView(E.Where) or MouseInOwner then
 | 
						||
        begin
 | 
						||
          TrackMouse;
 | 
						||
          if Size.Y = 1 then AutoSelect := True;
 | 
						||
        end else Action := DoReturn;
 | 
						||
      evMouseUp:
 | 
						||
        begin
 | 
						||
          TrackMouse;
 | 
						||
          if MouseInOwner then
 | 
						||
            Current := Menu^.Default
 | 
						||
          else
 | 
						||
            if (Current <> nil) and (Current^.Name <> nil) then
 | 
						||
              Action := DoSelect
 | 
						||
            else
 | 
						||
              if MouseActive or MouseInView(E.Where) then Action := DoReturn
 | 
						||
              else
 | 
						||
              begin
 | 
						||
                Current := Menu^.Default;
 | 
						||
                if Current = nil then Current := Menu^.Items;
 | 
						||
                Action := DoNothing;
 | 
						||
              end;
 | 
						||
        end;
 | 
						||
      evMouseMove:
 | 
						||
        if E.Buttons <> 0 then
 | 
						||
        begin
 | 
						||
          TrackMouse;
 | 
						||
          if not (MouseInView(E.Where) or MouseInOwner) and
 | 
						||
            MouseInMenus then Action := DoReturn;
 | 
						||
        end;
 | 
						||
      evKeyDown:
 | 
						||
        case CtrlToArrow(E.KeyCode) of
 | 
						||
          kbUp, kbDown:
 | 
						||
            if Size.Y <> 1 then
 | 
						||
              TrackKey(CtrlToArrow(E.KeyCode) = kbDown) else
 | 
						||
              if E.KeyCode = kbDown then AutoSelect := True;
 | 
						||
          kbLeft, kbRight:
 | 
						||
            if ParentMenu = nil then
 | 
						||
              TrackKey(CtrlToArrow(E.KeyCode) = kbRight) else
 | 
						||
              Action := DoReturn;
 | 
						||
          kbHome, kbEnd:
 | 
						||
            if Size.Y <> 1 then
 | 
						||
            begin
 | 
						||
              Current := Menu^.Items;
 | 
						||
              if E.KeyCode = kbEnd then TrackKey(False);
 | 
						||
            end;
 | 
						||
          kbEnter:
 | 
						||
            begin
 | 
						||
              if Size.Y = 1 then AutoSelect := True;
 | 
						||
              Action := DoSelect;
 | 
						||
            end;
 | 
						||
          kbEsc:
 | 
						||
            begin
 | 
						||
              Action := DoReturn;
 | 
						||
              if (ParentMenu = nil) or (ParentMenu^.Size.Y <> 1) then
 | 
						||
                ClearEvent(E);
 | 
						||
            end;
 | 
						||
        else
 | 
						||
          Target := @Self;
 | 
						||
          Ch := GetAltChar(E.KeyCode);
 | 
						||
          if Ch = #0 then Ch := E.CharCode else Target := TopMenu;
 | 
						||
          P := Target^.FindItem(Ch);
 | 
						||
          if P = nil then
 | 
						||
          begin
 | 
						||
            P := TopMenu^.HotKey(E.KeyCode);
 | 
						||
            if (P <> nil) and CommandEnabled(P^.Command) then
 | 
						||
            begin
 | 
						||
              Res := P^.Command;
 | 
						||
              Action := DoReturn;
 | 
						||
            end
 | 
						||
          end else
 | 
						||
            if Target = @Self then
 | 
						||
            begin
 | 
						||
              if Size.Y = 1 then AutoSelect := True;
 | 
						||
              Action := DoSelect;
 | 
						||
              Current := P;
 | 
						||
            end else
 | 
						||
              if (ParentMenu <> Target) or (ParentMenu^.Current <> P) then
 | 
						||
                Action := DoReturn;
 | 
						||
        end;
 | 
						||
      evCommand:
 | 
						||
        if E.Command = cmMenu then
 | 
						||
        begin
 | 
						||
          AutoSelect := False;
 | 
						||
          if ParentMenu <> nil then Action := DoReturn;
 | 
						||
        end else Action := DoReturn;
 | 
						||
    end;
 | 
						||
    if ItemShown <> Current then
 | 
						||
    begin
 | 
						||
      ItemShown := Current;
 | 
						||
      DrawView;
 | 
						||
    end;
 | 
						||
    if (Action = DoSelect) or ((Action = DoNothing) and AutoSelect) then
 | 
						||
      if Current <> nil then with Current^ do if Name <> nil then
 | 
						||
        if Command = 0 then
 | 
						||
        begin
 | 
						||
          if E.What and (evMouseDown + evMouseMove) <> 0 then PutEvent(E);
 | 
						||
          GetItemRect(Current, R);
 | 
						||
          R.A.X := R.A.X + Origin.X;
 | 
						||
          R.A.Y := R.B.Y + Origin.Y;
 | 
						||
          R.B := Owner^.Size;
 | 
						||
          if Size.Y = 1 then Dec(R.A.X);
 | 
						||
          Target := TopMenu^.NewSubView(R, SubMenu, @Self);
 | 
						||
          Res := Owner^.ExecView(Target);
 | 
						||
          Dispose(Target, Done);
 | 
						||
        end else if Action = DoSelect then Res := Command;
 | 
						||
    if (Res <> 0) and CommandEnabled(Res) then
 | 
						||
    begin
 | 
						||
      Action := DoReturn;
 | 
						||
      ClearEvent(E);
 | 
						||
    end
 | 
						||
    else
 | 
						||
      Res := 0;
 | 
						||
  until Action = DoReturn;
 | 
						||
 end;
 | 
						||
  if E.What <> evNothing then
 | 
						||
    if (ParentMenu <> nil) or (E.What = evCommand) then PutEvent(E);
 | 
						||
  if Current <> nil then
 | 
						||
  begin
 | 
						||
    Menu^.Default := Current;
 | 
						||
    Current := nil;
 | 
						||
    DrawView;
 | 
						||
  end;
 | 
						||
  Execute := Res;
 | 
						||
end;
 | 
						||
 | 
						||
procedure TAdvancedStaticText.SetText(S: string);
 | 
						||
begin
 | 
						||
  if Text<>nil then DisposeStr(Text);
 | 
						||
  Text:=NewStr(S);
 | 
						||
  DrawView;
 | 
						||
end;
 | 
						||
 | 
						||
procedure TAdvancedListBox.FocusItem(Item: sw_integer);
 | 
						||
var OFocused: sw_integer;
 | 
						||
begin
 | 
						||
  OFocused:=Focused;
 | 
						||
  inherited FocusItem(Item);
 | 
						||
  if Focused<>OFocused then
 | 
						||
  Message(Owner,evBroadcast,cmListFocusChanged,@Self);
 | 
						||
end;
 | 
						||
 | 
						||
procedure TAdvancedListBox.HandleEvent(var Event: TEvent);
 | 
						||
begin
 | 
						||
  case Event.What of
 | 
						||
    evMouseDown :
 | 
						||
      if MouseInView(Event.Where) {and (Event.Double)} then
 | 
						||
      begin
 | 
						||
        inherited HandleEvent(Event);
 | 
						||
        if Event.Double then
 | 
						||
          if Range>Focused then
 | 
						||
            SelectItem(Focused);
 | 
						||
      end;
 | 
						||
    evBroadcast :
 | 
						||
      case Event.Command of
 | 
						||
        cmListItemSelected :
 | 
						||
          Message(Owner,evBroadcast,cmDefault,nil);
 | 
						||
      end;
 | 
						||
  end;
 | 
						||
  if assigned(VScrollBar) then
 | 
						||
    VScrollBar^.HandleEvent(Event);
 | 
						||
  if assigned(HScrollBar) then
 | 
						||
    HScrollBar^.HandleEvent(Event);
 | 
						||
  inherited HandleEvent(Event);
 | 
						||
end;
 | 
						||
 | 
						||
constructor TColorStaticText.Init(var Bounds: TRect; AText: String; AColor: word; AWrap: boolean);
 | 
						||
begin
 | 
						||
  inherited Init(Bounds,AText);
 | 
						||
  DontWrap:=not AWrap;
 | 
						||
  Color:=AColor;
 | 
						||
end;
 | 
						||
 | 
						||
function TColorStaticText.GetPalette: PPalette;
 | 
						||
begin
 | 
						||
  GetPalette:=nil;
 | 
						||
end;
 | 
						||
 | 
						||
procedure TColorStaticText.Draw;
 | 
						||
 | 
						||
  procedure MoveColorTxt(var b;const curs:string;c:word);
 | 
						||
  var
 | 
						||
    p : ^word;
 | 
						||
    i : sw_integer;
 | 
						||
    col : byte;
 | 
						||
    tilde : boolean;
 | 
						||
  begin
 | 
						||
    tilde:=false;
 | 
						||
    col:=lo(c);
 | 
						||
    p:=@b;
 | 
						||
    i:=0;
 | 
						||
    while (i<length(Curs)) do
 | 
						||
     begin
 | 
						||
       Inc(i);
 | 
						||
       case CurS[i] of
 | 
						||
         #1 :
 | 
						||
           begin
 | 
						||
             Inc(i);
 | 
						||
             Col:=ord(curS[i]);
 | 
						||
           end;
 | 
						||
         #2 :
 | 
						||
           begin
 | 
						||
             if tilde then
 | 
						||
              col:=hi(Color)
 | 
						||
             else
 | 
						||
              col:=lo(Color)
 | 
						||
           end;
 | 
						||
         '~' :
 | 
						||
           begin
 | 
						||
             tilde:=not tilde;
 | 
						||
             if tilde then
 | 
						||
              col:=hi(Color)
 | 
						||
             else
 | 
						||
              col:=lo(Color)
 | 
						||
           end;
 | 
						||
         else
 | 
						||
           begin
 | 
						||
             p^:=(col shl 8) or ord(curs[i]);
 | 
						||
             inc(p);
 | 
						||
           end;
 | 
						||
       end;
 | 
						||
     end;
 | 
						||
  end;
 | 
						||
 | 
						||
var
 | 
						||
  C: word;
 | 
						||
  Center: Boolean;
 | 
						||
  I, J, L, P, Y: Sw_Integer;
 | 
						||
  B: TDrawBuffer;
 | 
						||
  S: String;
 | 
						||
  T: string;
 | 
						||
  CurS: string;
 | 
						||
  TildeCount,Po: Sw_integer;
 | 
						||
  TempS: string;
 | 
						||
begin
 | 
						||
  if Size.X=0 then Exit;
 | 
						||
  C:=Color;
 | 
						||
  if (C and $0f)=((C and $f0) shr 4) then
 | 
						||
    C:=GetColor(C and $0f);
 | 
						||
  if DontWrap=false then
 | 
						||
 begin
 | 
						||
  GetText(S);
 | 
						||
  L := Length(S);
 | 
						||
  P := 1;
 | 
						||
  Y := 0;
 | 
						||
  Center := False;
 | 
						||
  while Y < Size.Y do
 | 
						||
  begin
 | 
						||
    MoveChar(B, ' ', Lo(C), Size.X);
 | 
						||
    if P <= L then
 | 
						||
    begin
 | 
						||
      if S[P] = #3 then
 | 
						||
      begin
 | 
						||
        Center := True;
 | 
						||
        Inc(P);
 | 
						||
      end;
 | 
						||
      I := P;
 | 
						||
      repeat
 | 
						||
        J := P;
 | 
						||
        while (P <= L) and (S[P] = ' ') do Inc(P);
 | 
						||
        while (P <= L) and (S[P] <> ' ') and (S[P] <> #13) do Inc(P);
 | 
						||
      until (P > L) or (P >= I + Size.X) or (S[P] = #13);
 | 
						||
      TildeCount:=0; TempS:=copy(S,I,P-I);
 | 
						||
      repeat
 | 
						||
        Po:=Pos('~',TempS);
 | 
						||
        if Po>0 then begin Inc(TildeCount); Delete(TempS,1,Po); end;
 | 
						||
      until Po=0;
 | 
						||
      if P > I + Size.X + TildeCount then
 | 
						||
        if J > I then P := J else P := I + Size.X;
 | 
						||
      T:=copy(S,I,P-I);
 | 
						||
      if Center then J := (Size.X - {P + I}CStrLen(T)) div 2 else J := 0;
 | 
						||
      MoveColorTxt(B[J],T,C);
 | 
						||
      while (P <= L) and (S[P] = ' ') do Inc(P);
 | 
						||
      if (P <= L) and (S[P] = #13) then
 | 
						||
      begin
 | 
						||
        Center := False;
 | 
						||
        Inc(P);
 | 
						||
        if (P <= L) and (S[P] = #10) then Inc(P);
 | 
						||
      end;
 | 
						||
    end;
 | 
						||
    WriteLine(0, Y, Size.X, 1, B);
 | 
						||
    Inc(Y);
 | 
						||
  end;
 | 
						||
 end { Wrap=false } else
 | 
						||
 begin
 | 
						||
  GetText(S);
 | 
						||
  I:=1;
 | 
						||
  for Y:=0 to Size.Y-1 do
 | 
						||
  begin
 | 
						||
    MoveChar(B, ' ', Lo(C), Size.X);
 | 
						||
    CurS:='';
 | 
						||
    if S<>'' then
 | 
						||
    begin
 | 
						||
    P:=Pos(#13,S);
 | 
						||
    if P=0 then P:=length(S)+1;
 | 
						||
    CurS:=copy(S,1,P-1);
 | 
						||
    CurS:=copy(CurS,Delta.X+1,High(CurS));
 | 
						||
    CurS:=copy(CurS,1,MaxViewWidth);
 | 
						||
    Delete(S,1,P);
 | 
						||
    end;
 | 
						||
    if CurS<>'' then
 | 
						||
      MoveColorTxt(B,CurS,C);
 | 
						||
    WriteLine(0,Y,Size.X,1,B);
 | 
						||
  end;
 | 
						||
 end;
 | 
						||
end;
 | 
						||
 | 
						||
constructor TColorStaticText.Load(var S: TStream);
 | 
						||
begin
 | 
						||
  inherited Load(S);
 | 
						||
 | 
						||
  S.Read(Color,SizeOf(Color));
 | 
						||
  S.Read(DontWrap,SizeOf(DontWrap));
 | 
						||
  S.Read(Delta,SizeOf(Delta));
 | 
						||
end;
 | 
						||
 | 
						||
procedure TColorStaticText.Store(var S: TStream);
 | 
						||
begin
 | 
						||
  inherited Store(S);
 | 
						||
 | 
						||
  S.Write(Color,SizeOf(Color));
 | 
						||
  S.Write(DontWrap,SizeOf(DontWrap));
 | 
						||
  S.Write(Delta,SizeOf(Delta));
 | 
						||
end;
 | 
						||
 | 
						||
constructor THSListBox.Init(var Bounds: TRect; ANumCols: Word; AHScrollBar, AVScrollBar: PScrollBar);
 | 
						||
begin
 | 
						||
  inherited Init(Bounds,ANumCols,AVScrollBar);
 | 
						||
  HScrollBar:=AHScrollBar;
 | 
						||
  if assigned(VScrollBar) then
 | 
						||
    VScrollBar^.SetStep(Bounds.B.Y-Bounds.A.Y-2,1);
 | 
						||
  if assigned(HScrollBar) then
 | 
						||
    HScrollBar^.SetStep(Bounds.B.X-Bounds.A.X-2,1);
 | 
						||
end;
 | 
						||
 | 
						||
function THSListBox.SaveToFile(const AFileName: string): boolean;
 | 
						||
var OK: boolean;
 | 
						||
    S: PBufStream;
 | 
						||
    i, count : sw_integer;
 | 
						||
    st : string;
 | 
						||
begin
 | 
						||
  New(S, Init(AFileName,stCreate,4096));
 | 
						||
  OK:=Assigned(S) and (S^.Status=stOK);
 | 
						||
  if OK then
 | 
						||
    begin
 | 
						||
      if assigned(List) then
 | 
						||
        Count:=List^.Count
 | 
						||
      else
 | 
						||
        Count:=0;
 | 
						||
      for i:=0 to Count-1 do
 | 
						||
        begin
 | 
						||
          st:=GetText(i,High(st));
 | 
						||
          S^.Write(St[1],length(St));
 | 
						||
          if i<Count then
 | 
						||
          S^.Write(EOL[1],length(EOL));
 | 
						||
          OK:=(S^.Status=stOK);
 | 
						||
          if not OK then
 | 
						||
            break;
 | 
						||
        end;
 | 
						||
    end;
 | 
						||
  if Assigned(S) then Dispose(S, Done);
 | 
						||
  SaveToFile:=OK;
 | 
						||
end;
 | 
						||
 | 
						||
function THSListBox.SaveAs: Boolean;
 | 
						||
var
 | 
						||
  DefExt,Title,Filename : string;
 | 
						||
  Re : word;
 | 
						||
begin
 | 
						||
  SaveAs := False;
 | 
						||
  Filename:='listbox.txt';
 | 
						||
  DefExt:='*.txt';
 | 
						||
  Title:='Save list box content';
 | 
						||
  Re:=Application^.ExecuteDialog(New(PFileDialog, Init(DefExt,
 | 
						||
          Title, label_name, fdOkButton, FileId)), @FileName);
 | 
						||
  if Re <> cmCancel then
 | 
						||
    SaveAs := SaveToFile(FileName);
 | 
						||
end;
 | 
						||
 | 
						||
 | 
						||
constructor TDlgWindow.Init(var Bounds: TRect; ATitle: TTitleStr; ANumber: Sw_Integer);
 | 
						||
begin
 | 
						||
  inherited Init(Bounds,ATitle);
 | 
						||
  Number:=ANumber;
 | 
						||
  Flags:=Flags or (wfMove + wfGrow + wfClose + wfZoom);
 | 
						||
end;
 | 
						||
 | 
						||
 | 
						||
procedure TDlgWindow.Update;
 | 
						||
begin
 | 
						||
  DrawView;
 | 
						||
end;
 | 
						||
 | 
						||
 | 
						||
procedure TDlgWindow.HandleEvent(var Event: TEvent);
 | 
						||
begin
 | 
						||
  case Event.What of
 | 
						||
    evBroadcast :
 | 
						||
      case Event.Command of
 | 
						||
        cmUpdate : Update;
 | 
						||
      end;
 | 
						||
  end;
 | 
						||
  inherited HandleEvent(Event);
 | 
						||
end;
 | 
						||
 | 
						||
procedure TLocalMenuListBox.LocalMenu(P: TPoint);
 | 
						||
var M: PMenu;
 | 
						||
    MV: PAdvancedMenuPopUp;
 | 
						||
    R: TRect;
 | 
						||
    Re: word;
 | 
						||
begin
 | 
						||
  M:=GetLocalMenu;
 | 
						||
  if M=nil then Exit;
 | 
						||
  if LastLocalCmd<>0 then
 | 
						||
     M^.Default:=SearchMenuItem(M,LastLocalCmd);
 | 
						||
  Desktop^.GetExtent(R);
 | 
						||
  MakeGlobal(P,R.A); {Desktop^.MakeLocal(R.A,R.A);}
 | 
						||
  New(MV, Init(R, M));
 | 
						||
  Re:=Application^.ExecView(MV);
 | 
						||
  if M^.Default=nil then LastLocalCmd:=0
 | 
						||
     else LastLocalCmd:=M^.Default^.Command;
 | 
						||
  Dispose(MV, Done);
 | 
						||
  if Re<>0 then
 | 
						||
    Message(GetCommandTarget,evCommand,Re,@Self);
 | 
						||
end;
 | 
						||
 | 
						||
function TLocalMenuListBox.GetLocalMenu: PMenu;
 | 
						||
begin
 | 
						||
  GetLocalMenu:=nil;
 | 
						||
{  Abstract;}
 | 
						||
end;
 | 
						||
 | 
						||
function TLocalMenuListBox.GetCommandTarget: PView;
 | 
						||
begin
 | 
						||
  GetCommandTarget:=@Self;
 | 
						||
end;
 | 
						||
 | 
						||
procedure TLocalMenuListBox.HandleEvent(var Event: TEvent);
 | 
						||
var DontClear: boolean;
 | 
						||
    P: TPoint;
 | 
						||
begin
 | 
						||
  case Event.What of
 | 
						||
    evMouseDown :
 | 
						||
      if MouseInView(Event.Where) and (Event.Buttons=mbRightButton) then
 | 
						||
        begin
 | 
						||
          MakeLocal(Event.Where,P); Inc(P.X); Inc(P.Y);
 | 
						||
          LocalMenu(P);
 | 
						||
          ClearEvent(Event);
 | 
						||
        end;
 | 
						||
    evKeyDown :
 | 
						||
      begin
 | 
						||
        DontClear:=false;
 | 
						||
        case Event.KeyCode of
 | 
						||
          kbAltF10 : Message(@Self,evCommand,cmLocalMenu,@Self);
 | 
						||
        else DontClear:=true;
 | 
						||
        end;
 | 
						||
        if DontClear=false then ClearEvent(Event);
 | 
						||
      end;
 | 
						||
    evCommand :
 | 
						||
      begin
 | 
						||
        DontClear:=false;
 | 
						||
        case Event.Command of
 | 
						||
          cmLocalMenu :
 | 
						||
            begin
 | 
						||
              P:=Cursor; Inc(P.X); Inc(P.Y);
 | 
						||
              LocalMenu(P);
 | 
						||
            end;
 | 
						||
        else DontClear:=true;
 | 
						||
        end;
 | 
						||
        if not DontClear then ClearEvent(Event);
 | 
						||
      end;
 | 
						||
  end;
 | 
						||
  inherited HandleEvent(Event);
 | 
						||
end;
 | 
						||
 | 
						||
function TAdvancedStatusLine.GetStatusText: string;
 | 
						||
var S: string;
 | 
						||
begin
 | 
						||
  if StatusText=nil then S:='' else S:=StatusText^;
 | 
						||
  GetStatusText:=S;
 | 
						||
end;
 | 
						||
 | 
						||
procedure TAdvancedStatusLine.SetStatusText(const S: string);
 | 
						||
begin
 | 
						||
  if StatusText<>nil then DisposeStr(StatusText);
 | 
						||
  StatusText:=NewStr(S);
 | 
						||
  DrawView;
 | 
						||
end;
 | 
						||
 | 
						||
procedure TAdvancedStatusLine.ClearStatusText;
 | 
						||
begin
 | 
						||
  SetStatusText('');
 | 
						||
end;
 | 
						||
 | 
						||
procedure TAdvancedStatusLine.Draw;
 | 
						||
var B: TDrawBuffer;
 | 
						||
    C: word;
 | 
						||
    S: string;
 | 
						||
begin
 | 
						||
  S:=GetStatusText;
 | 
						||
  if S='' then inherited Draw else
 | 
						||
  begin
 | 
						||
    C:=GetColor(1);
 | 
						||
    MoveChar(B,' ',C,Size.X);
 | 
						||
    MoveStr(B[1],S,C);
 | 
						||
    WriteLine(0,0,Size.X,Size.Y,B);
 | 
						||
  end;
 | 
						||
end;
 | 
						||
 | 
						||
procedure Bug(const S: string; Params: pointer);
 | 
						||
begin
 | 
						||
  ErrorBox(FormatStrStr(msg_bugcheckfailed,S),Params);
 | 
						||
end;
 | 
						||
 | 
						||
procedure ErrorBox(const S: string; Params: pointer);
 | 
						||
begin
 | 
						||
  AdvMessageBox(S,Params,mfError+mfInsertInApp+mfOKButton);
 | 
						||
end;
 | 
						||
 | 
						||
procedure WarningBox(const S: string; Params: pointer);
 | 
						||
begin
 | 
						||
  AdvMessageBox(S,Params,mfWarning+mfInsertInApp+mfOKButton);
 | 
						||
end;
 | 
						||
 | 
						||
procedure InformationBox(const S: string; Params: pointer);
 | 
						||
begin
 | 
						||
  AdvMessageBox(S,Params,mfInformation+mfInsertInApp+mfOKButton);
 | 
						||
end;
 | 
						||
 | 
						||
function OKCancelBox(const S: string; Params: pointer): word;
 | 
						||
begin
 | 
						||
  OKCancelBox:=AdvMessageBox(S,Params,mfInformation+mfInsertInApp+mfOKButton+mfCancelButton);
 | 
						||
end;
 | 
						||
 | 
						||
function b2i(B: boolean): longint;
 | 
						||
begin
 | 
						||
  if b then b2i:=1 else b2i:=0;
 | 
						||
end;
 | 
						||
 | 
						||
function ConfirmBox(const S: string; Params: pointer; CanCancel: boolean): word;
 | 
						||
begin
 | 
						||
  ConfirmBox:=AdvMessageBox(S,Params,mfConfirmation+mfInsertInApp+mfYesButton+mfNoButton+
 | 
						||
     b2i(CanCancel)*mfCancelButton+b2i(not CanCancel)*mfCantCancel);
 | 
						||
end;
 | 
						||
 | 
						||
function ChoiceBox(const S: string; Params: pointer; Buttons: array of string; CanCancel: boolean): word;
 | 
						||
var BtnMask,M: longint;
 | 
						||
    I,BtnCount: integer;
 | 
						||
begin
 | 
						||
  BtnCount:=Min(High(Buttons)-Low(Buttons)+1,High(UserButtonName)-Low(UserButtonName)+1);
 | 
						||
  BtnMask:=0; M:=mfUserBtn1;
 | 
						||
  for I:=Low(Buttons) to Low(Buttons)+BtnCount-1 do
 | 
						||
    begin
 | 
						||
      UserButtonName[Low(UserButtonName)+I-Low(Buttons)]:=Buttons[I];
 | 
						||
      BtnMask:=BtnMask or M; M:=M shl 1;
 | 
						||
    end;
 | 
						||
  ChoiceBox:=AdvMessageBox(S,Params,mfConfirmation+BtnMask+
 | 
						||
    b2i(CanCancel)*mfCancelButton+b2i(not CanCancel)*mfCantCancel);
 | 
						||
end;
 | 
						||
 | 
						||
function IsSeparator(P: PMenuItem): boolean;
 | 
						||
begin
 | 
						||
  IsSeparator:=(P<>nil) and (P^.Name=nil) and (P^.HelpCtx=hcNoContext);
 | 
						||
end;
 | 
						||
 | 
						||
function IsSubMenu(P: PMenuItem): boolean;
 | 
						||
begin
 | 
						||
  IsSubMenu:=(P<>nil) and (P^.Name<>nil) and (P^.Command=0) and (P^.SubMenu<>nil);
 | 
						||
end;
 | 
						||
 | 
						||
function SearchMenuItem(Menu: PMenu; Cmd: word): PMenuItem;
 | 
						||
var P,I: PMenuItem;
 | 
						||
begin
 | 
						||
  I:=nil;
 | 
						||
  if Menu=nil then P:=nil else P:=Menu^.Items;
 | 
						||
  while (P<>nil) and (I=nil) do
 | 
						||
  begin
 | 
						||
    if IsSubMenu(P) then
 | 
						||
       I:=SearchMenuItem(P^.SubMenu,Cmd);
 | 
						||
    if I=nil then
 | 
						||
    if P^.Command=Cmd then I:=P else
 | 
						||
    P:=P^.Next;
 | 
						||
  end;
 | 
						||
  SearchMenuItem:=I;
 | 
						||
end;
 | 
						||
 | 
						||
procedure SetMenuItemParam(Menu: PMenuItem; Param: string);
 | 
						||
begin
 | 
						||
  if Menu=nil then Exit;
 | 
						||
  if Menu^.Param<>nil then DisposeStr(Menu^.Param);
 | 
						||
  Menu^.Param:=NewStr(Param);
 | 
						||
end;
 | 
						||
 | 
						||
function UpdateMenu(M: PMenu): boolean;
 | 
						||
var P: PMenuItem;
 | 
						||
    IsEnabled: boolean;
 | 
						||
begin
 | 
						||
  if M=nil then begin UpdateMenu:=false; Exit; end;
 | 
						||
  P:=M^.Items; IsEnabled:=false;
 | 
						||
  while (P<>nil) do
 | 
						||
  begin
 | 
						||
    if IsSubMenu(P) then
 | 
						||
       begin
 | 
						||
         P^.Disabled:=not UpdateMenu(P^.SubMenu);
 | 
						||
         if not P^.Disabled then
 | 
						||
           IsEnabled:=true;
 | 
						||
       end
 | 
						||
    else
 | 
						||
      begin
 | 
						||
        if not IsSeparator(P) and
 | 
						||
           Application^.CommandEnabled(P^.Command) then
 | 
						||
          begin
 | 
						||
            p^.disabled:=false;
 | 
						||
            IsEnabled:=true;
 | 
						||
          end;
 | 
						||
       end;
 | 
						||
    P:=P^.Next;
 | 
						||
  end;
 | 
						||
  UpdateMenu:=IsEnabled;
 | 
						||
end;
 | 
						||
 | 
						||
function SearchSubMenu(M: PMenu; Index: Sw_integer): PMenuItem;
 | 
						||
var P,C: PMenuItem;
 | 
						||
    Count: Sw_integer;
 | 
						||
begin
 | 
						||
  P:=nil; Count:=-1;
 | 
						||
  if M<>nil then C:=M^.Items else C:=nil;
 | 
						||
  while (C<>nil) and (P=nil) do
 | 
						||
  begin
 | 
						||
    if IsSubMenu(C) then
 | 
						||
     begin
 | 
						||
       Inc(Count);
 | 
						||
       if Count=Index then P:=C;
 | 
						||
     end;
 | 
						||
    C:=C^.Next;
 | 
						||
  end;
 | 
						||
  SearchSubMenu:=P;
 | 
						||
end;
 | 
						||
 | 
						||
procedure AppendMenuItem(M: PMenu; I: PMenuItem);
 | 
						||
var P: PMenuItem;
 | 
						||
begin
 | 
						||
  if (M=nil) or (I=nil) then Exit;
 | 
						||
  I^.Next:=nil;
 | 
						||
  if M^.Items=nil then M^.Items:=I else
 | 
						||
  begin
 | 
						||
    P:=M^.Items;
 | 
						||
    while (P^.Next<>nil) do P:=P^.Next;
 | 
						||
    P^.Next:=I;
 | 
						||
  end;
 | 
						||
end;
 | 
						||
 | 
						||
procedure DisposeMenuItem(P: PMenuItem);
 | 
						||
begin
 | 
						||
  if P<>nil then
 | 
						||
  begin
 | 
						||
    if IsSubMenu(P) then DisposeMenu(P^.SubMenu) else
 | 
						||
      if IsSeparator(P)=false then
 | 
						||
       if P^.Param<>nil then DisposeStr(P^.Param);
 | 
						||
    if P^.Name<>nil then DisposeStr(P^.Name);
 | 
						||
    Dispose(P);
 | 
						||
  end;
 | 
						||
end;
 | 
						||
 | 
						||
procedure RemoveMenuItem(Menu: PMenu; I: PMenuItem);
 | 
						||
var P,PrevP: PMenuItem;
 | 
						||
begin
 | 
						||
  if (Menu=nil) or (I=nil) then Exit;
 | 
						||
  P:=Menu^.Items; PrevP:=nil;
 | 
						||
  while (P<>nil) do
 | 
						||
  begin
 | 
						||
    if P=I then
 | 
						||
      begin
 | 
						||
        if Menu^.Items<>I then PrevP^.Next:=P^.Next
 | 
						||
                          else Menu^.Items:=P^.Next;
 | 
						||
        DisposeMenuItem(P);
 | 
						||
        Break;
 | 
						||
      end;
 | 
						||
    PrevP:=P; P:=P^.Next;
 | 
						||
  end;
 | 
						||
end;
 | 
						||
 | 
						||
function GetMenuItemBefore(Menu: PMenu; BeforeOf: PMenuItem): PMenuItem;
 | 
						||
var P,C: PMenuItem;
 | 
						||
begin
 | 
						||
  P:=nil;
 | 
						||
  if Menu<>nil then C:=Menu^.Items else C:=nil;
 | 
						||
  while (C<>nil) do
 | 
						||
    begin
 | 
						||
      if C^.Next=BeforeOf then begin P:=C; Break; end;
 | 
						||
      C:=C^.Next;
 | 
						||
    end;
 | 
						||
  GetMenuItemBefore:=P;
 | 
						||
end;
 | 
						||
 | 
						||
procedure NotImplemented;
 | 
						||
begin
 | 
						||
  InformationBox(msg_functionnotimplemented,nil);
 | 
						||
end;
 | 
						||
 | 
						||
procedure InsertButtons(ADialog: PDialog);
 | 
						||
var R   : TRect;
 | 
						||
    W,H : Sw_integer;
 | 
						||
    X   : Sw_integer;
 | 
						||
    X1,X2: Sw_integer;
 | 
						||
begin
 | 
						||
  with ADialog^ do
 | 
						||
  begin
 | 
						||
    GetExtent(R);
 | 
						||
    W:=R.B.X-R.A.X; H:=(R.B.Y-R.A.Y);
 | 
						||
    R.Assign(0,0,W,H+3); ChangeBounds(R);
 | 
						||
    X:=W div 2; X1:=X div 2+1; X2:=X+X1-1;
 | 
						||
    R.Assign(X1-3,H,X1+7,H+2);
 | 
						||
    Insert(New(PButton, Init(R, btn_OK, cmOK, bfDefault)));
 | 
						||
    R.Assign(X2-7,H,X2+3,H+2);
 | 
						||
    Insert(New(PButton, Init(R, btn_Cancel, cmCancel, bfNormal)));
 | 
						||
    SelectNext(true);
 | 
						||
  end;
 | 
						||
end;
 | 
						||
 | 
						||
procedure InsertOK(ADialog: PDialog);
 | 
						||
var BW: Sw_integer;
 | 
						||
    R: TRect;
 | 
						||
begin
 | 
						||
  with ADialog^ do
 | 
						||
  begin
 | 
						||
    GetBounds(R); R.Grow(0,1); Inc(R.B.Y);
 | 
						||
    ChangeBounds(R);
 | 
						||
    BW:=10;
 | 
						||
    R.A.Y:=R.B.Y-2; R.B.Y:=R.A.Y+2;
 | 
						||
    R.A.X:=R.A.X+(R.B.X-R.A.X-BW) div 2; R.B.X:=R.A.X+BW;
 | 
						||
    Insert(New(PButton, Init(R, btn_OK, cmOK, bfDefault)));
 | 
						||
    SelectNext(true);
 | 
						||
  end;
 | 
						||
end;
 | 
						||
 | 
						||
procedure ShowMessage(Msg: string);
 | 
						||
var R: TRect;
 | 
						||
    Width: Sw_integer;
 | 
						||
begin
 | 
						||
  Width:=length(Msg)+4*2;
 | 
						||
  if Width<(Desktop^.Size.X div 2) then Width:=(Desktop^.Size.X div 2);
 | 
						||
  R.Assign(0,0,Width,5);
 | 
						||
  New(MessageDialog, Init(R, ''));
 | 
						||
  with MessageDialog^ do
 | 
						||
  begin
 | 
						||
    Flags:=0;
 | 
						||
    GetExtent(R); R.Grow(-4,-2);
 | 
						||
    if copy(Msg,1,1)<>^C then Msg:=^C+Msg;
 | 
						||
    Insert(New(PStaticText, Init(R, Msg)));
 | 
						||
  end;
 | 
						||
  Application^.Insert(MessageDialog);
 | 
						||
end;
 | 
						||
 | 
						||
procedure HideMessage;
 | 
						||
begin
 | 
						||
  if MessageDialog<>nil then
 | 
						||
    begin
 | 
						||
      Application^.Delete(MessageDialog);
 | 
						||
      Dispose(MessageDialog, Done);
 | 
						||
      MessageDialog:=nil;
 | 
						||
    end;
 | 
						||
end;
 | 
						||
 | 
						||
 | 
						||
constructor TDDHelperLB.Init(ALink: PDropDownListBox; var Bounds: TRect; ANumCols: Word; AScrollBar: PScrollBar);
 | 
						||
begin
 | 
						||
  inherited Init(Bounds,ANumCols,AScrollBar);
 | 
						||
  EventMask:=EventMask or (evMouseMove+evIdle);
 | 
						||
{  Options:=Options or ofPreProcess;}
 | 
						||
  Link:=ALink;
 | 
						||
end;
 | 
						||
 | 
						||
procedure TDDHelperLB.SetState(AState: Word; Enable: Boolean);
 | 
						||
{var OState: longint;}
 | 
						||
begin
 | 
						||
{  OState:=State;}
 | 
						||
  inherited SetState(AState,Enable);
 | 
						||
{  if (((State xor OState) and sfFocused)<>0) and (GetState(sfFocused)=false) then
 | 
						||
    Link^.DropList(false);}
 | 
						||
end;
 | 
						||
 | 
						||
function TDDHelperLB.GetText(Item,MaxLen: Sw_Integer): String;
 | 
						||
var P: pointer;
 | 
						||
    S: string;
 | 
						||
begin
 | 
						||
  P:=List^.At(Item);
 | 
						||
  if Link=nil then S:='' else
 | 
						||
    S:=Link^.GetText(P,MaxLen);
 | 
						||
  GetText:=S;
 | 
						||
end;
 | 
						||
 | 
						||
function TDDHelperLB.GetLocalMenu: PMenu;
 | 
						||
begin
 | 
						||
  GetLocalMenu:=Link^.LBGetLocalMenu;
 | 
						||
end;
 | 
						||
 | 
						||
function TDDHelperLB.GetCommandTarget: PView;
 | 
						||
begin
 | 
						||
  GetCommandTarget:=Link^.LBGetCommandTarget;
 | 
						||
end;
 | 
						||
 | 
						||
procedure TDDHelperLB.HandleEvent(var Event: TEvent);
 | 
						||
const
 | 
						||
  MouseAutosToSkip = 4;
 | 
						||
var
 | 
						||
  Mouse : TPoint;
 | 
						||
  OldItem, NewItem : Sw_Integer;
 | 
						||
  ColWidth : sw_integer;
 | 
						||
  Count : Sw_Word;
 | 
						||
  GoSelectItem: sw_integer;
 | 
						||
  MouseWhere: TPoint;
 | 
						||
begin
 | 
						||
  GoSelectItem:=-1;
 | 
						||
  TView.HandleEvent(Event);
 | 
						||
  case Event.What of
 | 
						||
    evMouseDown :
 | 
						||
      if MouseInView(Event.Where)=false then
 | 
						||
        GoSelectItem:=-2
 | 
						||
      else
 | 
						||
      begin
 | 
						||
        ColWidth := Size.X div NumCols + 1;
 | 
						||
        OldItem := Focused;
 | 
						||
        MakeLocal(Event.Where, Mouse);
 | 
						||
        if MouseInView(Event.Where) then
 | 
						||
          NewItem := Mouse.Y + (Size.Y * (Mouse.X div ColWidth)) + TopItem
 | 
						||
        else
 | 
						||
          NewItem := OldItem;
 | 
						||
        Count := 0;
 | 
						||
        repeat
 | 
						||
          if NewItem <> OldItem then
 | 
						||
           begin
 | 
						||
             FocusItemNum(NewItem);
 | 
						||
             DrawView;
 | 
						||
           end;
 | 
						||
          OldItem := NewItem;
 | 
						||
          MakeLocal(Event.Where, Mouse);
 | 
						||
          if MouseInView(Event.Where) then
 | 
						||
            NewItem := Mouse.Y + (Size.Y * (Mouse.X div ColWidth)) + TopItem
 | 
						||
          else
 | 
						||
          begin
 | 
						||
            if NumCols = 1 then
 | 
						||
            begin
 | 
						||
              if Event.What = evMouseAuto then Inc(Count);
 | 
						||
              if Count = MouseAutosToSkip then
 | 
						||
              begin
 | 
						||
                Count := 0;
 | 
						||
                if Mouse.Y < 0 then NewItem := Focused-1
 | 
						||
                else if Mouse.Y >= Size.Y then NewItem := Focused+1;
 | 
						||
              end;
 | 
						||
            end
 | 
						||
            else
 | 
						||
            begin
 | 
						||
              if Event.What = evMouseAuto then Inc(Count);
 | 
						||
              if Count = MouseAutosToSkip then
 | 
						||
              begin
 | 
						||
                Count := 0;
 | 
						||
                if Mouse.X < 0 then NewItem := Focused-Size.Y
 | 
						||
                else if Mouse.X >= Size.X then NewItem := Focused+Size.Y
 | 
						||
                else if Mouse.Y < 0 then
 | 
						||
                  NewItem := Focused - Focused mod Size.Y
 | 
						||
                else if Mouse.Y > Size.Y then
 | 
						||
                  NewItem := Focused - Focused mod Size.Y + Size.Y - 1;
 | 
						||
              end
 | 
						||
            end;
 | 
						||
          end;
 | 
						||
        until not MouseEvent(Event, evMouseMove + evMouseAuto);
 | 
						||
        FocusItemNum(NewItem);
 | 
						||
        DrawView;
 | 
						||
        if Event.Double and (Range > Focused) then SelectItem(Focused);
 | 
						||
        ClearEvent(Event);
 | 
						||
        GoSelectItem:=Focused;
 | 
						||
      end;
 | 
						||
    evMouseMove,evMouseAuto:
 | 
						||
     if GetState(sfFocused) then
 | 
						||
      if MouseInView(Event.Where) then
 | 
						||
        begin
 | 
						||
          MakeLocal(Event.Where,Mouse);
 | 
						||
          FocusItemNum(TopItem+Mouse.Y);
 | 
						||
          ClearEvent(Event);
 | 
						||
        end;
 | 
						||
    evKeyDown :
 | 
						||
      begin
 | 
						||
        if (Event.KeyCode=kbEsc) then
 | 
						||
          begin
 | 
						||
            GoSelectItem:=-2;
 | 
						||
            ClearEvent(Event);
 | 
						||
          end else
 | 
						||
        if ((Event.KeyCode=kbEnter) or (Event.CharCode = ' ')) and
 | 
						||
           (Focused < Range) then
 | 
						||
          begin
 | 
						||
            GoSelectItem:=Focused;
 | 
						||
            NewItem := Focused;
 | 
						||
          end
 | 
						||
        else
 | 
						||
          case CtrlToArrow(Event.KeyCode) of
 | 
						||
            kbUp   : NewItem := Focused - 1;
 | 
						||
            kbDown : NewItem := Focused + 1;
 | 
						||
            kbRight: if NumCols > 1 then NewItem := Focused + Size.Y else Exit;
 | 
						||
            kbLeft : if NumCols > 1 then NewItem := Focused - Size.Y else Exit;
 | 
						||
            kbPgDn : NewItem := Focused + Size.Y * NumCols;
 | 
						||
            kbPgUp : NewItem := Focused - Size.Y * NumCols;
 | 
						||
            kbHome : NewItem := TopItem;
 | 
						||
            kbEnd  : NewItem := TopItem + (Size.Y * NumCols) - 1;
 | 
						||
            kbCtrlPgDn: NewItem := Range - 1;
 | 
						||
            kbCtrlPgUp: NewItem := 0;
 | 
						||
        else
 | 
						||
          Exit;
 | 
						||
        end;
 | 
						||
        FocusItemNum(NewItem);
 | 
						||
        DrawView;
 | 
						||
        ClearEvent(Event);
 | 
						||
      end;
 | 
						||
    evBroadcast :
 | 
						||
      case Event.Command of
 | 
						||
        cmReceivedFocus :
 | 
						||
          if (Event.InfoPtr<>@Self) and (InClose=false) then
 | 
						||
            begin
 | 
						||
              GoSelectItem:=-2;
 | 
						||
            end;
 | 
						||
      else
 | 
						||
        if Options and ofSelectable <> 0 then
 | 
						||
          if (Event.Command = cmScrollBarClicked) and
 | 
						||
             ((Event.InfoPtr = HScrollBar) or (Event.InfoPtr = VScrollBar)) then
 | 
						||
            Select
 | 
						||
          else
 | 
						||
            if (Event.Command = cmScrollBarChanged) then
 | 
						||
              begin
 | 
						||
                if (VScrollBar = Event.InfoPtr) then
 | 
						||
                  begin
 | 
						||
                    FocusItemNum(VScrollBar^.Value);
 | 
						||
                    DrawView;
 | 
						||
                  end
 | 
						||
                else
 | 
						||
                  if (HScrollBar = Event.InfoPtr) then
 | 
						||
                    DrawView;
 | 
						||
              end;
 | 
						||
      end;
 | 
						||
    evIdle :
 | 
						||
      begin
 | 
						||
        MouseWhere.X:=MouseWhereX shr 3; MouseWhere.Y:=MouseWhereY shr 3;
 | 
						||
        if MouseInView(MouseWhere)=false then
 | 
						||
         if abs(GetDosTicks-LastTT)>=1 then
 | 
						||
          begin
 | 
						||
            LastTT:=GetDosTicks;
 | 
						||
            MakeLocal(MouseWhere,Mouse);
 | 
						||
            if ((Mouse.Y<-1) or (Mouse.Y>=Size.Y)) and
 | 
						||
               ((0<=Mouse.X) and (Mouse.X<Size.X)) then
 | 
						||
            if Range>0 then
 | 
						||
              if Mouse.Y<0 then
 | 
						||
                FocusItemNum(Focused-(0-Mouse.Y))
 | 
						||
              else
 | 
						||
                FocusItemNum(Focused+(Mouse.Y-(Size.Y-1)));
 | 
						||
          end;
 | 
						||
      end;
 | 
						||
  end;
 | 
						||
  if (Range>0) and (GoSelectItem<>-1) then
 | 
						||
   begin
 | 
						||
     InClose:=true;
 | 
						||
     if GoSelectItem=-2 then
 | 
						||
       Link^.DropList(false)
 | 
						||
     else
 | 
						||
       SelectItem(GoSelectItem);
 | 
						||
   end;
 | 
						||
end;
 | 
						||
 | 
						||
procedure TDDHelperLB.SelectItem(Item: Sw_Integer);
 | 
						||
begin
 | 
						||
  inherited SelectItem(Item);
 | 
						||
  Link^.FocusItem(Focused);
 | 
						||
  Link^.DropList(false);
 | 
						||
end;
 | 
						||
 | 
						||
constructor TDropDownListBox.Init(var Bounds: TRect; ADropLineCount: Sw_integer; AList: PCollection);
 | 
						||
begin
 | 
						||
  inherited Init(Bounds);
 | 
						||
  Options:=Options or (ofSelectable);
 | 
						||
  EventMask:=EventMask or (evBroadcast);
 | 
						||
  DropLineCount:=ADropLineCount;
 | 
						||
  NewList(AList);
 | 
						||
end;
 | 
						||
 | 
						||
procedure TDropDownListBox.HandleEvent(var Event: TEvent);
 | 
						||
var DontClear: boolean;
 | 
						||
    Count: sw_integer;
 | 
						||
begin
 | 
						||
  case Event.What of
 | 
						||
    evKeyDown :
 | 
						||
      if GetState(sfFocused) then
 | 
						||
       begin
 | 
						||
         DontClear:=false;
 | 
						||
         Count:=GetItemCount;
 | 
						||
         if Count>0 then
 | 
						||
         case Event.KeyCode of
 | 
						||
           kbUp :
 | 
						||
             if Focused>0 then
 | 
						||
               FocusItem(Focused-1);
 | 
						||
           kbDown :
 | 
						||
             if Focused<Count-1 then
 | 
						||
               FocusItem(Focused+1);
 | 
						||
           kbHome :
 | 
						||
             FocusItem(0);
 | 
						||
           kbEnd  :
 | 
						||
             FocusItem(Count-1);
 | 
						||
           kbEnter,
 | 
						||
           kbPgDn :
 | 
						||
             DropList(true);
 | 
						||
         else DontClear:=true;
 | 
						||
         end;
 | 
						||
         if DontClear=false then ClearEvent(Event);
 | 
						||
       end;
 | 
						||
    evBroadcast :
 | 
						||
      case Event.Command of
 | 
						||
        cmReleasedFocus :
 | 
						||
          if (ListBox<>nil) and (Event.InfoPtr=ListBox) then
 | 
						||
            DropList(false);
 | 
						||
        cmListItemSelected :
 | 
						||
          if (ListBox<>nil) and (Event.InfoPtr=ListBox) then
 | 
						||
            begin
 | 
						||
              FocusItem(ListBox^.Focused);
 | 
						||
              Text:=GetText(List^.At(Focused),High(Text));
 | 
						||
              DrawView;
 | 
						||
              DropList(false);
 | 
						||
            end;
 | 
						||
      end;
 | 
						||
    evMouseDown :
 | 
						||
      if MouseInView(Event.Where) then
 | 
						||
        begin
 | 
						||
          DropList(not ListDropped);
 | 
						||
          ClearEvent(Event);
 | 
						||
        end;
 | 
						||
  end;
 | 
						||
  inherited HandleEvent(Event);
 | 
						||
end;
 | 
						||
 | 
						||
function TDropDownListBox.GetText(Item: pointer; MaxLen: Sw_integer): string;
 | 
						||
var S: string;
 | 
						||
begin
 | 
						||
  S:=GetStr(Item);
 | 
						||
  GetText:=copy(S,1,MaxLen);
 | 
						||
end;
 | 
						||
 | 
						||
procedure TDropDownListBox.NewList(AList: PCollection);
 | 
						||
begin
 | 
						||
  if List<>nil then Dispose(List, Done); List:=nil;
 | 
						||
  List:=AList; FocusItem(0);
 | 
						||
end;
 | 
						||
 | 
						||
procedure TDropDownListBox.CreateListBox(var R: TRect);
 | 
						||
var R2: TRect;
 | 
						||
begin
 | 
						||
  R2.Copy(R); R2.A.X:=R2.B.X-1;
 | 
						||
  New(SB, Init(R2));
 | 
						||
  Dec(R.B.X);
 | 
						||
  New(ListBox, Init(@Self,R,1,SB));
 | 
						||
end;
 | 
						||
 | 
						||
procedure TDropDownListBox.DropList(Drop: boolean);
 | 
						||
var R: TRect;
 | 
						||
    LB: PListBox;
 | 
						||
begin
 | 
						||
  if (ListDropped=Drop) then Exit;
 | 
						||
 | 
						||
  if Drop then
 | 
						||
    begin
 | 
						||
      R.Assign(Origin.X+1,Origin.Y+Size.Y,Origin.X+Size.X,Origin.Y+Size.Y+DropLineCount);
 | 
						||
      if Owner<>nil then Owner^.Lock;
 | 
						||
      CreateListBox(R);
 | 
						||
      if SB<>nil then
 | 
						||
        Owner^.Insert(SB);
 | 
						||
      if ListBox<>nil then
 | 
						||
        begin
 | 
						||
          ListBox^.NewList(List);
 | 
						||
          ListBox^.FocusItem(Focused);
 | 
						||
          Owner^.Insert(ListBox);
 | 
						||
        end;
 | 
						||
      if Owner<>nil then Owner^.UnLock;
 | 
						||
    end
 | 
						||
  else
 | 
						||
    begin
 | 
						||
      if Owner<>nil then Owner^.Lock;
 | 
						||
      if ListBox<>nil then
 | 
						||
        begin
 | 
						||
{          ListBox^.List:=nil;}
 | 
						||
          LB:=ListBox; ListBox:=nil; { this prevents GPFs while deleting }
 | 
						||
          Dispose(LB, Done);
 | 
						||
        end;
 | 
						||
      if SB<>nil then
 | 
						||
        begin
 | 
						||
          Dispose(SB, Done);
 | 
						||
          SB:=nil;
 | 
						||
        end;
 | 
						||
      Select;
 | 
						||
      if Owner<>nil then Owner^.UnLock;
 | 
						||
    end;
 | 
						||
 | 
						||
  ListDropped:=Drop;
 | 
						||
  DrawView;
 | 
						||
end;
 | 
						||
 | 
						||
function TDropDownListBox.GetItemCount: sw_integer;
 | 
						||
var Count: sw_integer;
 | 
						||
begin
 | 
						||
  if assigned(List)=false then Count:=0 else
 | 
						||
    Count:=List^.Count;
 | 
						||
  GetItemCount:=Count;
 | 
						||
end;
 | 
						||
 | 
						||
procedure TDropDownListBox.FocusItem(Item: sw_integer);
 | 
						||
var P: pointer;
 | 
						||
begin
 | 
						||
  Focused:=Item;
 | 
						||
  if assigned(ListBox) and (Item>=0) then
 | 
						||
    ListBox^.FocusItem(Item);
 | 
						||
  if (GetItemCount>0) and (Focused>=0) then
 | 
						||
    begin
 | 
						||
      P:=List^.At(Focused);
 | 
						||
      Text:=GetText(P,Size.X-4);
 | 
						||
    end;
 | 
						||
  DrawView;
 | 
						||
end;
 | 
						||
 | 
						||
function TDropDownListBox.LBGetLocalMenu: PMenu;
 | 
						||
begin
 | 
						||
  LBGetLocalMenu:=nil;
 | 
						||
end;
 | 
						||
 | 
						||
function TDropDownListBox.LBGetCommandTarget: PView;
 | 
						||
begin
 | 
						||
  LBGetCommandTarget:=@Self;
 | 
						||
end;
 | 
						||
 | 
						||
procedure TDropDownListBox.SetState(AState: Word; Enable: Boolean);
 | 
						||
begin
 | 
						||
  inherited SetState(AState,Enable);
 | 
						||
  if (AState and (sfSelected + sfActive + sfFocused)) <> 0 then DrawView;
 | 
						||
end;
 | 
						||
 | 
						||
procedure TDropDownListBox.Draw;
 | 
						||
var B: TDrawBuffer;
 | 
						||
    C,TextC: word;
 | 
						||
    LC: char;
 | 
						||
begin
 | 
						||
  if GetState(sfFocused)=false then
 | 
						||
    begin
 | 
						||
      C:=GetColor(2);
 | 
						||
      TextC:=GetColor(2);
 | 
						||
    end
 | 
						||
  else
 | 
						||
    begin
 | 
						||
      C:=GetColor(3);
 | 
						||
      TextC:=GetColor(3);
 | 
						||
    end;
 | 
						||
  MoveChar(B,' ',C,Size.X);
 | 
						||
  MoveStr(B[1],copy(Text,1,Size.X-2),TextC);
 | 
						||
  if ListDropped then LC:='^' else LC:='v';
 | 
						||
  MoveChar(B[Size.X-2],LC,C,1);
 | 
						||
  WriteLine(0,0,Size.X,Size.Y,B);
 | 
						||
end;
 | 
						||
 | 
						||
function TDropDownListBox.GetPalette: PPalette;
 | 
						||
const P: string[length(CListViewer)] = CListViewer;
 | 
						||
begin
 | 
						||
  GetPalette:=@P;
 | 
						||
end;
 | 
						||
 | 
						||
destructor TDropDownListBox.Done;
 | 
						||
begin
 | 
						||
  if ListDropped then DropList(false);
 | 
						||
  inherited Done;
 | 
						||
end;
 | 
						||
 | 
						||
constructor TGroupView.Init(var Bounds: TRect; AText: String; ALink: PView);
 | 
						||
begin
 | 
						||
  inherited Init(Bounds,AText,ALink);
 | 
						||
end;
 | 
						||
 | 
						||
procedure TGroupView.Draw;
 | 
						||
var B: TDrawBuffer;
 | 
						||
    FrameC,LabelC: word;
 | 
						||
begin
 | 
						||
  FrameC:=GetColor(1);
 | 
						||
  if Light then
 | 
						||
    LabelC:=GetColor(2)+GetColor(4) shl 8
 | 
						||
  else
 | 
						||
    LabelC:=GetColor(1)+GetColor(3) shl 8;
 | 
						||
  { First Line }
 | 
						||
  MoveChar(B[0],'<27>',FrameC,1);
 | 
						||
  MoveChar(B[1],'<27>',FrameC,Size.X-2);
 | 
						||
  MoveChar(B[Size.X-1],'<27>',FrameC,1);
 | 
						||
  if Text<>nil then
 | 
						||
    begin
 | 
						||
      MoveCStr(B[1],' '+Text^+' ',LabelC);
 | 
						||
    end;
 | 
						||
  WriteLine(0,0,Size.X,1,B);
 | 
						||
  { Mid Lines }
 | 
						||
  MoveChar(B[0],'<27>',FrameC,1);
 | 
						||
  MoveChar(B[1],' ',FrameC,Size.X-2);
 | 
						||
  MoveChar(B[Size.X-1],'<27>',FrameC,1);
 | 
						||
  WriteLine(0,1,Size.X,Size.Y-2,B);
 | 
						||
  { Last Line }
 | 
						||
  MoveChar(B[0],'<27>',FrameC,1);
 | 
						||
  MoveChar(B[1],'<27>',FrameC,Size.X-2);
 | 
						||
  MoveChar(B[Size.X-1],'<27>',FrameC,1);
 | 
						||
  WriteLine(0,Size.Y-1,Size.X,1,B);
 | 
						||
end;
 | 
						||
 | 
						||
function TPlainCheckBoxes.GetPalette: PPalette;
 | 
						||
const P: string[length(CPlainCluster)] = CPlainCluster;
 | 
						||
begin
 | 
						||
  GetPalette:=@P;
 | 
						||
end;
 | 
						||
 | 
						||
function TPlainRadioButtons.GetPalette: PPalette;
 | 
						||
const P: string[length(CPlainCluster)] = CPlainCluster;
 | 
						||
begin
 | 
						||
  GetPalette:=@P;
 | 
						||
end;
 | 
						||
 | 
						||
constructor TAdvancedListBox.Load(var S: TStream);
 | 
						||
begin
 | 
						||
  inherited Load(S);
 | 
						||
 | 
						||
  S.Read(Default,SizeOf(Default));
 | 
						||
end;
 | 
						||
 | 
						||
procedure TAdvancedListBox.Store(var S: TStream);
 | 
						||
begin
 | 
						||
  inherited Store(S);
 | 
						||
 | 
						||
  S.Write(Default,SizeOf(Default));
 | 
						||
end;
 | 
						||
 | 
						||
procedure TNoUpdateButton.HandleEvent(var Event: TEvent);
 | 
						||
begin
 | 
						||
  if (Event.What<>evBroadcast) or (Event.Command<>cmCommandSetChanged) then
 | 
						||
  inherited HandleEvent(Event);
 | 
						||
end;
 | 
						||
 | 
						||
constructor TPanel.Init(var Bounds: TRect);
 | 
						||
begin
 | 
						||
  inherited Init(Bounds);
 | 
						||
  Options:=Options or (ofSelectable+ofTopSelect);
 | 
						||
  GrowMode:=gfGrowHiX+gfGrowHiY;
 | 
						||
end;
 | 
						||
 | 
						||
procedure TAdvMessageBox.HandleEvent(var Event: TEvent);
 | 
						||
var I: integer;
 | 
						||
begin
 | 
						||
  if (not CanCancel) and (Event.What=evCommand) and (Event.Command=cmCancel) then
 | 
						||
    ClearEvent(Event);
 | 
						||
  inherited HandleEvent(Event);
 | 
						||
  case Event.What of
 | 
						||
    evCommand:
 | 
						||
      begin
 | 
						||
        for I:=Low(UserButtonCmd) to High(UserButtonCmd) do
 | 
						||
         if Event.Command=UserButtonCmd[I] then
 | 
						||
          if State and sfModal <> 0 then
 | 
						||
          begin
 | 
						||
            EndModal(Event.Command);
 | 
						||
            ClearEvent(Event);
 | 
						||
          end;
 | 
						||
      end;
 | 
						||
  end;
 | 
						||
end;
 | 
						||
 | 
						||
procedure ClearFormatParams;
 | 
						||
begin
 | 
						||
  FormatParamCount:=0; FillChar(FormatParams,sizeof(FormatParams),0);
 | 
						||
  FormatParamStrCount:=0;
 | 
						||
end;
 | 
						||
 | 
						||
procedure AddFormatParam(P: pointer);
 | 
						||
begin
 | 
						||
  AddFormatParamInt(ptrint(P));
 | 
						||
end;
 | 
						||
 | 
						||
procedure AddFormatParamInt(L: longint);
 | 
						||
begin
 | 
						||
  Inc(FormatParamCount);
 | 
						||
  FormatParams[FormatParamCount]:=L;
 | 
						||
end;
 | 
						||
 | 
						||
procedure AddFormatParamChar(C: char);
 | 
						||
begin
 | 
						||
  AddFormatParamInt(ord(C));
 | 
						||
end;
 | 
						||
 | 
						||
procedure AddFormatParamStr(const S: string);
 | 
						||
begin
 | 
						||
  Inc(FormatParamStrCount);
 | 
						||
  FormatParamStrs[FormatParamStrCount]:=S;
 | 
						||
  AddFormatParam(@FormatParamStrs[FormatParamStrCount]);
 | 
						||
end;
 | 
						||
 | 
						||
function FormatStrF(const Format: string; var Params): string;
 | 
						||
var S: string;
 | 
						||
begin
 | 
						||
  S:='';
 | 
						||
  FormatStr(S,Format,Params);
 | 
						||
  FormatStrF:=S;
 | 
						||
end;
 | 
						||
 | 
						||
function FormatStrStr(const Format, Param: string): string;
 | 
						||
var S: string;
 | 
						||
    P: pointer;
 | 
						||
begin
 | 
						||
  P:=@Param;
 | 
						||
  FormatStr(S,Format,P);
 | 
						||
  FormatStrStr:=S;
 | 
						||
end;
 | 
						||
 | 
						||
function FormatStrStr2(const Format, Param1,Param2: string): string;
 | 
						||
var S: string;
 | 
						||
    P: array[1..2] of pointer;
 | 
						||
begin
 | 
						||
  P[1]:=@Param1; P[2]:=@Param2;
 | 
						||
  FormatStr(S,Format,P);
 | 
						||
  FormatStrStr2:=S;
 | 
						||
end;
 | 
						||
 | 
						||
function FormatStrStr3(const Format, Param1,Param2,Param3: string): string;
 | 
						||
var S: string;
 | 
						||
    P: array[1..3] of pointer;
 | 
						||
begin
 | 
						||
  P[1]:=@Param1;
 | 
						||
  P[2]:=@Param2;
 | 
						||
  P[3]:=@Param3;
 | 
						||
  FormatStr(S,Format,P);
 | 
						||
  FormatStrStr3:=S;
 | 
						||
end;
 | 
						||
 | 
						||
function FormatStrInt(const Format: string; L: PtrInt): string;
 | 
						||
var S: string;
 | 
						||
begin
 | 
						||
  FormatStr(S,Format,L);
 | 
						||
  FormatStrInt:=S;
 | 
						||
end;
 | 
						||
 | 
						||
const
 | 
						||
  Cmds: array[0..3] of word =
 | 
						||
    (cmYes, cmNo, cmOK, cmCancel);
 | 
						||
var
 | 
						||
 | 
						||
  ButtonName: array[0..3] of string;
 | 
						||
  Titles: array[0..3] of string;
 | 
						||
 | 
						||
function AdvMessageBox(const Msg: String; Params: Pointer; AOptions: longint): Word;
 | 
						||
var
 | 
						||
  R: TRect;
 | 
						||
begin
 | 
						||
  R.Assign(0, 0, 0, 0);
 | 
						||
  AdvMessageBox := AdvMessageBoxRect(R, Msg, Params, AOptions);
 | 
						||
end;
 | 
						||
 | 
						||
procedure GetStaticTextDimensions(const S: string; ViewWidth: integer; var MaxCols, Rows: integer);
 | 
						||
var
 | 
						||
  Center: Boolean;
 | 
						||
  I, J, L, P, Y: Sw_Integer;
 | 
						||
  CurLine: string;
 | 
						||
begin
 | 
						||
  MaxCols:=0;
 | 
						||
  L := Length(S);
 | 
						||
  P := 1;
 | 
						||
  Y := 0;
 | 
						||
  Center := False;
 | 
						||
  while (Y < 32767) and (P<=length(S)) do
 | 
						||
  begin
 | 
						||
    CurLine:='';
 | 
						||
    if P <= L then
 | 
						||
    begin
 | 
						||
      if S[P] = #3 then
 | 
						||
      begin
 | 
						||
        Center := True;
 | 
						||
        Inc(P);
 | 
						||
      end;
 | 
						||
      I := P;
 | 
						||
      repeat
 | 
						||
        J := P;
 | 
						||
        while (P <= L) and (S[P] = ' ') do Inc(P);
 | 
						||
        while (P <= L) and (S[P] <> ' ') and (S[P] <> #13) do Inc(P);
 | 
						||
      until (P > L) or (P >= I + ViewWidth) or (S[P] = #13);
 | 
						||
      if P > I + ViewWidth then
 | 
						||
        if J > I then P := J else P := I + ViewWidth;
 | 
						||
      if Center then J := (ViewWidth - P + I) div 2 else J := 0;
 | 
						||
      CurLine:=CurLine+copy(S,I,P-I);
 | 
						||
{      MoveBuf(B[J], S[I], Color, P - I);}
 | 
						||
      while (P <= L) and (S[P] = ' ') do Inc(P);
 | 
						||
      if (P <= L) and (S[P] = #13) then
 | 
						||
      begin
 | 
						||
        Center := False;
 | 
						||
        Inc(P);
 | 
						||
        if (P <= L) and (S[P] = #10) then Inc(P);
 | 
						||
      end;
 | 
						||
    end;
 | 
						||
    if length(CurLine)>MaxCols then
 | 
						||
      MaxCols:=length(CurLine);
 | 
						||
{    WriteLine(0, Y, Size.X, 1, B);}
 | 
						||
    Inc(Y);
 | 
						||
  end;
 | 
						||
  Rows:=Y;
 | 
						||
end;
 | 
						||
 | 
						||
function AdvMessageBoxRect(var R: TRect; const Msg: String; Params: Pointer; AOptions: longint): Word;
 | 
						||
var
 | 
						||
  I, X, ButtonCount: Sw_Integer;
 | 
						||
  Dialog: PAdvMessageBox;
 | 
						||
  Control: PView;
 | 
						||
  ButtonList: array[0..4] of PView;
 | 
						||
  S,BtnName: String;
 | 
						||
  Cols,Rows: integer;
 | 
						||
begin
 | 
						||
  FormatStr(S, Msg, Params^);
 | 
						||
  if R.Empty then
 | 
						||
  begin
 | 
						||
    GetStaticTextDimensions(S,40,Cols,Rows);
 | 
						||
    if Cols<32 then Cols:=32; if Rows=0 then Rows:=1;
 | 
						||
    R.Assign(0,0,3+Cols+3,Rows+6);
 | 
						||
    if (AOptions and mfInsertInApp)= 0 then
 | 
						||
      R.Move((Desktop^.Size.X-(R.B.X-R.A.X)) div 2,(Desktop^.Size.Y-(R.B.Y-R.A.Y)) div 2)
 | 
						||
    else
 | 
						||
      R.Move((Application^.Size.X-(R.B.X-R.A.X)) div 2,(Application^.Size.Y-(R.B.Y-R.A.Y)) div 2);
 | 
						||
  end;
 | 
						||
  New(Dialog,Init(R, Titles[AOptions and $3]));
 | 
						||
  with Dialog^ do
 | 
						||
   begin
 | 
						||
     CanCancel:=(Options and mfCantCancel)=0;
 | 
						||
     R.Assign(3,2, Size.X-2,Size.Y-3);
 | 
						||
     Control := New(PStaticText, Init(R, S));
 | 
						||
     Insert(Control);
 | 
						||
     X := -2;
 | 
						||
     ButtonCount := 0;
 | 
						||
     for I := 0 to 3 do
 | 
						||
      if AOptions and ($10000 shl I) <> 0 then
 | 
						||
       begin
 | 
						||
         BtnName:=UserButtonName[I+1];
 | 
						||
         R.Assign(0, 0, Max(10,length(BtnName)+2), 2);
 | 
						||
         Control := New(PButton, Init(R, BtnName, UserButtonCmd[I+1], bfNormal));
 | 
						||
         Inc(X, Control^.Size.X + 2);
 | 
						||
         ButtonList[ButtonCount] := Control;
 | 
						||
         Inc(ButtonCount);
 | 
						||
       end;
 | 
						||
     for I := 0 to 3 do
 | 
						||
      if AOptions and ($0100 shl I) <> 0 then
 | 
						||
       begin
 | 
						||
         R.Assign(0, 0, 10, 2);
 | 
						||
         Control := New(PButton, Init(R, ButtonName[I], Cmds[i], bfNormal));
 | 
						||
         Inc(X, Control^.Size.X + 2);
 | 
						||
         ButtonList[ButtonCount] := Control;
 | 
						||
         Inc(ButtonCount);
 | 
						||
       end;
 | 
						||
     X := (Size.X - X) div 2;
 | 
						||
     for I := 0 to ButtonCount - 1 do
 | 
						||
      begin
 | 
						||
        Control := ButtonList[I];
 | 
						||
        Insert(Control);
 | 
						||
        Control^.MoveTo(X, Size.Y - 3);
 | 
						||
        Inc(X, Control^.Size.X + 2);
 | 
						||
      end;
 | 
						||
     SelectNext(False);
 | 
						||
   end;
 | 
						||
  if AOptions and mfInsertInApp = 0 then
 | 
						||
    AdvMessageBoxRect := DeskTop^.ExecView(Dialog)
 | 
						||
  else
 | 
						||
    AdvMessageBoxRect := Application^.ExecView(Dialog);
 | 
						||
  Dispose(Dialog, Done);
 | 
						||
end;
 | 
						||
 | 
						||
procedure InitAdvMsgBox;
 | 
						||
begin
 | 
						||
  ButtonName[0] := slYes;
 | 
						||
  ButtonName[1] := slNo;
 | 
						||
  ButtonName[2] := slOk;
 | 
						||
  ButtonName[3] := slCancel;
 | 
						||
  Titles[0] := sWarning;
 | 
						||
  Titles[1] := sError;
 | 
						||
  Titles[2] := sInformation;
 | 
						||
  Titles[3] := sConfirm;
 | 
						||
end;
 | 
						||
 | 
						||
procedure DoneAdvMsgBox;
 | 
						||
begin
 | 
						||
end;
 | 
						||
 | 
						||
 | 
						||
procedure RegisterWViews;
 | 
						||
begin
 | 
						||
{$ifndef NOOBJREG}
 | 
						||
  RegisterType(RAdvancedListBox);
 | 
						||
  RegisterType(RColorStaticText);
 | 
						||
  RegisterType(RHSListBox);
 | 
						||
  RegisterType(RDlgWindow);
 | 
						||
{$endif}
 | 
						||
end;
 | 
						||
 | 
						||
 | 
						||
END.
 |