home *** CD-ROM | disk | FTP | other *** search
/ PC-X 1998 July / pcx23_9807.iso / PC-XUSER / PC-XUSER.16 / OOP / PCX_DLG.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1998-04-13  |  36.7 KB  |  1,303 lines

  1. {*******************************************************}
  2. {                                                       }
  3. {   PC-X User Dialogs for Turbo Vision                  }
  4. {   Copyright (c) 1997 By PC-X User and Bérczi László   }
  5. {                                                       }
  6. {   Portions Copyright (c) 1990 by Borland Int.         }
  7. {*******************************************************}
  8. {Last Edit: 1997 II 15. 21:00}
  9. {$X+,V-,F+,O-,S+,Q-}
  10.  
  11. {Lásd a file végét a szerzô megállapodás véget ! - Licens agreements.}
  12.  
  13. unit PCX_Dlg;
  14.  
  15. INTERFACE
  16. uses Objects, Dialogs, Drivers, Menus, Views;
  17.  
  18. const
  19.  
  20.   GFrameCornerLU         = #193;   {┌}                     {Corner=Sarok  }
  21.   GFrameCornerRU         = #194;   {┐}                     {L=Left;R=Right}
  22.   GFrameCornerLD         = #195;   {└}                     {U=Up  ;D=Down }
  23.   GFrameCornerRD         = #197;   {┘}
  24.   GFrameSummitU          = #198;   {─}                     {Summit=Tetô   }
  25.   GFrameSummitD          = #199;   {─}
  26.   GFrameEdgeL            = #200;   {│}                     {Edge=Szél(e)  }
  27.   GFrameEdgeR            = #201;   {│}
  28.  
  29.   CheckBoxCenterN  =  #203; {' '}
  30.   CheckBoxCenterX  =  #204; {'X'}
  31.   CheckBoxLeft     =  #202; {'['}
  32.   CheckBoxRight    =  #181; {']'}
  33.   RadioButtonCenterN = #207; {' '}
  34.   RadioButtonCenterX = #206; { #7}
  35.   RadioButtonLeft    = #205; {'('}
  36.   RadioButtonRight   = #182; {')'}
  37.  
  38.   cmMouseChanged       = 1003;
  39.   cmCheckBoxChanged    = 1004;
  40.   cmRadioButtonChanged = 1005;
  41.   cmViewChanged        = 1006;
  42.   cmMove               = 1007;
  43.   cmRefresh            = 1008;
  44.   cmPCXFrameChanged    = 1009;
  45.  
  46. { Color palettes }
  47.  
  48.   {CPCXDialogs}
  49.   CPCXBlueDialog =
  50.     #64#65#66#67#68#69#70#71#72#73#74#75#76#77#78#79+                {  1- 16}
  51.     #80#81#82#83#84#85#86#87#88#89#90#91#92#92#94#95+                { 17- 32}
  52.     #96#97#98#99#100;                                                { 33- 37}
  53.     {#64-#100}
  54.   CPCXRedDialog  =
  55.     #101#102#103#104#105#106#107#108#109#110#111#112#113#114#115#116+{  1- 16}
  56.     #117#118#119#120#121#122#123#124#125#126#127#128#129#130#131#132+{ 17- 32}
  57.     #133#134#135#136#137;                                            { 33- 37}
  58.     {#101-#137}
  59.   CPCXGrayDialog =
  60.     #138#139#140#141#142#143#144#145#146#147#148#149#150#151#152#153+{  1- 16}
  61.     #154#155#156#157#158#159#160#161#162#163#164#165#166#167#168#169+{ 17- 32}
  62.     #170#171#172#173#174;                                            { 33- 37}
  63.     {#138-#174}
  64.   CPCXDialog     = CGrayDialog+#170#171#172#173#174;
  65.  
  66.   {CPCXWindows}
  67.   CPCXWindow     = CPCXDialog;
  68.   CPCXBlueWindow = CPCXBlueDialog;
  69.   CPCXRedWindow  = CPCXRedDialog;
  70.   CPCXGrayWindow = CPCXGrayDialog;
  71.  
  72.   CPCXIndicator  = #2#37#3#37;
  73.   CPCXFileEditor = #6#4;
  74.  
  75.   CPCXTitleBar      = #175;
  76.   CPCXControlBoxApp = #175;
  77.   CPCXControlBoxDlg = #34;
  78.   CPCXControlBoxWin = #34;
  79.  
  80.   CPCXFrame = #1#33#2#34#36#37#35; {CFrame + DragWindow + DragTitle}
  81.   CPCXScrollBar = #4#5#4#5; {CSrollBar + CMyScroolBox}
  82.  
  83. type
  84.   PString = OBJECTS.PString;
  85.  
  86.   PPCXPoint = ^TPCXPoint;
  87.   TPCXPoint = Object(TPoint)
  88.     procedure Assign(XA, YA: Integer);
  89.   end;
  90.  
  91.   PPCXMenuBox = ^TPCXMenuBox;
  92.   TPCXMenuBox = Object(TMenuBox)
  93.     procedure Draw; virtual;
  94.   end;
  95.  
  96.   PPCXControlBox = ^TPCXControlBox;
  97.   TPCXControlBox = Object(TStaticText)
  98.     constructor Init(P: TPCXPoint);
  99.     procedure HandleEvent(var Event: TEvent); virtual;
  100.     procedure ExecControlMenuBox; virtual;
  101.   private
  102.     ControlMenuBox: PPCXMenuBox;
  103.   end;
  104.  
  105.   PPCXControlBoxApp = ^TPCXControlBoxApp;
  106.   TPCXControlBoxApp = Object(TPCXControlBox)
  107.     function  GetPalette: PPalette; virtual;
  108.     procedure ExecControlMenuBox; virtual;
  109.   end;
  110.  
  111.   PPCXControlBoxDlg = ^TPCXControlBoxDlg;
  112.   TPCXControlBoxDlg = Object(TPCXControlBox)
  113.     function  GetPalette: PPalette; virtual;
  114.     procedure ExecControlMenuBox; virtual;
  115.   end;
  116.  
  117.   PPCXControlBoxWin = ^TPCXControlBoxWin;
  118.   TPCXControlBoxWin = Object(TPCXControlBox)
  119.     function  GetPalette: PPalette; virtual;
  120.     procedure ExecControlMenuBox; virtual;
  121.   end;
  122.  
  123.   PPCXMenuBar = ^TPCXMenuBar;
  124.   TPCXMenuBar = Object(TMenuBar)
  125.     function NewSubView(var Bounds: TRect; AMenu: PMenu;
  126.       AParentMenu: PMenuView): PMenuView; virtual;
  127.   end;
  128.  
  129.   TPCXScrollChars = Array[0..5] of Char;
  130.  
  131.   PPCXScrollBar = ^TPCXScrollBar;
  132.   TPCXScrollBar = Object(TScrollBar)
  133.     constructor Init(var Bounds: TRect);
  134.     procedure Draw; virtual;
  135.     procedure HandleEvent(var Event: TEvent); virtual;
  136.     function  GetPalette: PPalette; virtual;
  137.   private
  138.     Chars: TPCXScrollChars;
  139.     TempB: Byte;
  140.     IsHorizontal: Boolean;
  141.     procedure DrawPos(Pos: Integer);
  142.     function GetPos: Integer;
  143.     function GetSize: Integer;
  144.   end;
  145.  
  146.   PPCXFrame = ^TPCXFrame;
  147.   TPCXFrame = Object(TFrame)
  148.     procedure Draw; virtual;
  149.     function  GetPalette: PPalette; virtual;
  150.   private
  151.     FrameMode: Word;
  152.   end;
  153.  
  154.   PPCXWindow = ^TPCXWindow;
  155.   TPCXWindow = Object(TWindow)
  156.     constructor Init(var Bounds: TRect; ATitle: TTitleStr; ANumber: Integer);
  157.     procedure InitFrame; virtual;
  158.     procedure Draw; virtual;
  159.     function  GetPalette: PPalette; virtual;
  160.     procedure HandleEvent(var Event: TEvent); virtual;
  161.     function  StandardScrollBar(AOptions: Word): PPCXScrollBar;
  162.   private
  163.     ControlBoxWin: PPCXControlBoxWin;
  164.   end;
  165.  
  166.   PPCXBlueWindow = ^TPCXBlueWindow;
  167.   TPCXBlueWindow = Object(TPCXWindow)
  168.     function  GetPalette: PPalette; virtual;
  169.   end;
  170.  
  171.   PPCXRedWindow = ^TPCXRedWindow;
  172.   TPCXRedWindow = Object(TPCXWindow)
  173.     function  GetPalette: PPalette; virtual;
  174.   end;
  175.  
  176.   PPCXGrayWindow = ^TPCXGrayWindow;
  177.   TPCXGrayWindow = Object(TPCXWindow)
  178.     function  GetPalette: PPalette; virtual;
  179.   end;
  180.  
  181.   PPCXDialog = ^TPCXDialog;
  182.   TPCXDialog = Object(TDialog)
  183.     constructor Init(var Bounds: TRect; ATitle: TTitleStr);
  184.     procedure InitFrame; virtual;
  185.     procedure Draw; virtual;
  186.     function  GetPalette: PPalette; virtual;
  187.     procedure HandleEvent(var Event: TEvent); virtual;
  188.   private
  189.     ControlBoxDlg: PPCXControlBoxDlg;
  190.   end;
  191.  
  192.   PPCXBlueDialog = ^TPCXBlueDialog;
  193.   TPCXBlueDialog = Object(TPCXDialog)
  194.     function  GetPalette: PPalette; virtual;
  195.   end;
  196.  
  197.   PPCXRedDialog = ^TPCXRedDialog;
  198.   TPCXRedDialog = Object(TPCXDialog)
  199.     function  GetPalette: PPalette; virtual;
  200.   end;
  201.  
  202.   PPCXGrayDialog = ^TPCXGrayDialog;
  203.   TPCXGrayDialog = Object(TPCXDialog)
  204.     function  GetPalette: PPalette; virtual;
  205.   end;
  206.  
  207.   PPCXStaticText = ^TPCXStaticText;
  208.   TPCXStaticText = Object(TStaticText)
  209.      procedure SetText(AText: String); virtual;
  210.   end;
  211.  
  212.   PPCXButton = ^TPCXButton;
  213.   TPCXButton = Object(TButton)
  214.     procedure Draw; virtual;
  215.     procedure DrawView;
  216.     procedure DrawState(Down: Boolean); virtual;
  217.     procedure HandleEvent(var Event: TEvent); virtual;
  218.   private
  219.     procedure DrawCursor;
  220.     procedure ResetCursor; virtual;
  221.   end;
  222.  
  223.  
  224. const
  225.   IsMagyarul : Boolean = False;
  226.   IsIntensity: Boolean = False;
  227.   ShowMouseOn: Boolean = True;
  228.   IsHomokOra : Boolean = False;
  229.   On  = True;
  230.   Off = False;
  231.   Be  = True;
  232.   Ki  = False;
  233.  
  234.   {Bit flags to determine how to draw the frame icons}
  235.   fmCloseClicked = $0001;
  236.   fmZoomClicked  = $0002;
  237.  
  238.   {PCXScrollBar}
  239.   sbGraphLike = $0004;
  240.   sbTextLike  = $0008;
  241.  
  242. IMPLEMENTATION
  243. uses App, PCX_Util;
  244.  
  245. const
  246.   FrameEmpty: String[80] =  '                                        '+
  247.                             '                                        ';
  248.   FrameFull : String[80] =  '████████████████████████████████████████'+
  249.                             '████████████████████████████████████████';
  250.   GFrameUp  : String[80] =  '╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞'+
  251.                             '╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞╞';
  252.   FrameUp   : String[80] =  '▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀'+
  253.                             '▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀';
  254.   GFrameDown: String[80] =  '╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟'+
  255.                             '╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟╟';
  256.   FrameDown : String[80] =  '████████████████████████████████████████'+
  257.                             '████████████████████████████████████████';
  258.  
  259.   WindowSizer: String[2] = #210#14; {'─┘'}
  260.   ControlBox : String[2] = #209#180;{'[■]'}
  261.   UpWin      : String[2] = #214#11;
  262.   RestoreWin : String[2] = #9#10;
  263.   GFrame3DConers: Array[0..1] of Char = #221#222;
  264.   PasswordChar  : Byte = 42; {'*' = #42}
  265.  
  266. {TPCXPoint}
  267. procedure TPCXPoint.Assign(XA, YA: Integer);
  268. begin
  269.   X:=XA; Y:=YA;
  270. end;
  271.  
  272. {TPCXMenuBox}
  273. procedure TPCXMenuBox.Draw;
  274. var
  275.   CNormal, CSelect, CNormDisabled, CSelDisabled, Color: Word;
  276.   Y: Integer;
  277.   P: PMenuItem;
  278.   B: TDrawBuffer;
  279.  
  280. procedure FrameLine(N: Integer);
  281. const
  282.      FrameChars: Array[0..19] of Char = ' ┌─┐  └─┘  │ │  ├─┤ ';
  283.   PCXFrameChars: Array[0..19] of Char =
  284.     GFrameCornerLU+GFrameSummitU+GFrameSummitU+GFrameSummitU+GFrameCornerRU+
  285.     GFrameCornerLD+GFrameSummitD+GFrameSummitD+GFrameSummitD+GFrameCornerRD+
  286.     GFrameEdgeL+#32#32#32+GFrameEdgeR+
  287.     GFrameEdgeL+#32#196#32+GFrameEdgeR; {'┴╞╞╞┬├╟╟╟┼╚   ╔╚ ─ ╔'}
  288. begin
  289.   if IsPCXGraphCharsOn
  290.   then begin
  291.          MoveBuf(B[0], PCXFrameChars[N], Byte(CNormal), 2);
  292.          MoveChar(B[2], PCXFrameChars[N + 2], Byte(Color), Size.X - 4);
  293.          MoveBuf(B[Size.X - 2], PCXFrameChars[N + 3], Byte(CNormal), 2);
  294.        end
  295.   else begin
  296.          MoveBuf(B[0], FrameChars[N], Byte(CNormal), 2);
  297.          MoveChar(B[2], FrameChars[N + 2], Byte(Color), Size.X - 4);
  298.          MoveBuf(B[Size.X - 2], FrameChars[N + 3], Byte(CNormal), 2);
  299.        end;
  300. end;
  301.  
  302. procedure DrawLine;
  303. begin
  304.   WriteBuf(0, Y, Size.X, 1, B);
  305.   Inc(Y);
  306. end;
  307.  
  308. begin
  309.   CNormal := GetColor($0301);
  310.   CSelect := GetColor($0604);
  311.   CNormDisabled := GetColor($0202);
  312.   CSelDisabled := GetColor($0505);
  313.   Y := 0;
  314.   Color := CNormal;
  315.   FrameLine(0);
  316.   DrawLine;
  317.   if Menu <> nil then
  318.   begin
  319.     P := Menu^.Items;
  320.     while P <> nil do
  321.     begin
  322.       Color := CNormal;
  323.       if P^.Name = nil then FrameLine(15) else
  324.       begin
  325.         if P^.Disabled then
  326.           if P = Current then
  327.             Color := CSelDisabled else
  328.             Color := CNormDisabled else
  329.           if P = Current then Color := CSelect;
  330.         FrameLine(10);
  331.         MoveCStr(B[3], P^.Name^, Color);
  332.         if P^.Command = 0 then
  333.           MoveChar(B[Size.X - 4], #16, Byte(Color), 1) else
  334.           if P^.Param <> nil then
  335.             MoveStr(B[Size.X - 3 - Length(P^.Param^)],
  336.               P^.Param^, Byte(Color));
  337.       end;
  338.       DrawLine;
  339.       P := P^.Next;
  340.     end;
  341.   end;
  342.   Color := CNormal;
  343.   FrameLine(5);
  344.   DrawLine;
  345.   Message(Application, evCommand, cmMouseChanged, @Self);
  346. end;
  347.  
  348. {TPCXControlBox}
  349. constructor TPCXControlBox.Init(P: TPCXPoint);
  350. var
  351.   R    : TRect;
  352.   TempS: String;
  353. begin
  354.   ControlMenuBox:=nil;
  355.   R.A.X:=P.X; R.A.Y:=P.Y;
  356.               R.B.Y:=R.A.Y+1;
  357.   if IsPCXGraphCharsOn
  358.   then begin
  359.          R.B.X:=2;
  360.          TempS:=ControlBox;
  361.         end
  362.   else begin
  363.          R.B.X:=3;
  364.          TempS:='[■]';
  365.        end;
  366.   Inherited Init(R, TempS);
  367. end;
  368.  
  369. procedure TPCXControlBox.HandleEvent(var Event: TEvent);
  370. begin
  371.   ExecControlMenuBox;
  372.   Inherited HandleEvent(Event);
  373. end;
  374.  
  375. procedure TPCXControlBox.ExecControlMenuBox;
  376. begin
  377.   Abstract;
  378. end;
  379.  
  380. procedure TPCXControlBoxApp.ExecControlMenuBox;
  381. var
  382.   R    : TRect;
  383.   O    : TPCXPoint;
  384.   C    : Word;
  385.   Event: TEvent;
  386. begin
  387.   O.Assign(0,0);
  388.   MakeGlobal(O, O);
  389.   R.Assign(O.X,O.Y+1,O.X+18,O.Y+7);
  390.   if IsMagyarul then
  391.   begin
  392.     Inc(R.A.X, 2);
  393.     Inc(R.B.X, 2);
  394.   end;
  395.   if Not IsMagyarul then
  396.   New(ControlMenuBox, Init(R, NewMenu(
  397.     NewItem('~M~ove', 'Crt-F5', kbCtrlF5, cmMove, hcNoContext,
  398.     NewItem('~Q~uit', 'Alt- X', kbAltQ, cmQuit, hcNoContext,
  399.     NewLine(
  400.     NewItem('~R~efresh', '', kbNoKey, cmRefresh, hcNoContext, nil))))),
  401.     nil))           else
  402.   New(ControlMenuBox, Init(R, NewMenu(
  403.     NewItem('~M~ozgat', 'Crt-F5', kbCtrlF5, cmMove, hcNoContext,
  404.     NewItem('~K~ilépés', 'Alt- X', kbAltQ, cmQuit, hcNoContext,
  405.     NewLine(
  406.     NewItem('~F~rissítés', '', kbNoKey, cmRefresh, hcNoContext, nil))))),
  407.     nil));
  408.   C:=Application^.ExecView(ControlMenuBox);
  409.   if C<>cmCancel then
  410.   begin
  411.     case C of cmMove:
  412.               begin
  413.                 {Application^.GetEvent(Event);
  414.                 Event.What:=evKeyboard;
  415.                 Application^.PutEvent(Event);}
  416.                 KeyStrokeToKeyboardBuffer(0, $62);
  417.                 Message(Application, evCommand, cmMouseChanged, @Self);
  418.               end;
  419.               cmRefresh: Application^.ReDraw;
  420.               cmQuit:  {if AreYouSureToQuit then} Message(Application, evCommand, cmQuit, @Self);
  421.     {javit!}
  422.  
  423.  
  424.     end;
  425.   end;
  426. end;
  427.  
  428. function  TPCXControlBoxApp.GetPalette: PPalette;
  429. const P: String[Length(CPCXControlBoxApp)] = CPCXControlBoxApp;
  430. begin
  431.   GetPalette:=@P;
  432. end;
  433.  
  434. procedure TPCXControlBoxDlg.ExecControlMenuBox;
  435. var
  436.   R    : TRect;
  437.   O    : TPCXPoint;
  438.   C    : Word;
  439.   Event: TEvent;
  440. begin
  441.   O.Assign(1,0);
  442.   MakeGlobal(O, O);
  443.   R.Assign(O.X,O.Y+1,O.X+18,O.Y+7);
  444.   if IsMagyarul then
  445.   begin
  446.     Inc(R.A.X);
  447.     Inc(R.B.X);
  448.   end;
  449.   if IsMagyarul then
  450.   New(ControlMenuBox, Init(R, NewMenu(
  451.     NewItem('~M~ozgat', 'Crt-F5', kbCtrlF5, cmMove, hcNoContext,
  452.     NewItem('~B~ezár', 'Alt-F3', kbAltF3, cmClose, hcNoContext,
  453.     NewLine(
  454.     NewItem('~F~rissít', '', kbNoKey, cmRefresh, hcNoContext, nil))))),
  455.     nil))           else
  456.   New(ControlMenuBox, Init(R, NewMenu(
  457.     NewItem('~M~ove', 'Crt-F5', kbCtrlF5, cmMove, hcNoContext,
  458.     NewItem('~C~lose', 'Alt-F3', kbAltF3, cmClose, hcNoContext,
  459.     NewLine(
  460.     NewItem('~R~efresh', '', kbNoKey, cmRefresh, hcNoContext, nil))))),
  461.     nil));
  462.   C:=Application^.ExecView(ControlMenuBox);
  463.   Owner^.EnableCommands([cmClose]);
  464.   EnableCommands([cmClose]);
  465.   if C<>cmCancel then
  466.   begin
  467.     case C of cmMove:
  468.               begin
  469.                 {Application^.GetEvent(Event);
  470.                 Event.What:=evKeyboard;
  471.                 Application^.PutEvent(Event);}
  472.                 KeyStrokeToKeyboardBuffer(0, $62);
  473.                 Message(Application, evCommand, cmMouseChanged, @Self);
  474.               end;
  475.               cmRefresh: Application^.ReDraw;
  476.               cmClose:   begin
  477.                            KeyStrokeToKeyboardBuffer(0, $6A);
  478.                            Message(Application, evBroadcast, cmClose, @Self);
  479.                            Message(Application, evCommand, cmMouseChanged, @Self);
  480.                          end;
  481.     end;
  482.   end;
  483. end;
  484.  
  485. function  TPCXControlBoxDlg.GetPalette: PPalette;
  486. const P: String[Length(CPCXControlBoxDlg)] = CPCXControlBoxDlg;
  487. begin
  488.   GetPalette:=@P;
  489. end;
  490.  
  491. procedure TPCXControlBoxWin.ExecControlMenuBox;
  492. var
  493.   R    : TRect;
  494.   O    : TPCXPoint;
  495.   C    : Word;
  496. begin
  497.   O.Assign(1,0);
  498.   MakeGlobal(O, O);
  499.   R.Assign(O.X,O.Y+1,O.X+18,O.Y+7);
  500.   Owner^.EnableCommands([cmClose]);
  501.   EnableCommands([cmClose]);
  502.   if IsMagyarul then
  503.   begin
  504.     Inc(R.A.X);
  505.     Inc(R.B.X);
  506.   end;
  507.   if IsMagyarul then
  508.   New(ControlMenuBox, Init(R, NewMenu(
  509.     NewItem('~M~ozgat', 'Crt-F5', kbCtrlF5, cmMove, hcNoContext,
  510.     NewItem('~B~ezár', 'Alt-F3', kbAltF3, cmClose, hcNoContext,
  511.     NewLine(
  512.     NewItem('~F~rissít', '', kbNoKey, cmRefresh, hcNoContext, nil))))),
  513.     nil))           else
  514.   New(ControlMenuBox, Init(R, NewMenu(
  515.     NewItem('~M~ove', 'Crt-F5', kbCtrlF5, cmMove, hcNoContext,
  516.     NewItem('~C~lose', 'Alt-F3', kbAltF3, cmClose, hcNoContext,
  517.     NewLine(
  518.     NewItem('~R~efresh', '', kbNoKey, cmRefresh, hcNoContext, nil))))),
  519.     nil));
  520.   C:=Application^.ExecView(ControlMenuBox);
  521.   if C<>cmCancel then
  522.   begin
  523.     case C of cmMove:
  524.               begin
  525.                  KeyStrokeToKeyboardBuffer(0, $62);
  526.                  Message(Application, evCommand, cmMouseChanged, @Self);
  527.               end;
  528.               cmRefresh: Application^.ReDraw;
  529.               cmClose:
  530.               begin
  531.                  KeyStrokeToKeyboardBuffer(0, $6A);
  532.                  Message(Application, evCommand, cmMouseChanged, @Self);
  533.               end;
  534.  
  535.     end;
  536.   end;
  537. end;
  538.  
  539. function  TPCXControlBoxWin.GetPalette: PPalette;
  540. const P: String[Length(CPCXControlBoxWin)] = CPCXControlBoxWin;
  541. begin
  542.   GetPalette:=@P;
  543. end;
  544.  
  545. {TPCXMenuBar}
  546. function TPCXMenuBar.NewSubView(var Bounds: TRect; AMenu: PMenu;
  547.   AParentMenu: PMenuView): PMenuView;
  548. begin
  549.   NewSubView := New(PPCXMenuBox, Init(Bounds, AMenu, AParentMenu));
  550. end;
  551.  
  552. {TPCXScrollBar}
  553. constructor TPCXScrollBar.Init(var Bounds: TRect);
  554. const
  555.   {                           felb  felj   leb   lej  }
  556.   GVChars: TPCXScrollChars = (#212, #183, #213, #184, GFrameEdgeL, GFrameEdgeR);
  557.   GHChars: TPCXScrollChars = (#217, #21, #218, #185, #215, #215);
  558.   VChars : TPCXScrollChars = (#30, #31, #177, #254, #178, #32); {Text, it's  }
  559.   HChars : TPCXScrollChars = (#17, #16, #177, #254, #178, #32); {the original}
  560. begin
  561.   TView.Init(Bounds);
  562.   if IsPCXGraphCharsOn then TempB:=2
  563.                        else TempB:=1;
  564.   Value := 0;
  565.   Min := 0;
  566.   Max := 0;
  567.   PgStep := 1;
  568.   ArStep := 1;
  569.   if Size.X = TempB then
  570.   begin
  571.     GrowMode := gfGrowLoX + gfGrowHiX + gfGrowHiY;
  572.     if IsPCXGraphCharsOn then Chars := GVChars
  573.                          else Chars := VChars;
  574.     IsHorizontal:=False;
  575.   end else
  576.   begin
  577.     GrowMode := gfGrowLoY + gfGrowHiX + gfGrowHiY;
  578.     if IsPCXGraphCharsOn then Chars := GHChars
  579.                          else Chars := HChars;
  580.     IsHorizontal:=True;
  581.   end;
  582. end;
  583.  
  584. procedure TPCXScrollBar.Draw;
  585. begin
  586.   DrawPos(GetPos);
  587.   Message(Application, evCommand, cmMouseChanged, @Self);
  588.  
  589.   { Include it to evIdle in HandleEvent for make realtime show|hide scrollbars
  590.   if HScrollBar <> nil then
  591.    if HScrollBar^.Min = HScrollBar^.Max 
  592.    then HScrollBar^.Hide
  593.    else HScrollBar^.Show;
  594.   }
  595. end;
  596.  
  597. procedure TPCXScrollBar.DrawPos(Pos: Integer);
  598. var
  599.   S: Integer;
  600.   B: TDrawBuffer;
  601.   i: Word;
  602. begin
  603.   if IsPCXGraphCharsOn then
  604.   begin
  605.     if Not IsHorizontal then
  606.     begin
  607.       S := GetSize - 1;
  608.       MoveCStr(B[0], Chars[0], GetColor(2));
  609.       MoveCStr(B[1], Chars[1], SwapHighAndLowAreaOfByte(GetColor(2)));
  610.       if Max = Min then
  611.       begin
  612.         i:=0;
  613.         while i<(S*2)-1 do
  614.         begin
  615.           Inc(I,2);
  616.           MoveCStr(B[i], ''+Chars[4]+Chars[5]+'', GetColor(1));
  617.         end;
  618.       end
  619.       else
  620.       begin
  621.           i:=0;
  622.           while i<(S*2)-1 do
  623.           begin
  624.             Inc(i,2);
  625.             MoveCStr(B[i], ''+Chars[4]+Chars[5]+'', GetColor(3));
  626.             MoveCStr(B[Pos*2], ''+Chars[4]+Chars[5]+'', GetColor(4));
  627.           end;
  628.       end;
  629.       MoveCStr(B[S*2], Chars[2], GetColor(2));
  630.       MoveCStr(B[(S*2)+1], Chars[3], SwapHighAndLowAreaOfByte(GetColor(2)));
  631.       WriteBuf(0, 0, Size.X, Size.Y, B);      
  632.     end
  633.     else
  634.     begin
  635.       S := GetSize - 1;
  636.       if Pos=1 then Inc(Pos);
  637.       if Pos+1=S then Pos:=S-3;
  638.       MoveCStr(B[0], Chars[0], GetColor(2));
  639.       MoveCStr(B[1], Chars[1], SwapHighAndLowAreaOfByte(GetColor(2)));
  640.       if Max = Min then
  641.         MoveChar(B[2], Chars[4], GetColor(1), S - 2)
  642.       else
  643.       begin
  644.         MoveChar(B[2], Chars[4], GetColor(3), S - 2);
  645.         MoveCStr(B[Pos], Chars[5]+Chars[5], GetColor(4));
  646.       end;
  647.       MoveCStr(B[S-1], Chars[2], GetColor(2));
  648.       MoveCStr(B[S], Chars[3], SwapHighAndLowAreaOfByte(GetColor(2)));
  649.       WriteBuf(0, 0, Size.X, Size.Y, B);
  650.     end;
  651.   end
  652.   else
  653.   begin
  654.     S := GetSize - 1;
  655.     MoveChar(B[0], Chars[0], GetColor(2), 1);
  656.     if Max = Min then
  657.       MoveChar(B[1], Chars[4], GetColor(1), S - 1)
  658.     else
  659.     begin
  660.       MoveChar(B[1], Chars[2], GetColor(1), S - 1);
  661.       MoveChar(B[Pos], Chars[3], GetColor(3), 1);
  662.     end;
  663.     MoveChar(B[S], Chars[1], GetColor(2), 1);
  664.     WriteBuf(0, 0, Size.X, Size.Y, B);
  665.   end;
  666.   Message(Application, evCommand, cmMouseChanged, @Self);
  667. end;
  668.  
  669. procedure TPCXScrollBar.HandleEvent(var Event: TEvent);
  670. var
  671.   Tracking : Boolean;
  672.   I, P,
  673.   S,
  674.   ClickPart: Integer;
  675.   Mouse    : TPoint;
  676.   Extent   : TRect;
  677. function GetPartCode: Integer;
  678. var
  679.   Mark, Part: Integer;
  680. begin
  681.   Part := -1;
  682.   if Extent.Contains(Mouse) then
  683.   begin
  684.     if Size.X = TempB then Mark := Mouse.Y else Mark := Mouse.X;
  685.     if Mark = P then Part := sbIndicator else
  686.     begin
  687.       if Mark < TempB then Part := sbLeftArrow else
  688.         if Mark < P then Part := sbPageLeft else
  689.           if Mark < S then Part := sbPageRight else
  690.             Part := sbRightArrow;
  691.       if Size.X = TempB then Inc(Part, 4);
  692.     end;
  693.   end;
  694.   GetPartCode := Part;
  695. end;
  696.  
  697. procedure Clicked;
  698. begin
  699.   Message(Owner, evCommand, cmViewChanged, @Self);
  700. end;
  701.  
  702. begin
  703.   TView.HandleEvent(Event);
  704.   case Event.What of
  705.     evMouseDown:
  706.       begin
  707.         Clicked;
  708.         MakeLocal(Event.Where, Mouse);
  709.         GetExtent(Extent);
  710.         Extent.Grow(1, 1);
  711.         P := GetPos;
  712.         S := GetSize - 1;
  713.         ClickPart := GetPartCode;
  714.         if ClickPart <> sbIndicator then
  715.         begin
  716.           repeat
  717.             MakeLocal(Event.Where, Mouse);
  718.             if GetPartCode = ClickPart then
  719.               SetValue(Value + ScrollStep(ClickPart));
  720.           until not MouseEvent(Event, evMouseAuto);
  721.         end else
  722.         begin
  723.           repeat
  724.             MakeLocal(Event.Where, Mouse);
  725.             Tracking := Extent.Contains(Mouse);
  726.             if Tracking then
  727.             begin
  728.               if Size.X = TempB then I := Mouse.Y else I := Mouse.X;
  729.               if I <= 0 then I := 1;
  730.               if I >= S then I := S - 1;
  731.             end else I := GetPos;
  732.             if I <> P then
  733.             begin
  734.               DrawPos(I);
  735.               P := I;
  736.             end;
  737.           until not MouseEvent(Event, evMouseMove);
  738.           if Tracking and (S > 2) then
  739.           begin
  740.             Dec(S, 2);
  741.             SetValue(LongDiv(LongMul(P - 1, Max - Min) + S shr 1, S) + Min);
  742.           end;
  743.         end;
  744.         ClearEvent(Event);
  745.       end;
  746.     evKeyDown:
  747.       if State and sfVisible <> 0 then
  748.       begin
  749.         ClickPart := sbIndicator;
  750.         if Size.Y = 1 then
  751.           case CtrlToArrow(Event.KeyCode) of
  752.             kbLeft: ClickPart := sbLeftArrow;
  753.             kbRight: ClickPart := sbRightArrow;
  754.             kbCtrlLeft: ClickPart := sbPageLeft;
  755.             kbCtrlRight: ClickPart := sbPageRight;
  756.             kbHome: I := Min;
  757.             kbEnd: I := Max;
  758.           else
  759.             Exit;
  760.           end
  761.         else
  762.           case CtrlToArrow(Event.KeyCode) of
  763.             kbUp: ClickPart := sbUpArrow;
  764.             kbDown: ClickPart := sbDownArrow;
  765.             kbPgUp: ClickPart := sbPageUp;
  766.             kbPgDn: ClickPart := sbPageDown;
  767.             kbCtrlPgUp: I := Min;
  768.             kbCtrlPgDn: I := Max;
  769.           else
  770.             Exit;
  771.           end;
  772.         Clicked;
  773.         if ClickPart <> sbIndicator then I := Value + ScrollStep(ClickPart);
  774.         SetValue(I);
  775.         ClearEvent(Event);
  776.       end;
  777.   end;
  778. end;
  779.  
  780. function TPCXScrollBar.GetPalette: PPalette;
  781. const P: String[Length(CPCXScrollBar)] = CPCXScrollBar;
  782. begin
  783.   GetPalette:=@P;
  784. end;
  785.  
  786. function TPCXScrollBar.GetPos: Integer;
  787. var
  788.   R: Integer;
  789. begin
  790.   R := Max - Min;
  791.   if R = 0 then
  792.     GetPos := 1 else
  793.     GetPos := LongDiv(LongMul(Value - Min, GetSize - 3) + R shr 1, R) + 1;
  794. end;
  795.  
  796. function TPCXScrollBar.GetSize: Integer;
  797. var
  798.   S: Integer;
  799. begin
  800.   if Size.X = TempB then S := Size.Y else S := Size.X;
  801.   if S < 2+TempB then GetSize := 2+TempB else GetSize := S;
  802. end;
  803.  
  804. {TPCXFrame}
  805. procedure TPCXFrame.Draw;
  806. var
  807.   CFrame, CTitle: Word;
  808.   F, I, L, Width: Integer;
  809.   B: TDrawBuffer;
  810.   Title: TTitleStr;
  811.   Min, Max: TPoint;
  812. begin
  813.   if State and sfDragging <> 0 then
  814.   begin
  815.     CFrame := $0706;
  816.     CTitle := $0007;
  817.     F := 0;
  818.   end else if State and sfActive = 0 then
  819.   begin
  820.     CFrame := $0101;
  821.     CTitle := $0002;
  822.     F := 0;
  823.   end else
  824.   begin
  825.     CFrame := $0503;
  826.     CTitle := $0004;
  827.     F := 9;
  828.   end;
  829.   CFrame := GetColor(CFrame);
  830.   CTitle := GetColor(CTitle);
  831.   Width := Size.X;
  832.   L := Width - 10;
  833.   if PWindow(Owner)^.Flags and (wfClose+wfZoom) <> 0 then Dec(L,6);
  834.   if IsPCXGraphCharsOn then MoveCStr(B, Copy(FrameEmpty, 1, Size.X), CTitle)
  835.                        else MoveCStr(B, Copy(FrameEmpty, 1, Size.X), CTitle);
  836.   if (PWindow(Owner)^.Number <> wnNoNumber) and
  837.      (PWindow(Owner)^.Number < 10) then
  838.   begin
  839.     Dec(L,4);
  840.     if PWindow(Owner)^.Flags and wfZoom <> 0 then I := 7
  841.     else I := 3;
  842.     WordRec(B[Width - I]).Lo := PWindow(Owner)^.Number + $30;
  843.   end;
  844.   if Owner <> nil then Title := PWindow(Owner)^.GetTitle(L)
  845.   else Title := '';
  846.   if Title <> '' then
  847.   begin
  848.     L := Length(Title);
  849.     if L > Width - 10 then L := Width - 10;
  850.     if L < 0 then L := 0;
  851.     I := (Width - L) shr 1;
  852.     MoveChar(B[I - 1], ' ', CTitle, 1);
  853.     MoveBuf(B[I], Title[1], CTitle, L);
  854.     MoveChar(B[I + L], ' ', CTitle, 1);
  855.   end;
  856.   if State and sfActive <> 0 then
  857.   begin
  858.     if PWindow(Owner)^.Flags and wfClose <> 0 then
  859.       if FrameMode and fmCloseClicked = 0 then
  860.         if IsPCXGraphCharsOn then MoveCStr(B[0], '~'+ControlBox+'~', CFrame) {#209#180}
  861.                              else MoveCStr(B[1], '', CFrame) {~[■]~}
  862.       else MoveCStr(B[2], '[~'#15'~]', CFrame);
  863.     if PWindow(Owner)^.Flags and wfZoom <> 0 then
  864.     begin
  865.       if IsPCXGraphCharsOn then MoveCStr(B[Width - 4], '~'+UpWin+'~', CFrame)
  866.                            else MoveCStr(B[Width - 4], '~['#24']~', CFrame);
  867.       Owner^.SizeLimits(Min, Max);
  868.       if FrameMode and fmZoomClicked <> 0 then
  869.         WordRec(B[Width - 4]).Lo := 15
  870.       else if Longint(Owner^.Size) = Longint(Max) then
  871.       begin
  872.         if IsPCXGraphCharsOn then MoveCStr(B[Width - 4], '~'+RestoreWin+'~', CFrame)
  873.                              else MoveCStr(B[Width - 4], '~['#18']~', CFrame);
  874.       end;
  875.     end;
  876.   end;
  877.   WriteLine(0, 0, Size.X, 1, B);
  878.   for I := 1 to Size.Y - 2 do
  879.   begin
  880.     if IsPCXGraphCharsOn then MoveCStr(B, GFrameEdgeL+Copy(FrameEmpty, 1, Size.X-2)+GFrameEdgeR, CFrame)
  881.                          else MoveCStr(B, #221+Copy(FrameEmpty, 1, Size.X-2)+#222, CFrame);
  882.     WriteLine(0, I, Size.X, 1, B);
  883.   end;
  884.   if IsPCXGraphCharsOn then MoveCStr(B, GFrameCornerLD+Copy(GFrameDown, 1, Size.X-2)+GFrameCornerRD, CFrame)
  885.                        else MoveCStr(B, {#221+} Copy(FrameDown{FrameFull}, 1, Size.X) {+#222}, CFrame);
  886.   if State and sfActive <> 0 then
  887.     if PWindow(Owner)^.Flags and wfGrow <> 0 then
  888.       if IsPCXGraphCharsOn then MoveCStr(B[Width - 2], WindowSizer, CFrame) {#210#211}
  889.                            else MoveCStr(B[Width - 2], '~─┘~', CFrame);
  890.   WriteLine(0, Size.Y - 1, Size.X, 1, B);
  891.   Message(Application, evCommand, cmMouseChanged, @Self);
  892.   Message(Application, evCommand, cmPCXFrameChanged, @Self);
  893.   Message(Application, evBroadcast, cmPCXFrameChanged, @Self);
  894. end;
  895.  
  896. function  TPCXFrame.GetPalette: PPalette;
  897. const P: String[Length(CPCXFrame)] = CPCXFrame;
  898. begin
  899.   GetPalette:=@P;
  900. end;
  901.  
  902. {TPCXWindow}
  903. constructor TPCXWindow.Init(var Bounds: TRect; ATitle: TTitleStr; ANumber: Integer);
  904. var P: TPCXPoint;
  905. begin
  906.   Inherited Init(Bounds, ATitle, ANumber);
  907.   P.Assign(0, 0);
  908.   New(ControlBoxWin, Init(P));
  909.   Insert(ControlBoxWin);
  910. end;
  911.  
  912. procedure TPCXWindow.InitFrame;
  913. var R: TRect;
  914. begin
  915.   GetExtent(R);
  916.   Frame := New(PPCXFrame, Init(R));
  917. end;
  918.  
  919. procedure TPCXWindow.Draw;
  920. begin
  921.   Inherited Draw;
  922.   Message(Application, evCommand, cmMouseChanged, @Self);  
  923. end;
  924.  
  925. function  TPCXWindow.GetPalette: PPalette;
  926. const P: String[Length(CPCXWindow)] = CPCXWindow;
  927. begin
  928.   GetPalette:=@P;
  929. end;
  930.  
  931. procedure TPCXWindow.HandleEvent(var Event: TEvent);
  932. begin
  933.   if Event.KeyCode=kbAltSpace then
  934.   begin
  935.     ControlBoxWin^.ExecControlMenuBox;
  936.     Event.KeyCode:=Event.KeyCode and Not kbAltSpace;
  937.   end;
  938.   Inherited HandleEvent(Event);
  939. end;
  940.  
  941. function TPCXWindow.StandardScrollBar(AOptions: Word): PPCXScrollBar;
  942. var
  943.   R: TRect;
  944.   S: PPCXScrollBar;
  945. begin
  946.   GetExtent(R);
  947.   if AOptions and sbGraphLike = 0
  948.   then if AOptions and sbVertical = 0 
  949.        then R.Assign(R.A.X + 2, R.B.Y-1, R.B.X-2, R.B.Y) 
  950.        else R.Assign(R.B.X-1,R.A.Y+1,R.B.X,R.B.Y-1)
  951.   else if AOptions and sbVertical = 0 
  952.        then R.Assign(R.A.X + 2, R.B.Y-1, R.B.X-2, R.B.Y) 
  953.        else R.Assign(R.B.X-2,R.A.Y+1,R.B.X,R.B.Y-1);
  954.   S := New(PPCXScrollBar, Init(R));
  955.   Insert(S);
  956.   if AOptions and sbHandleKeyboard <> 0 
  957.   then S^.Options := S^.Options or ofPostProcess;
  958.   StandardScrollBar := S;
  959. end;
  960.  
  961. {TPCXXXXXWindows}
  962. function  TPCXBlueWindow.GetPalette: PPalette;
  963. const P: String[Length(CPCXBlueWindow)] = CPCXBlueWindow;
  964. begin
  965.   GetPalette:=@P;
  966. end;
  967.  
  968. function  TPCXRedWindow.GetPalette: PPalette;
  969. const P: String[Length(CPCXRedWindow)] = CPCXRedWindow;
  970. begin
  971.   GetPalette:=@P;
  972. end;
  973.  
  974. function  TPCXGrayWindow.GetPalette: PPalette;
  975. const P: String[Length(CPCXGrayWindow)] = CPCXGrayWindow;
  976. begin
  977.   GetPalette:=@P;
  978. end;
  979.  
  980. {TPCXDialog}
  981. constructor TPCXDialog.Init(var Bounds: TRect; ATitle: TTitleStr);
  982. var P: TPCXPoint;
  983. begin
  984.   Inherited Init(Bounds, ATitle);
  985.   P.Assign(0,0);
  986.   New(ControlBoxDlg, Init(P));
  987.   Insert(ControlBoxDlg);
  988. end;
  989.  
  990. procedure TPCXDialog.InitFrame;
  991. var
  992.   R: TRect;
  993. begin
  994.   GetExtent(R);
  995.   Frame := New(PPCXFrame, Init(R));
  996. end;
  997.  
  998. procedure TPCXDialog.Draw;
  999. begin
  1000.   Inherited Draw;
  1001.   Message(Application, evCommand, cmMouseChanged, @Self);  
  1002. end;
  1003.  
  1004. function  TPCXDialog.GetPalette: PPalette;
  1005. const P: String[Length(CPCXDialog)] = CPCXDialog;
  1006. begin
  1007.   GetPalette:=@P;
  1008. end;
  1009.  
  1010. procedure TPCXDialog.HandleEvent(var Event: TEvent);
  1011. begin
  1012.   if Event.KeyCode=kbAltSpace then
  1013.   begin
  1014.     ControlBoxDlg^.ExecControlMenuBox;
  1015.     Event.KeyCode:=Event.KeyCode and Not kbAltSpace;
  1016.   end;
  1017.   Inherited HandleEvent(Event);
  1018. end;
  1019.  
  1020. function  TPCXBlueDialog.GetPalette: PPalette;
  1021. const P: String[Length(CPCXBlueDialog)] = CPCXBlueDialog;
  1022. begin
  1023.   GetPalette:=@P;
  1024. end;
  1025.  
  1026. function  TPCXRedDialog.GetPalette: PPalette;
  1027. const P: String[Length(CPCXRedDialog)] = CPCXRedDialog;
  1028. begin
  1029.   GetPalette:=@P;
  1030. end;
  1031.  
  1032. function  TPCXGrayDialog.GetPalette: PPalette;
  1033. const P: String[Length(CPCXGrayDialog)] = CPCXGrayDialog;
  1034. begin
  1035.   GetPalette:=@P;
  1036. end;
  1037.  
  1038. {TPCXStaticText}
  1039. procedure TPCXStaticText.SetText(AText: String);
  1040. begin
  1041.   if Text<>nil then DisposeStr(Text);   {Idea: By Bérczi Gábor, Power INC.}
  1042.   if AText<>'' then Text:=NewStr(AText) {      TOO . . .                  }
  1043.                else Text:=Nil;          {      TOO . . .                  }
  1044.   Draw;
  1045.   Message(Application, evCommand, cmMouseChanged, @Self);
  1046. end;
  1047.  
  1048. {TPCXButton}
  1049. procedure TPCXButton.Draw;
  1050. begin
  1051.   DrawState(False);
  1052.   Message(Application, evCommand, cmMouseChanged, @Self);
  1053. end;
  1054.  
  1055. procedure TPCXButton.DrawState(Down: Boolean);
  1056. var
  1057.   CButton, CShadow: Word;
  1058.   Ch: Char;
  1059.   I, S, Y, T: Integer;
  1060.   B: TDrawBuffer;
  1061.  
  1062. procedure DrawTitle;
  1063. var
  1064.   L, SCOff: Integer;
  1065. begin
  1066.   if Flags and bfLeftJust <> 0 then L := 1 else
  1067.   begin
  1068.     L := (S - CStrLen(Title^) - 1) div 2;
  1069.     if L < 1 then L := 1;
  1070.   end;
  1071.   MoveCStr(B[I + L], Title^, CButton);
  1072.   if ShowMarkers and not Down then
  1073.   begin
  1074.     if State and sfSelected <> 0 then SCOff := 0 else
  1075.       if AmDefault then SCOff := 2 else SCOff := 4;
  1076.     WordRec(B[0]).Lo := Byte(SpecialChars[SCOff]);
  1077.     WordRec(B[S]).Lo := Byte(SpecialChars[SCOff + 1]);
  1078.   end;
  1079. end;
  1080.  
  1081. begin
  1082.   if State and sfDisabled <> 0 then CButton := GetColor($0404) else
  1083.   begin
  1084.     CButton := GetColor($0501);
  1085.     if State and sfActive <> 0 then
  1086.       if State and sfSelected <> 0 then CButton := GetColor($0703) else
  1087.         if AmDefault then CButton := GetColor($0602);
  1088.   end;
  1089.   CShadow := GetColor(8);
  1090.   S := Size.X - 1;
  1091.   T := Size.Y div 2 - 1;
  1092.   for Y := 0 to Size.Y - 2 do
  1093.   begin
  1094.     MoveChar(B, ' ', Byte(CButton), Size.X);
  1095.     WordRec(B[0]).Hi := CShadow;
  1096.     if Down then
  1097.     begin
  1098.       WordRec(B[1]).Hi := CShadow;
  1099.       Ch := ' ';
  1100.       I := 2;
  1101.     end else
  1102.     begin
  1103.       if ShowMarkers then WordRec(B[S]).Hi := Byte(CShadow)
  1104.                      else WordRec(B[S]).Hi := SwapHighAndLowAreaOfByte(Byte(CShadow)); {from PCX_Util}
  1105.       if ShowMarkers then Ch := ' ' else
  1106.       begin
  1107.         if Y = 0 then
  1108.           WordRec(B[S]).Lo := Byte('▀') else {#223 invert = #220}
  1109.           WordRec(B[S]).Lo := Byte('█');
  1110.         Ch := '▀';
  1111.       end;
  1112.       I := 1;
  1113.     end;
  1114.     if (Y = T) and (Title <> nil) then DrawTitle;
  1115.     if ShowMarkers and not Down then
  1116.     begin
  1117.       WordRec(B[1]).Lo := Byte('[');
  1118.       WordRec(B[S - 1]).Lo := Byte(']');
  1119.     end;
  1120.     WriteLine(0, Y, Size.X, 1, B);
  1121.   end;
  1122.   MoveChar(B[0], ' ', Byte(CShadow), 2);
  1123.   MoveChar(B[2], Ch, Byte(CShadow), S - 1);
  1124.   WriteLine(0, Size.Y - 1, Size.X, 1, B);
  1125. end;
  1126.  
  1127. function HotKey(const S: String): Char;
  1128. var
  1129.   P: Word;
  1130. begin
  1131.   P := Pos('~',S);
  1132.   if P <> 0 then HotKey := UpCase(S[P+1])
  1133.   else HotKey := #0;
  1134. end;
  1135.  
  1136. const
  1137.  
  1138. { TButton messages }
  1139.  
  1140.   cmGrabDefault    = 61;
  1141.   cmReleaseDefault = 62;
  1142.  
  1143. procedure TPCXButton.HandleEvent(var Event: TEvent);
  1144. var
  1145.   Down: Boolean;
  1146.   C: Char;
  1147.   Mouse: TPoint;
  1148.   ClickRect: TRect;
  1149. begin
  1150.   GetExtent(ClickRect);
  1151.   Inc(ClickRect.A.X);
  1152.   Dec(ClickRect.B.X);
  1153.   Dec(ClickRect.B.Y);
  1154.   if Event.What = evMouseDown then
  1155.   begin
  1156.     MakeLocal(Event.Where, Mouse);
  1157.     if not ClickRect.Contains(Mouse) then ClearEvent(Event);
  1158.   end;
  1159.   if Flags and bfGrabFocus <> 0 then
  1160.     TView.HandleEvent(Event);
  1161.   case Event.What of
  1162.     evMouseDown:
  1163.       begin
  1164.         if State and sfDisabled = 0 then
  1165.         begin
  1166.           Inc(ClickRect.B.X);
  1167.           Down := False;
  1168.           repeat
  1169.             MakeLocal(Event.Where, Mouse);
  1170.             if Down <> ClickRect.Contains(Mouse) then
  1171.             begin
  1172.               Down := not Down;
  1173.               DrawState(Down);
  1174.             end;
  1175.           until not MouseEvent(Event, evMouseMove);
  1176.           if Down then
  1177.           begin
  1178.             Press;
  1179.             DrawState(False);
  1180.           end;
  1181.         end;
  1182.         ClearEvent(Event);
  1183.       end;
  1184.     evKeyDown:
  1185.       begin
  1186.         C := HotKey(Title^);
  1187.         if (Event.KeyCode = GetAltCode(C)) or
  1188.           (Owner^.Phase = phPostProcess) and (C <> #0) and
  1189.             (Upcase(Event.CharCode) = C) or
  1190.           (State and sfFocused <> 0) and (Event.CharCode = ' ') then
  1191.         begin
  1192.           Press;
  1193.           ClearEvent(Event);
  1194.         end;
  1195.       end;
  1196.     evBroadcast:
  1197.       case Event.Command of
  1198.         cmDefault:
  1199.           if AmDefault then
  1200.           begin
  1201.             Press;
  1202.             ClearEvent(Event);
  1203.           end;
  1204.         cmGrabDefault, cmReleaseDefault:
  1205.           if Flags and bfDefault <> 0 then
  1206.           begin
  1207.             AmDefault := Event.Command = cmReleaseDefault;
  1208.             DrawView;
  1209.           end;
  1210.         cmCommandSetChanged:
  1211.           begin
  1212.             SetState(sfDisabled, not CommandEnabled(Command));
  1213.             DrawView;
  1214.           end;
  1215.       end;
  1216.   end;
  1217. end;
  1218.  
  1219. procedure TPCXButton.ResetCursor; assembler;
  1220. asm
  1221.         LES     DI,Self
  1222.         MOV     AX,ES:[DI].TPCXButton.State
  1223.         NOT     AX
  1224.         TEST    AX,sfVisible+sfCursorVis+sfFocused
  1225.         JNE     @@4
  1226.         MOV     AX,ES:[DI].TView.Cursor.Y
  1227.         MOV     DX,ES:[DI].TView.Cursor.X
  1228. @@1:    OR      AX,AX
  1229.         JL      @@4
  1230.         CMP     AX,ES:[DI].TPCXButton.Size.Y
  1231.         JGE     @@4
  1232.         OR      DX,DX
  1233.         JL      @@4
  1234.         CMP     DX,ES:[DI].TPCXButton.Size.X
  1235.         JGE     @@4
  1236.         ADD     AX,ES:[DI].TPCXButton.Origin.Y
  1237.         ADD     DX,ES:[DI].TPCXButton.Origin.X
  1238.         MOV     CX,DI
  1239.         MOV     BX,ES
  1240.         LES     DI,ES:[DI].TPCXButton.Owner
  1241.         MOV     SI,ES
  1242.         OR      SI,DI
  1243.         JE      @@5
  1244.         TEST    ES:[DI].TPCXButton.State,sfVisible
  1245.         JE      @@4
  1246.         LES     DI,ES:[DI].TGroup.Last
  1247. @@2:    LES     DI,ES:[DI].TPCXButton.Next
  1248.         CMP     CX,DI
  1249.         JNE     @@3
  1250.         MOV     SI,ES
  1251.         CMP     BX,SI
  1252.         JNE     @@3
  1253.         LES     DI,ES:[DI].TPCXButton.Owner
  1254.         JMP     @@1
  1255. @@3:    TEST    ES:[DI].TPCXButton.State,sfVisible
  1256.         JE      @@2
  1257.         MOV     SI,ES:[DI].TPCXButton.Origin.Y
  1258.         CMP     AX,SI
  1259.         JL      @@2
  1260.         ADD     SI,ES:[DI].TPCXButton.Size.Y
  1261.         CMP     AX,SI
  1262.         JGE     @@2
  1263.         MOV     SI,ES:[DI].TPCXButton.Origin.X
  1264.         CMP     DX,SI
  1265.         JL      @@2
  1266.         ADD     SI,ES:[DI].TPCXButton.Size.X
  1267.         CMP     DX,SI
  1268.         JGE     @@2
  1269. @@4:    MOV     CX,2000H
  1270.         JMP     @@6
  1271. @@5:    MOV     DH,AL
  1272.         XOR     BH,BH
  1273.         MOV     AH,2
  1274.         INT     10H
  1275.         MOV     CX,CursorLines
  1276.         LES     DI,Self
  1277.         TEST    ES:[DI].TPCXButton.State,sfCursorIns
  1278.         JE      @@6
  1279.         MOV     CH,0
  1280.         OR      CL,CL
  1281.         JNE     @@6
  1282.         MOV     CL,7
  1283. @@6:    MOV     AH,1
  1284.         INT     10H
  1285. end;
  1286.  
  1287. procedure TPCXButton.DrawCursor;
  1288. begin
  1289.   if State and sfFocused <> 0 then ResetCursor;
  1290. end;
  1291.  
  1292.  
  1293. procedure TPCXButton.DrawView;
  1294. begin
  1295.   if Exposed then
  1296.   begin
  1297.     Draw;
  1298.     DrawCursor;
  1299.   end;
  1300. end;
  1301.  
  1302.  
  1303. END.