home *** CD-ROM | disk | FTP | other *** search
/ Delphi 5 for Professionals / DELPHI5.iso / AddOns / Components / Orpheus v3.02 / SETUP.EXE / %MAINDIR% / OvcSplit.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1999-02-25  |  21.1 KB  |  854 lines

  1. {*********************************************************}
  2. {*                  OVCSPLIT.PAS 3.00                    *}
  3. {*     Copyright 1995-99 (c) TurboPower Software Co      *}
  4. {*                 All rights reserved.                  *}
  5. {*********************************************************}
  6.  
  7. {$I OVC.INC}
  8.  
  9. {$B-} {Complete Boolean Evaluation}
  10. {$I+} {Input/Output-Checking}
  11. {$P+} {Open Parameters}
  12. {$T-} {Typed @ Operator}
  13. {$W-} {Windows Stack Frame}
  14. {$X+} {Extended Syntax}
  15.  
  16. {$IFNDEF Win32}
  17. {$G+} {286 Instructions}
  18. {$N+} {Numeric Coprocessor}
  19.  
  20. {$C MOVEABLE,DEMANDLOAD,DISCARDABLE}
  21. {$ENDIF}
  22.  
  23. unit OvcSplit;
  24.   {-Splitter component}
  25.  
  26. interface
  27.  
  28. uses
  29.   {$IFDEF Win32} Windows, {$ELSE} WinTypes, WinProcs, {$ENDIF}
  30.   SysUtils, Messages, Classes, Graphics, Controls, Forms, Dialogs,
  31.   Buttons, ExtCtrls,
  32.   OvcBase, OvcData;
  33.  
  34. type
  35.   TSplitterOrientation = (soVertical, soHorizontal);
  36.  
  37. type
  38.   {section to act as parent for components}
  39.   TOvcSection = class(TOvcCollectibleControl)
  40.   {.Z+}
  41.   protected {private}
  42.     {windows message response methods}
  43.     procedure WMNCHitTest(var Msg : TWMNCHitTest);
  44.       message WM_NCHITTEST;
  45.   protected
  46.   {$IFNDEF Win32}
  47.     procedure ReadState(Reader : TReader);
  48.       override;
  49.   {$ENDIF}
  50.   public
  51.     constructor Create(AOwner : TComponent);
  52.       override;
  53.   {.Z-}
  54.   published
  55.     property Color;
  56.     property Height stored False;
  57.     property Left stored False;
  58.     property Top stored False;
  59.     property Width stored False;
  60.   end;
  61.  
  62.   TOvcSplitter = class(TOvcCustomControlEx)
  63.   {.Z+}
  64.   protected {private}
  65.     {property variables}
  66.     FAllowResize   : Boolean;
  67.     FAutoScale     : Boolean;
  68.     FAutoUpdate    : Boolean;
  69.     FBorderStyle   : TBorderStyle;
  70.     FOrientation   : TSplitterOrientation;
  71.     FPosition      : Integer;
  72.     FColorLeft     : TColor;
  73.     FColorRight    : TColor;
  74.     FSplitterColor : TColor;
  75.     FSplitterSize  : Integer;
  76.  
  77.     {event variables}
  78.     FOnOwnerDraw   : TNotifyEvent;
  79.     FOnResize      : TNotifyEvent;
  80.  
  81.     {internal variables}
  82.     FPaneColl      : TOvcCollection;
  83.     sCanResize     : Boolean;
  84.     sPos           : TPoint;
  85.  
  86.     {property methods}
  87.     function GetSection(Index : Integer) : TOvcSection;
  88.     procedure SetAutoUpdate(Value : Boolean);
  89.     procedure SetBorderStyle(Value : TBorderStyle);
  90.     procedure SetColorLeft(Value : TColor);
  91.     procedure SetColorRight(Value : TColor);
  92.     procedure SetOrientation(Value : TSplitterOrientation);
  93.     procedure SetPosition(Value : Integer);
  94.     procedure SetSplitterColor(Value : TColor);
  95.     procedure SetSplitterSize(Value : Integer);
  96.  
  97.     {internal methods}
  98.     procedure sDrawSplitter(X, Y : Integer);
  99.     procedure sInvalidateSplitter;
  100.     procedure sSetPositionPrim(Value : Integer);
  101.     procedure sSetSectionInfo;
  102.  
  103.     {VCL control methods}
  104.     procedure CMCtl3DChanged(var Msg : TMessage);
  105.       message CM_CTL3DCHANGED;
  106.     procedure CMDesignHitTest(var Msg : TCMDesignHitTest);
  107.       message CM_DESIGNHITTEST;
  108.  
  109.     {windows message response methods}
  110.     procedure WMEraseBkGnd(var Msg : TWMEraseBkGnd);
  111.       message WM_ERASEBKGND;
  112.     procedure WMSetCursor(var Msg : TWMSetCursor);
  113.       message WM_SETCURSOR;
  114.  
  115.   protected
  116.     procedure CreateParams(var Params : TCreateParams);
  117.       override;
  118.     procedure CreateWnd;
  119.       override;
  120.     procedure DoOnResize;
  121.       dynamic;
  122.     procedure DoOnOwnerDraw;
  123.       virtual;
  124.     procedure Loaded;
  125.       override;
  126.     procedure MouseDown(Button : TMouseButton; Shift : TShiftState; X, Y : Integer);
  127.       override;
  128.     procedure MouseMove(Shift : TShiftState; X, Y : Integer);
  129.       override;
  130.     procedure MouseUp(Button : TMouseButton; Shift : TShiftState; X, Y : Integer);
  131.       override;
  132.     procedure Paint;
  133.       override;
  134.     procedure ReadState(Reader : TReader);
  135.       override;
  136.  
  137.   public
  138.     constructor Create(AOwner : TComponent);
  139.       override;
  140.     destructor Destroy;
  141.       override;
  142.     procedure SetBounds(ALeft, ATop, AWidth, AHeight : Integer);
  143.       override;
  144.   {.Z-}
  145.  
  146.     {public methods}
  147.     procedure Center;
  148.       {-position the splitter bar in the middle of the region}
  149.  
  150.     {public properties}
  151.     property Section[Index : Integer] : TOvcSection
  152.       read GetSection;
  153.  
  154.   published
  155.     {properties}
  156.     property AllowResize : Boolean
  157.       read FAllowResize write FAllowResize;
  158.     property AutoScale : Boolean
  159.       read FAutoScale write FAutoScale;
  160.     property AutoUpdate : Boolean
  161.       read FAutoUpdate write SetAutoUpdate;
  162.   {.Z+}
  163.     property BorderStyle : TBorderStyle
  164.       read FBorderStyle write SetBorderStyle;
  165.   {.Z-}
  166.     property ColorLeft : TColor
  167.       read FColorLeft write SetColorLeft;
  168.     property ColorRight : TColor
  169.       read FColorRight write SetColorRight;
  170.     property Orientation : TSplitterOrientation
  171.       read FOrientation write SetOrientation;
  172.     property Position : Integer
  173.       read FPosition write SetPosition;
  174.     property SplitterColor : TColor
  175.       read FSplitterColor write SetSplitterColor;
  176.     property SplitterSize : Integer
  177.       read FSplitterSize write SetSplitterSize;
  178.  
  179.     {events}
  180.     property OnOwnerDraw : TNotifyEvent
  181.       read FOnOwnerDraw write FOnOwnerDraw;
  182.     property OnResize : TNotifyEvent
  183.       read FOnResize write FOnResize;
  184.  
  185.     {inherited properties}
  186.     {$IFDEF VERSION4}
  187.     property Anchors;
  188.     property Constraints;
  189.     {$ENDIF}
  190.     property Align;
  191.     property Color;
  192.     property Ctl3D;
  193.     property Enabled;
  194.     property ParentCtl3D;
  195.     property ParentShowHint;
  196.     property ShowHint;
  197.     property Visible;
  198.   end;
  199.  
  200.  
  201. implementation
  202.  
  203.  
  204. {*** TOvcSection ***}
  205.  
  206. constructor TOvcSection.Create(AOwner : TComponent);
  207. begin
  208.   inherited Create(AOwner);
  209.   ControlStyle := ControlStyle + [csAcceptsControls];
  210.   ParentCtl3D := True;
  211.   Color := clBtnFace;
  212.   Parent := TWinControl(AOwner);
  213. end;
  214.  
  215. {$IFNDEF Win32}
  216. procedure TOvcSection.ReadState(Reader : TReader);
  217. var
  218.   PF : TForm;
  219. var
  220.   OldOwner : TComponent;
  221.   I        : Integer;
  222.   TC       : TControl;
  223. begin
  224.   PF := TForm(GetParentForm(TOvcSplitter(Owner)));
  225.   OldOwner := Reader.Owner;
  226.   Reader.Owner := PF;
  227.   inherited ReadState(Reader);
  228.   Reader.Owner := OldOwner;
  229. end;
  230. {$ENDIF}
  231.  
  232. procedure TOvcSection.WMNCHitTest(var Msg : TWMNCHitTest);
  233. begin
  234.   if not (csDesigning in ComponentState) then
  235.     Msg.Result := HTTRANSPARENT
  236.   else
  237.     inherited;
  238. end;
  239.  
  240.  
  241. {*** TOvcSplitter ***}
  242.  
  243. procedure TOvcSplitter.Center;
  244. begin
  245.   case Orientation of
  246.     soHorizontal : Position := (ClientHeight - FSplitterSize) div 2;
  247.     soVertical   : Position := (ClientWidth - FSplitterSize) div 2;
  248.   end;
  249. end;
  250.  
  251. procedure TOvcSplitter.CMCtl3DChanged(var Msg : TMessage);
  252. begin
  253.   inherited;
  254.  
  255.   if (csLoading in ComponentState) then
  256.     Exit;
  257.  
  258.   {update section size and position}
  259.   sSetSectionInfo;
  260.  
  261.   Refresh;
  262. end;
  263.  
  264. procedure TOvcSplitter.CMDesignHitTest(var Msg : TCMDesignHitTest);
  265. begin
  266.   if sCanResize then
  267.     Msg.Result := 1
  268.   else
  269.     inherited;
  270. end;
  271.  
  272. constructor TOvcSplitter.Create(AOwner: TComponent);
  273. begin
  274.   inherited Create(AOwner);
  275.  
  276.   FPaneColl := TOvcCollection.Create(Self, TOvcSection);
  277.  
  278.   Ctl3D  := True;
  279.   Height := 100;
  280.   Width  := 200;
  281.  
  282.   if Classes.GetClass(TOvcSection.ClassName) = nil then
  283.     Classes.RegisterClass(TOvcSection);
  284.  
  285.   FPaneColl.Add.Name := 'SPL1';
  286.   FPaneColl.Add.Name := 'SPL2';
  287.  
  288.   FAllowResize   := True;
  289.   FAutoScale     := True;
  290.   FAutoUpdate    := False;
  291.   FBorderStyle   := bsNone;
  292.   FOrientation   := soVertical;
  293.   FPosition      := 200 div 2;
  294.   FSplitterColor := clWindowText;
  295.   FSplitterSize  := 3;
  296.  
  297.   sPos.X := -1;
  298.   sPos.Y := -1;
  299. end;
  300.  
  301. procedure TOvcSplitter.CreateParams(var Params : TCreateParams);
  302. begin
  303.   inherited CreateParams(Params);
  304.  
  305.   Params.Style := LongInt(Params.Style) or BorderStyles[FBorderStyle];
  306. end;
  307.  
  308. procedure TOvcSplitter.CreateWnd;
  309. begin
  310.   inherited CreateWnd;
  311.  
  312.   {update section size and position}
  313.   sSetSectionInfo;
  314. end;
  315.  
  316. destructor TOvcSplitter.Destroy;
  317. begin
  318.   Parent := nil;
  319.   FPaneColl.Free;
  320.  
  321.   inherited Destroy;
  322. end;
  323.  
  324. procedure TOvcSplitter.DoOnOwnerDraw;
  325. begin
  326.   if Assigned(FOnOwnerDraw) then
  327.     FOnOwnerDraw(Self);
  328. end;
  329.  
  330. procedure TOvcSplitter.DoOnResize;
  331. begin
  332.   if Assigned(FOnResize) then
  333.     FOnResize(Self);
  334. end;
  335.  
  336. function TOvcSplitter.GetSection(Index : Integer) : TOvcSection;
  337. begin
  338.   if (Index < 0) or (FPaneColl = nil) or (Index >= FPaneColl.Count) then
  339.     Result := nil
  340.   else
  341.     Result := TOvcSection(FPaneColl.Item[Index]);
  342. end;
  343.  
  344. procedure TOvcSplitter.Loaded;
  345. begin
  346.   inherited Loaded;
  347. end;
  348.  
  349. procedure TOvcSplitter.MouseDown(Button : TMouseButton; Shift : TShiftState; X, Y : Integer);
  350. var
  351.   Delta : Integer;
  352. begin
  353.   inherited MouseDown(Button, Shift, X, Y);
  354.  
  355.   if sCanResize then begin
  356.     if (Button = mbLeft) then begin
  357.       case Orientation of
  358.         soHorizontal : Delta := FPosition - Y;
  359.         soVertical   : Delta := FPosition - X;
  360.       else
  361.         Delta := 0;
  362.       end;
  363.       if Abs(Delta) < FSplitterSize then begin
  364.         SetCapture(Handle);
  365.         sDrawSplitter(X, Y);
  366.       end;
  367.     end;
  368.   end;
  369. end;
  370.  
  371. procedure TOvcSplitter.MouseMove(Shift : TShiftState; X, Y : Integer);
  372. begin
  373.   inherited MouseMove(Shift, X, Y);
  374.  
  375.   case Orientation of
  376.     soHorizontal :
  377.       if (Y < 0) or (Y > ClientHeight) or (Y = FPosition) then
  378.         Exit;
  379.     soVertical   :
  380.       if (X < 0) or (X > ClientWidth) or (X = FPosition) then
  381.         Exit;
  382.   end;
  383.  
  384.   if (GetCapture = Handle) and sCanResize then begin
  385.     sDrawSplitter(X, Y);
  386.  
  387.     if AutoUpdate then
  388.       {update section size and position}
  389.       sSetSectionInfo;
  390.   end;
  391. end;
  392.  
  393. procedure TOvcSplitter.MouseUp(Button : TMouseButton; Shift : TShiftState; X, Y : Integer);
  394. begin
  395.   if sCanResize then begin
  396.     ReleaseCapture;
  397.     sCanResize := False;
  398.     sDrawSplitter(-1, -1); {erase}
  399.  
  400.     {update Section size and position}
  401.     sSetSectionInfo;
  402.     Refresh;
  403.  
  404.     DoOnResize;
  405.   end;
  406.  
  407.   inherited MouseUp(Button, Shift, X, Y);
  408. end;
  409.  
  410. procedure TOvcSplitter.Paint;
  411. var
  412.   P, P1  : Integer;
  413.   S, S1  : Integer;
  414.   CW, CH : Integer;
  415.   Split0,
  416.   Split1 : Boolean;
  417. begin
  418.   {update section size and position}
  419.   sSetSectionInfo;
  420.  
  421.   if Assigned(FOnOwnerDraw) then begin
  422.     DoOnOwnerDraw;
  423.     Exit;
  424.   end;
  425.  
  426.   P  := Position;
  427.   P1 := Position-1;
  428.   CW := ClientWidth;
  429.   CH := ClientHeight;
  430.   S  := FSplitterSize;
  431.   S1 := FSplitterSize-1;
  432.  
  433.   if not Ctl3D then begin
  434.     Canvas.Pen.Color := SplitterColor;
  435.     Canvas.Brush.Color := SplitterColor;
  436.     case Orientation of
  437.       soHorizontal : Canvas.Rectangle(0, P, CW, P+S);
  438.       soVertical   : Canvas.Rectangle(P, 0, P+S, CH);
  439.     end;
  440.     Exit;
  441.   end;
  442.  
  443.   Canvas.Brush.Color := Color;
  444.  
  445.   Split0 := (Section[0] <> nil) and (Section[0].ControlCount > 0) and
  446.     (Section[0].Controls[0] is TOvcSplitter)
  447.     and (Section[0].Controls[0].Align = alClient);
  448.   Split1 := (Section[1] <> nil) and (Section[1].ControlCount > 0) and
  449.     (Section[1].Controls[0] is TOvcSplitter)
  450.     and (Section[1].Controls[0].Align = alClient);
  451.  
  452.   {draw highlight border (right and bottom of each section)}
  453.   Canvas.Pen.Color := clBtnHighlight;
  454.   case Orientation of
  455.     soHorizontal :
  456.       begin
  457.         if not Split0 then
  458.           Canvas.PolyLine([Point(0, P1),
  459.                          Point(CW-1, P1),
  460.                         Point(CW-1, 0)]);
  461.         if not Split1 then
  462.           Canvas.PolyLine([Point(0, CH-1),
  463.                          Point(CW-1, CH-1),
  464.                          Point(CW-1, P+S1)]);
  465.       end;
  466.     soVertical   :
  467.       begin
  468.         if not Split0 then
  469.           Canvas.PolyLine([Point(0, CH-1),
  470.                          Point(P1, CH-1),
  471.                          Point(P1, 0)]);
  472.         if not Split1 then
  473.           Canvas.PolyLine([Point(P+S1, CH-1),
  474.                          Point(CW-1, CH-1),
  475.                          Point(CW-1, 0)]);
  476.       end;
  477.   end;
  478.  
  479.   {draw shadow border (left and top of each section)}
  480.   Canvas.Pen.Color := clBtnShadow;
  481.   case Orientation of
  482.     soHorizontal :
  483.       begin
  484.         if not Split0 then
  485.           Canvas.PolyLine([Point(0, P1-1),
  486.                          Point(0, 0),
  487.                          Point(CW-1, 0)]);
  488.         if not Split1 then
  489.           Canvas.PolyLine([Point(0, CH-2),
  490.                          Point(0, P+S),
  491.                          Point(CW-1, P+S)]);
  492.       end;
  493.     soVertical   :
  494.       begin
  495.         if not Split0 then
  496.           Canvas.PolyLine([Point(0, CH-2),
  497.                          Point(0, 0),
  498.                          Point(P1 + 1, 0)]);
  499.         if not Split1 then
  500.           Canvas.PolyLine([Point(P+S, CH-2),
  501.                          Point(P+S, 0),
  502.                          Point(CW-1, 0)]);
  503.       end;
  504.   end;
  505.  
  506.   {draw border (left and top of each section)}
  507.   Canvas.Pen.Color := clBlack;
  508.   case Orientation of
  509.     soHorizontal :
  510.       begin
  511.         if not Split0 then
  512.           Canvas.PolyLine([Point(1, P1-1),
  513.                          Point(1, 1),
  514.                          Point(CW-1, 1)]);
  515.         if not Split1 then
  516.           Canvas.PolyLine([Point(1, CH-2),
  517.                          Point(1, P+S+1),
  518.                          Point(CW-1, P+S+1)]);
  519.       end;
  520.     soVertical   :
  521.       begin
  522.         if not Split0 then
  523.           Canvas.PolyLine([Point(1, CH-2),
  524.                          Point(1, 1),
  525.                          Point(P-1, 1)]);
  526.         if not Split1 then
  527.           Canvas.PolyLine([Point(P+S+1, CH-2),
  528.                          Point(P+S+1, 1),
  529.                          Point(CW-1, 1)]);
  530.       end;
  531.   end;
  532.  
  533.   {draw splitter bar}
  534.   Canvas.Pen.Color := Color;
  535.   Canvas.Brush.Color := Color;
  536.   case Orientation of
  537.     soHorizontal :
  538.       Canvas.Rectangle(0, P, CW, P+S);
  539.     soVertical   :
  540.       Canvas.Rectangle(P, 0, P+S, CH);
  541.   end;
  542. end;
  543.  
  544. procedure TOvcSplitter.ReadState(Reader : TReader);
  545. begin
  546.   FPaneColl.Clear;
  547.   inherited ReadState(Reader);
  548. end;
  549.  
  550. procedure TOvcSplitter.sDrawSplitter(X, Y : Integer);
  551. begin
  552.   if AutoUpdate and (X > -1) and (Y > -1) then begin
  553.     sInvalidateSplitter;
  554.     case Orientation of
  555.       soHorizontal : sSetPositionPrim(Y);
  556.       soVertical   : sSetPositionPrim(X);
  557.     end;
  558.     sInvalidateSplitter;
  559.     Exit;
  560.   end;
  561.  
  562.  
  563.   {do we need to erase first?}
  564.   if (sPos.X > -1) or (sPos.Y > -1) then begin
  565.     case Orientation of
  566.       soHorizontal :
  567.         PatBlt(Canvas.Handle, 0, sPos.Y, ClientWidth, FSplitterSize - 1, DSTINVERT);
  568.       soVertical   :
  569.         PatBlt(Canvas.Handle, sPos.X, 0, FSplitterSize - 1, ClientHeight, DSTINVERT);
  570.     end;
  571.   end;
  572.  
  573.   {record new position}
  574.   sPos.X := X;
  575.   sPos.Y := Y;
  576.  
  577.   if not sCanResize then
  578.     Exit;
  579.  
  580.   case Orientation of
  581.     soHorizontal :
  582.       begin
  583.         sSetPositionPrim(sPos.Y);
  584.         sPos.Y := Position;
  585.         PatBlt(Canvas.Handle, 0, FPosition, ClientWidth, FSplitterSize - 1, DSTINVERT);
  586.       end;
  587.     soVertical   :
  588.       begin
  589.         sSetPositionPrim(sPos.X);
  590.         sPos.X := Position;
  591.         PatBlt(Canvas.Handle, FPosition, 0, FSplitterSize - 1, ClientHeight, DSTINVERT);
  592.       end;
  593.   end;
  594. end;
  595.  
  596. procedure TOvcSplitter.SetBounds(ALeft, ATop, AWidth, AHeight : Integer);
  597. var
  598.   P : Double;
  599. begin
  600.   if FAutoScale and not (csLoading in ComponentState) then begin
  601.     P := Position;
  602.     case Orientation of
  603.       soHorizontal :
  604.         if (Height <> 0) and (AHeight <> 0) then
  605.           Position := Round(P / Height * AHeight)
  606.         else
  607.           Position := 0;
  608.       soVertical   :
  609.         if (Width <> 0) and (AWidth <> 0) then
  610.           Position := Round(P / Width * AWidth)
  611.         else
  612.           Position := 0;
  613.     end;
  614.   end;
  615.  
  616.   inherited SetBounds(ALeft, ATop, AWidth, AHeight);
  617. end;
  618.  
  619. procedure TOvcSplitter.sInvalidateSplitter;
  620. var
  621.   R : TRect;
  622. begin
  623.   case Orientation of
  624.     soHorizontal : R := Rect(0, Position-2, ClientWidth, Position+FSplitterSize+2);
  625.     soVertical   : R := Rect(Position-2, 0, Position+FSplitterSize+2, ClientHeight);
  626.   end;
  627.   InvalidateRect(Handle, @R, True);
  628.   if Handle <> 0 then {};
  629. end;
  630.  
  631. procedure TOvcSplitter.SetAutoUpdate(Value : Boolean);
  632. begin
  633.   if (Value <> FAutoUpdate) then
  634.     FAutoUpdate := Value;
  635. end;
  636.  
  637. procedure TOvcSplitter.SetBorderStyle(Value : TBorderStyle);
  638. begin
  639.   if (Value <> FBorderStyle) then begin
  640.     FBorderStyle := Value;
  641.     RecreateWnd;
  642.   end;
  643. end;
  644.  
  645. procedure TOvcSplitter.SetOrientation(Value : TSplitterOrientation);
  646. begin
  647.   if (Value <> FOrientation) then begin
  648.     FOrientation := Value;
  649.  
  650.     if (csLoading in ComponentState) then
  651.       Exit;
  652.  
  653.     if not HandleAllocated then
  654.       Exit;
  655.  
  656.     {force position to readjust}
  657.     sSetPositionPrim(FPosition);
  658.  
  659.     {update Section size and position}
  660.     sSetSectionInfo;
  661.     Refresh;
  662.   end;
  663. end;
  664.  
  665. procedure TOvcSplitter.SetPosition(Value : Integer);
  666. begin
  667.   if (csLoading in ComponentState)
  668.   or not HandleAllocated then begin
  669.     FPosition := Value;
  670.     Exit;
  671.   end;
  672.  
  673.   sSetPositionPrim(Value);
  674.   Refresh;
  675.  
  676.   DoOnResize;
  677. end;
  678.  
  679. procedure TOvcSplitter.SetSplitterColor(Value : TColor);
  680. begin
  681.   {color to use if not Ctl3D}
  682.   if (Value <> FSplitterColor) then begin
  683.     FSplitterColor := Value;
  684.     Refresh;
  685.   end;
  686. end;
  687.  
  688. procedure TOvcSplitter.SetSplitterSize(Value : Integer);
  689. begin
  690.   if (Value <> FSplitterSize) then begin
  691.     FSplitterSize := Value;
  692.  
  693.     if (csLoading in ComponentState) then
  694.       Exit;
  695.  
  696.     if not HandleAllocated then
  697.       Exit;
  698.  
  699.     {update Section size and position}
  700.     sSetSectionInfo;
  701.     Refresh;
  702.   end;
  703. end;
  704.  
  705. procedure TOvcSplitter.sSetPositionPrim(Value : Integer);
  706. var
  707.   MinPos : Integer;
  708.   MaxPos : Integer;
  709.   PF     : TForm;
  710. begin
  711.   MinPos := 1;
  712.   case Orientation of
  713.     soHorizontal :
  714.       begin
  715.         MaxPos := ClientHeight - FSplitterSize - 2;
  716.         if Value < MinPos then
  717.           Value := MinPos;
  718.         if Value > MaxPos then
  719.           Value := MaxPos;
  720.         FPosition := Value;
  721.       end;
  722.     soVertical :
  723.       begin
  724.         MaxPos := ClientWidth - FSplitterSize - 2;
  725.         if Value < MinPos then
  726.           Value := MinPos;
  727.         if Value > MaxPos then
  728.           Value := MaxPos;
  729.         FPosition := Value;
  730.       end;
  731.   end;
  732.  
  733.   {notify the designer of the change}
  734.   if not AutoScale and (csDesigning in ComponentState) then begin
  735.     PF := TForm(GetParentForm(Self));
  736.     if Assigned(PF) and (PF.Designer <> nil) then
  737.       PF.Designer.Modified;
  738.   end;
  739. end;
  740.  
  741. procedure TOvcSplitter.sSetSectionInfo;
  742. var
  743.   P      : Integer;
  744.   S      : Integer;
  745.   CW, CH : Integer;
  746.   Split0,
  747.   Split1 : Boolean;
  748. begin
  749.   if (csLoading in ComponentState) then
  750.     Exit;
  751.  
  752.   if not HandleAllocated then
  753.     Exit;
  754.  
  755.   if Section[0] = nil then exit;
  756.  
  757.   P  := Position;
  758.   CW := ClientWidth;
  759.   CH := ClientHeight;
  760.   S  := FSplitterSize;
  761.  
  762.   Split0 := (Section[0] <> nil) and (Section[0].ControlCount > 0) and
  763.     (Section[0].Controls[0] is TOvcSplitter)
  764.     and (Section[0].Controls[0].Align = alClient);
  765.   Split1 := (Section[1] <> nil) and (Section[1].ControlCount > 0) and
  766.     (Section[1].Controls[0] is TOvcSplitter)
  767.     and (Section[1].Controls[0].Align = alClient);
  768.  
  769.   if Ctl3D then begin
  770.     case Orientation of
  771.       soHorizontal :
  772.         begin
  773.           if Split0 then
  774.             Section[0].SetBounds(0, 0, CW, P)
  775.           else
  776.             Section[0].SetBounds(2, 2, CW-3, P-3);
  777.           if Split1 then
  778.             Section[1].SetBounds(0, P+S, CW, CH-P-S)
  779.           else
  780.             Section[1].SetBounds(2, P+S+2, CW-3, CH-P-S-3);
  781.         end;
  782.       soVertical :
  783.         begin
  784.           if Split0 then
  785.             Section[0].SetBounds(0, 0, P, CH)
  786.           else
  787.             Section[0].SetBounds(2, 2, P-3, CH-3);
  788.           if Split1 then
  789.             Section[1].SetBounds(P+S, 0, CW-P-S, CH)
  790.           else
  791.             Section[1].SetBounds(P+S+2, 2, CW-P-S-3, CH-3);
  792.         end;
  793.     end;
  794.   end else begin
  795.     case Orientation of
  796.       soHorizontal :
  797.         begin
  798.           Section[0].SetBounds(0, 0, CW, P);
  799.           Section[1].SetBounds(0, P+S, CW, CH-P-S);
  800.         end;
  801.       soVertical :
  802.         begin
  803.           Section[0].SetBounds(0, 0, P, CH);
  804.           Section[1].SetBounds(P+S, 0, CW-P-S, CH);
  805.         end;
  806.     end;
  807.   end;
  808. end;
  809.  
  810. procedure TOvcSplitter.WMEraseBkGnd(var Msg : TWMEraseBkGnd);
  811. begin
  812.   Msg.Result := 1  {don't erase background}
  813. end;
  814.  
  815. procedure TOvcSplitter.WMSetCursor(var Msg : TWMSetCursor);
  816. var
  817.   Cur : hCursor;
  818.   P   : TPoint;
  819. begin
  820.   Cur := 0;
  821.  
  822.   if Msg.HitTest = HTCLIENT then begin
  823.     GetCursorPos(P);
  824.     P := ScreenToClient(P);
  825.     {are we over the split region?}
  826.     case Orientation of
  827.       soHorizontal : if Abs(Position - P.Y) <= FSplitterSize then
  828.         Cur := Screen.Cursors[crVSplit];
  829.       soVertical   : if Abs(Position - P.X) <= FSplitterSize then
  830.         Cur := Screen.Cursors[crHSplit];
  831.     end;
  832.   end;
  833.  
  834.   sCanResize := (FAllowResize or (csDesigning in ComponentState)) and (Cur <> 0);
  835.   if sCanResize then
  836.     SetCursor(Cur)
  837.   else
  838.     inherited;
  839. end;
  840.  
  841. procedure TOvcSplitter.SetColorLeft(Value: TColor);
  842. begin
  843.   if Section[0] <> nil then
  844.     Section[0].Color := Value;
  845. end;
  846.  
  847. procedure TOvcSplitter.SetColorRight(Value: TColor);
  848. begin
  849.   if Section[1] <> nil then
  850.     Section[1].Color := Value;
  851. end;
  852.  
  853. end.
  854.