home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 September / Chip_2001-09_cd1.bin / zkuste / delphi / kolekce / d6 / RX275D6.ZIP / Units / Rxslider.pas < prev    next >
Pascal/Delphi Source File  |  1999-10-12  |  36KB  |  1,204 lines

  1. {*******************************************************}
  2. {                                                       }
  3. {         Delphi VCL Extensions (RX)                    }
  4. {                                                       }
  5. {         Copyright (c) 1995, 1996 AO ROSNO             }
  6. {         Copyright (c) 1997, 1998 Master-Bank          }
  7. {                                                       }
  8. {*******************************************************}
  9.  
  10. unit RXSlider;
  11.  
  12. interface
  13.  
  14. {$I RX.INC}
  15.  
  16. uses {$IFDEF WIN32} Windows, {$ELSE} WinTypes, WinProcs, {$ENDIF}
  17.   Controls, ExtCtrls, Classes, Graphics, Messages, Menus;
  18.  
  19. type
  20.   TNumThumbStates = 1..2;
  21.   TSliderOrientation = (soHorizontal, soVertical);
  22.   TSliderOption = (soShowFocus, soShowPoints, soSmooth,
  23.     soRulerOpaque, soThumbOpaque);
  24.   TSliderOptions = set of TSliderOption;
  25.   TSliderImage = (siHThumb, siHRuler, siVThumb, siVRuler);
  26.   TSliderImages = set of TSliderImage;
  27.   TSliderImageArray = array[TSliderImage] of TBitmap;
  28.   TJumpMode = (jmNone, jmHome, jmEnd, jmNext, jmPrior);
  29.  
  30. { TRxCustomSlider }
  31.  
  32.   TRxCustomSlider = class(TCustomControl)
  33.   private
  34.     FUserImages: TSliderImages;
  35.     FImages: TSliderImageArray;
  36.     FEdgeSize: Integer;
  37.     FRuler: TBitmap;
  38.     FPaintBuffered: Boolean;
  39.     FRulerOrg: TPoint;
  40.     FThumbRect: TRect;
  41.     FThumbDown: Boolean;
  42.     FNumThumbStates: TNumThumbStates;
  43.     FPointsRect: TRect;
  44.     FOrientation: TSliderOrientation;
  45.     FOptions: TSliderOptions;
  46.     FBevelStyle: TPanelBevel;
  47.     FBevelWidth: Integer;
  48.     FMinValue: Longint;
  49.     FMaxValue: Longint;
  50.     FIncrement: Longint;
  51.     FValue: Longint;
  52.     FHit: Integer;
  53.     FFocused: Boolean;
  54.     FSliding: Boolean;
  55.     FTracking: Boolean;
  56.     FTimerActive: Boolean;
  57.     FMousePos: TPoint;
  58.     FStartJump: TJumpMode;
  59.     FReadOnly: Boolean;
  60.     FOnChange: TNotifyEvent;
  61.     FOnChanged: TNotifyEvent;
  62.     FOnDrawPoints: TNotifyEvent;
  63.     function GetImage(Index: Integer): TBitmap;
  64.     procedure SetImage(Index: Integer; Value: TBitmap);
  65.     procedure SliderImageChanged(Sender: TObject);
  66.     procedure SetEdgeSize(Value: Integer);
  67.     function GetNumThumbStates: TNumThumbStates;
  68.     procedure SetNumThumbStates(Value: TNumThumbStates);
  69.     procedure SetBevelStyle(Value: TPanelBevel);
  70.     procedure SetOrientation(Value: TSliderOrientation);
  71.     procedure SetOptions(Value: TSliderOptions);
  72.     procedure SetMinValue(Value: Longint);
  73.     procedure SetMaxValue(Value: Longint);
  74.     procedure SetIncrement(Value: Longint);
  75.     procedure SetReadOnly(Value: Boolean);
  76.     function GetThumbOffset: Integer;
  77.     procedure SetThumbOffset(Value: Integer);
  78.     procedure SetValue(Value: Longint);
  79.     procedure ThumbJump(Jump: TJumpMode);
  80.     function GetThumbPosition(var Offset: Integer): TPoint;
  81.     function JumpTo(X, Y: Integer): TJumpMode;
  82.     procedure InvalidateThumb;
  83.     procedure StopTracking;
  84.     procedure TimerTrack;
  85.     function StoreImage(Index: Integer): Boolean;
  86.     procedure CreateElements;
  87.     procedure BuildRuler(R: TRect);
  88.     procedure AdjustElements;
  89.     procedure ReadUserImages(Stream: TStream);
  90.     procedure WriteUserImages(Stream: TStream);
  91.     procedure InternalDrawPoints(ACanvas: TCanvas; PointsStep, PointsHeight,
  92.       ExtremePointsHeight: Longint);
  93.     procedure DrawThumb(Canvas: TCanvas; Origin: TPoint; Highlight: Boolean);
  94.     function GetValueByOffset(Offset: Integer): Longint;
  95.     function GetOffsetByValue(Value: Longint): Integer;
  96.     function GetRulerLength: Integer;
  97.     procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
  98.     procedure CMFocusChanged(var Message: TCMFocusChanged); message CM_FOCUSCHANGED;
  99.     procedure WMGetDlgCode(var Msg: TWMGetDlgCode); message WM_GETDLGCODE;
  100.     procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
  101.     procedure WMSetCursor(var Message: TWMSetCursor); message WM_SETCURSOR;
  102.     procedure WMSize(var Message: TWMSize); message WM_SIZE;
  103.     procedure WMTimer(var Message: TMessage); message WM_TIMER;
  104.   protected
  105.     procedure AlignControls(AControl: TControl; var Rect: TRect); override;
  106.     procedure DefineProperties(Filer: TFiler); override;
  107.     procedure KeyDown(var Key: Word; Shift: TShiftState); override;
  108.     procedure Loaded; override;
  109.     procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
  110.       X, Y: Integer); override;
  111.     procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
  112.     procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
  113.       X, Y: Integer); override;
  114.     procedure Paint; override;
  115.     function CanModify: Boolean; virtual;
  116.     function GetSliderRect: TRect; virtual;
  117.     function GetSliderValue: Longint; virtual;
  118.     procedure Change; dynamic;
  119.     procedure Changed; dynamic;
  120.     procedure Sized; virtual;
  121.     procedure RangeChanged; virtual;
  122.     procedure SetRange(Min, Max: Longint);
  123.     procedure ThumbMouseDown(Button: TMouseButton; Shift: TShiftState;
  124.       X, Y: Integer); virtual;
  125.     procedure ThumbMouseMove(Shift: TShiftState; X, Y: Integer); virtual;
  126.     procedure ThumbMouseUp(Button: TMouseButton; Shift: TShiftState;
  127.       X, Y: Integer); virtual;
  128.     property ThumbOffset: Integer read GetThumbOffset write SetThumbOffset;
  129.     property SliderRect: TRect read GetSliderRect;
  130.     property BevelStyle: TPanelBevel read FBevelStyle write SetBevelStyle
  131.       default bvNone;
  132.     property ImageHThumb: TBitmap index Ord(siHThumb) read GetImage
  133.       write SetImage stored StoreImage;
  134.     property ImageHRuler: TBitmap index Ord(siHRuler) read GetImage
  135.       write SetImage  stored StoreImage;
  136.     property ImageVThumb: TBitmap index Ord(siVThumb) read GetImage
  137.       write SetImage stored StoreImage;
  138.     property ImageVRuler: TBitmap index Ord(siVRuler) read GetImage
  139.       write SetImage stored StoreImage;
  140.     property NumThumbStates: TNumThumbStates read GetNumThumbStates
  141.       write SetNumThumbStates default 2;
  142.     property Orientation: TSliderOrientation read FOrientation
  143.       write SetOrientation default soHorizontal;
  144.     property EdgeSize: Integer read FEdgeSize write SetEdgeSize default 2;
  145.     property Options: TSliderOptions read FOptions write SetOptions
  146.       default [soShowFocus, soShowPoints, soSmooth];
  147.     property ReadOnly: Boolean read FReadOnly write SetReadOnly default False;
  148.     property OnChange: TNotifyEvent read FOnChange write FOnChange;
  149.     property OnChanged: TNotifyEvent read FOnChanged write FOnChanged;
  150.     property OnDrawPoints: TNotifyEvent read FOnDrawPoints write FOnDrawPoints;
  151.   public
  152.     constructor Create(AOwner: TComponent); override;
  153.     destructor Destroy; override;
  154.     procedure DefaultDrawPoints(PointsStep, PointsHeight,
  155.       ExtremePointsHeight: Longint); virtual;
  156.     property Canvas;
  157.     property Increment: Longint read FIncrement write SetIncrement default 10;
  158.     property MinValue: Longint read FMinValue write SetMinValue default 0;
  159.     property MaxValue: Longint read FMaxValue write SetMaxValue default 100;
  160.     property Value: Longint read FValue write SetValue default 0;
  161.   end;
  162.  
  163. { TRxSlider }
  164.  
  165.   TRxSlider = class(TRxCustomSlider)
  166.   published
  167.     property Align;
  168.     property BevelStyle;
  169.     property Color;
  170.     property Cursor;
  171.     property DragMode;
  172.     property DragCursor;
  173.     property Enabled;
  174.     property ImageHThumb;
  175.     property ImageHRuler;
  176.     property ImageVThumb;
  177.     property ImageVRuler;
  178.     property Increment;
  179.     property MinValue;
  180.     property MaxValue;
  181.     property NumThumbStates;
  182.     property Orientation;
  183.     { ensure Orientation is published before EdgeSize }
  184.     property EdgeSize;
  185.     property Options;
  186.     property ParentColor;
  187.     property ParentShowHint;
  188.     property PopupMenu;
  189.     property ShowHint;
  190.     property TabOrder;
  191.     property TabStop default True;
  192.     property Value;
  193.     property Visible;
  194. {$IFDEF RX_D4}
  195.     property Anchors;
  196.     property Constraints;
  197.     property DragKind;
  198. {$ENDIF}
  199.     property OnChange;
  200.     property OnChanged;
  201.     property OnDrawPoints;
  202.     property OnClick;
  203.     property OnDblClick;
  204.     property OnEnter;
  205.     property OnExit;
  206.     property OnMouseMove;
  207.     property OnMouseDown;
  208.     property OnMouseUp;
  209.     property OnKeyDown;
  210.     property OnKeyUp;
  211.     property OnKeyPress;
  212.     property OnDragOver;
  213.     property OnDragDrop;
  214.     property OnEndDrag;
  215. {$IFDEF WIN32}
  216.     property OnStartDrag;
  217. {$ENDIF}
  218. {$IFDEF RX_D5}
  219.     property OnContextPopup;
  220. {$ENDIF}
  221. {$IFDEF RX_D4}
  222.     property OnMouseWheelDown;
  223.     property OnMouseWheelUp;
  224.     property OnEndDock;
  225.     property OnStartDock;
  226. {$ENDIF}
  227.   end;
  228.  
  229. { TRxCustomTrackBar }
  230.  
  231.   TRxSliderImages = class;
  232.  
  233.   TRxCustomTrackBar = class(TRxCustomSlider)
  234.   private
  235.     FImages: TRxSliderImages;
  236.   protected
  237.     property Images: TRxSliderImages read FImages write FImages;
  238.   public
  239.     constructor Create(AOwner: TComponent); override;
  240.     destructor Destroy; override;
  241.   end;
  242.  
  243.   TRxSliderImages = class(TPersistent)
  244.   private
  245.     FSlider: TRxCustomSlider;
  246.     function GetNumThumbStates: TNumThumbStates;
  247.     procedure SetNumThumbStates(Value: TNumThumbStates);
  248.     function GetEdgeSize: Integer;
  249.     procedure SetEdgeSize(Value: Integer);
  250.     function GetImage(Index: Integer): TBitmap;
  251.     procedure SetImage(Index: Integer; Value: TBitmap);
  252.     function StoreImage(Index: Integer): Boolean;
  253.   published
  254.     property HorzThumb: TBitmap index Ord(siHThumb) read GetImage
  255.       write SetImage stored StoreImage;
  256.     property HorzRuler: TBitmap index Ord(siHRuler) read GetImage
  257.       write SetImage stored StoreImage;
  258.     property VertThumb: TBitmap index Ord(siVThumb) read GetImage
  259.       write SetImage stored StoreImage;
  260.     property VertRuler: TBitmap index Ord(siVRuler) read GetImage
  261.       write SetImage stored StoreImage;
  262.     property NumThumbStates: TNumThumbStates read GetNumThumbStates
  263.       write SetNumThumbStates default 2;
  264.     property EdgeSize: Integer read GetEdgeSize write SetEdgeSize default 2;
  265.   end;
  266.  
  267. implementation
  268.  
  269. uses Consts, Forms, SysUtils, VCLUtils, MaxMin, RxConst;
  270.  
  271. {$IFDEF WIN32}
  272.  {$R *.R32}
  273. {$ELSE}
  274.  {$R *.R16}
  275. {$ENDIF}
  276.  
  277. const
  278.   ImagesResNames: array[TSliderImage] of PChar =
  279.     ('W95_HTB', 'W95_HRL', 'W95_VTB', 'W95_VRL');
  280.   Indent = 6;
  281.   JumpInterval = 400;
  282.  
  283. { TRxCustomSlider }
  284.  
  285. constructor TRxCustomSlider.Create(AOwner: TComponent);
  286. begin
  287.   inherited Create(AOwner);
  288.   ControlState := ControlState + [csCreating];
  289.   ControlStyle := [csClickEvents, csCaptureMouse, csAcceptsControls,
  290.     csDoubleClicks, csOpaque];
  291.   Width := 150;
  292.   Height := 40;
  293.   FNumThumbStates := 2;
  294.   FBevelWidth := 1;
  295.   FOrientation := soHorizontal;
  296.   FOptions := [soShowFocus, soShowPoints, soSmooth];
  297.   FEdgeSize := 2;
  298.   FMinValue := 0;
  299.   FMaxValue := 100;
  300.   FIncrement := 10;
  301.   TabStop := True;
  302.   CreateElements;
  303.   ControlState := ControlState - [csCreating];
  304. end;
  305.  
  306. destructor TRxCustomSlider.Destroy;
  307. var
  308.   I: TSliderImage;
  309. begin
  310.   FOnChange := nil;
  311.   FOnChanged := nil;
  312.   FOnDrawPoints := nil;
  313.   FRuler.Free;
  314.   for I := Low(FImages) to High(FImages) do begin
  315.     FImages[I].OnChange := nil;
  316.     FImages[I].Free;
  317.   end;
  318.   inherited Destroy;
  319. end;
  320.  
  321. procedure TRxCustomSlider.Loaded;
  322. var
  323.   I: TSliderImage;
  324. begin
  325.   inherited Loaded;
  326.   for I := Low(FImages) to High(FImages) do
  327.     if I in FUserImages then SetImage(Ord(I), FImages[I]);
  328. end;
  329.  
  330. procedure TRxCustomSlider.AlignControls(AControl: TControl; var Rect: TRect);
  331. var
  332.   BevelSize: Integer;
  333. begin
  334.   BevelSize := 0;
  335.   if BevelStyle <> bvNone then Inc(BevelSize, FBevelWidth);
  336.   InflateRect(Rect, -BevelSize, -BevelSize);
  337.   inherited AlignControls(AControl, Rect);
  338. end;
  339.  
  340. procedure TRxCustomSlider.WMPaint(var Message: TWMPaint);
  341. var
  342.   DC, MemDC: HDC;
  343.   MemBitmap, OldBitmap: HBITMAP;
  344.   PS: TPaintStruct;
  345. begin
  346.   if FPaintBuffered then inherited
  347.   else begin
  348. {$IFDEF RX_D3}
  349.     Canvas.Lock;
  350.     try
  351. {$ENDIF}
  352.       MemDC := GetDC(0);
  353.       MemBitmap := CreateCompatibleBitmap(MemDC, ClientWidth, ClientHeight);
  354.       ReleaseDC(0, MemDC);
  355.       MemDC := CreateCompatibleDC(0);
  356.       OldBitmap := SelectObject(MemDC, MemBitmap);
  357.       try
  358.         DC := Message.DC;
  359.         Perform(WM_ERASEBKGND, MemDC, MemDC);
  360.         FPaintBuffered := True;
  361.         Message.DC := MemDC;
  362.         try
  363.           WMPaint(Message);
  364.         finally
  365.           Message.DC := DC;
  366.           FPaintBuffered := False;
  367.         end;
  368.         if DC = 0 then DC := BeginPaint(Handle, PS);
  369.         BitBlt(DC, 0, 0, ClientWidth, ClientHeight, MemDC, 0, 0, SRCCOPY);
  370.         if Message.DC = 0 then EndPaint(Handle, PS);
  371.       finally
  372.         SelectObject(MemDC, OldBitmap);
  373.         DeleteDC(MemDC);
  374.         DeleteObject(MemBitmap);
  375.       end;
  376. {$IFDEF RX_D3}
  377.     finally
  378.       Canvas.Unlock;
  379.     end;
  380. {$ENDIF}
  381.   end;
  382. end;
  383.  
  384. procedure TRxCustomSlider.Paint;
  385. var
  386.   R: TRect;
  387.   TopColor, BottomColor, TransColor: TColor;
  388.   HighlightThumb: Boolean;
  389.   P: TPoint;
  390. {$IFDEF WIN32}
  391.   Offset: Integer;
  392. {$ENDIF}
  393. begin
  394. {$IFDEF WIN32}
  395.   if csPaintCopy in ControlState then begin
  396.     Offset := GetOffsetByValue(GetSliderValue);
  397.     P := GetThumbPosition(Offset);
  398.   end else
  399. {$ENDIF}
  400.   P := Point(FThumbRect.Left, FThumbRect.Top);
  401.   R := GetClientRect;
  402.   if BevelStyle <> bvNone then begin
  403.     TopColor := clBtnHighlight;
  404.     if BevelStyle = bvLowered then TopColor := clBtnShadow;
  405.     BottomColor := clBtnShadow;
  406.     if BevelStyle = bvLowered then BottomColor := clBtnHighlight;
  407.     Frame3D(Canvas, R, TopColor, BottomColor, FBevelWidth);
  408.   end;
  409.   if (csOpaque in ControlStyle) then
  410.     with Canvas do begin
  411.       Brush.Color := Color;
  412.       FillRect(R);
  413.     end;
  414.   if FRuler.Width > 0 then begin
  415.     if soRulerOpaque in Options then TransColor := clNone
  416.     else TransColor := FRuler.TransparentColor;
  417.     DrawBitmapTransparent(Canvas, FRulerOrg.X, FRulerOrg.Y, FRuler,
  418.       TransColor);
  419.   end;
  420.   if (soShowFocus in Options) and FFocused and
  421.     not (csDesigning in ComponentState) then
  422.   begin
  423.     R := SliderRect;
  424.     InflateRect(R, -2, -2);
  425.     Canvas.DrawFocusRect(R);
  426.   end;
  427.   if (soShowPoints in Options) then begin
  428.     if Assigned(FOnDrawPoints) then FOnDrawPoints(Self)
  429.     else InternalDrawPoints(Canvas, Increment, 3, 5);
  430.   end;
  431. {$IFDEF WIN32}
  432.   if csPaintCopy in ControlState then
  433.     HighlightThumb := not Enabled else
  434. {$ENDIF}
  435.   HighlightThumb := FThumbDown or not Enabled;
  436.   DrawThumb(Canvas, P, HighlightThumb);
  437. end;
  438.  
  439. function TRxCustomSlider.CanModify: Boolean;
  440. begin
  441.   Result := True;
  442. end;
  443.  
  444. function TRxCustomSlider.GetSliderValue: Longint;
  445. begin
  446.   Result := FValue;
  447. end;
  448.  
  449. function TRxCustomSlider.GetSliderRect: TRect;
  450. begin
  451.   Result := Bounds(0, 0, Width, Height);
  452.   if BevelStyle <> bvNone then
  453.     InflateRect(Result, -FBevelWidth, -FBevelWidth);
  454. end;
  455.  
  456. procedure TRxCustomSlider.DrawThumb(Canvas: TCanvas; Origin: TPoint;
  457.   Highlight: Boolean);
  458. var
  459.   R: TRect;
  460.   Image: TBitmap;
  461.   TransColor: TColor;
  462. begin
  463.   if Orientation = soHorizontal then Image := ImageHThumb
  464.   else Image := ImageVThumb;
  465.   R := Rect(0, 0, Image.Width, Image.Height);
  466.   if NumThumbStates = 2 then begin
  467.     if Highlight then R.Left := (R.Right - R.Left) div 2
  468.     else R.Right := (R.Right - R.Left) div 2;
  469.   end;
  470.   if soThumbOpaque in Options then TransColor := clNone
  471.   else TransColor := Image.TransparentColor;
  472.   DrawBitmapRectTransparent(Canvas, Origin.X, Origin.Y, R, Image, TransColor);
  473. end;
  474.  
  475. procedure TRxCustomSlider.InternalDrawPoints(ACanvas: TCanvas; PointsStep,
  476.   PointsHeight, ExtremePointsHeight: Longint);
  477. const
  478.   MinInterval = 3;
  479. var
  480.   RulerLength: Integer;
  481.   Interval, Scale, PointsCnt, I, Val: Longint;
  482.   X, H, X1, X2, Y1, Y2: Integer;
  483.   Range: Double;
  484. begin
  485.   RulerLength := GetRulerLength;
  486.   ACanvas.Pen.Color := clWindowText;
  487.   Scale := 0;
  488.   Range := MaxValue - MinValue;
  489.   repeat
  490.     Inc(Scale);
  491.     PointsCnt := Round(Range / (Scale * PointsStep)) + 1;
  492.     if PointsCnt > 1 then
  493.       Interval := RulerLength div (PointsCnt - 1)
  494.     else Interval := RulerLength;
  495.   until (Interval >= MinInterval + 1) or (Interval >= RulerLength);
  496.   Val := MinValue;
  497.   for I := 1 to PointsCnt do begin
  498.     H := PointsHeight;
  499.     if I = PointsCnt then Val := MaxValue;
  500.     if (Val = MaxValue) or (Val = MinValue) then H := ExtremePointsHeight;
  501.     X := GetOffsetByValue(Val);
  502.     if Orientation = soHorizontal then begin
  503.       X1 := X + (FImages[siHThumb].Width div NumThumbStates) div 2;
  504.       Y1 := FPointsRect.Top;
  505.       X2 := X1;
  506.       Y2 := Y1 + H;
  507.     end
  508.     else begin
  509.       X1 := FPointsRect.Left;
  510.       Y1 := X + FImages[siVThumb].Height div 2;
  511.       X2 := X1 + H;
  512.       Y2 := Y1;
  513.     end;
  514.     with ACanvas do begin
  515.       MoveTo(X1, Y1);
  516.       LineTo(X2, Y2);
  517.     end;
  518.     Inc(Val, Scale * PointsStep);
  519.   end;
  520. end;
  521.  
  522. procedure TRxCustomSlider.DefaultDrawPoints(PointsStep, PointsHeight,
  523.   ExtremePointsHeight: Longint);
  524. begin
  525.   InternalDrawPoints(Canvas, PointsStep, PointsHeight, ExtremePointsHeight);
  526. end;
  527.  
  528. procedure TRxCustomSlider.CreateElements;
  529. var
  530.   I: TSliderImage;
  531. begin
  532.   FRuler := TBitmap.Create;
  533.   for I := Low(FImages) to High(FImages) do SetImage(Ord(I), nil);
  534.   AdjustElements;
  535. end;
  536.  
  537. procedure TRxCustomSlider.BuildRuler(R: TRect);
  538. var
  539.   DstR, BmpR: TRect;
  540.   I, L, B, N, C, Offs, Len, RulerWidth: Integer;
  541.   TmpBmp: TBitmap;
  542.   Index: TSliderImage;
  543. begin
  544.   TmpBmp := TBitmap.Create;
  545.   try
  546.     if Orientation = soHorizontal then Index := siHRuler
  547.     else Index := siVRuler;
  548.     if Orientation = soHorizontal then begin
  549.       L := R.Right - R.Left - 2 * Indent;
  550.       if L < 0 then L := 0;
  551.       TmpBmp.Width := L;
  552.       TmpBmp.Height := FImages[Index].Height;
  553.       L := TmpBmp.Width - 2 * FEdgeSize;
  554.       B := FImages[Index].Width - 2 * FEdgeSize;
  555.       RulerWidth := FImages[Index].Width;
  556.     end
  557.     else begin
  558.       TmpBmp.Width := FImages[Index].Width;
  559.       TmpBmp.Height := R.Bottom - R.Top - 2 * Indent;
  560.       L := TmpBmp.Height - 2 * FEdgeSize;
  561.       B := FImages[Index].Height - 2 * FEdgeSize;
  562.       RulerWidth := FImages[Index].Height;
  563.     end;
  564.     N := (L div B) + 1;
  565.     C := L mod B;
  566.     for I := 0 to N - 1 do begin
  567.       if I = 0 then begin
  568.         Offs := 0;
  569.         Len := RulerWidth - FEdgeSize;
  570.       end
  571.       else begin
  572.         Offs := FEdgeSize + I * B;
  573.         if I = N - 1 then Len := C + FEdgeSize
  574.         else Len := B;
  575.       end;
  576.       if Orientation = soHorizontal then
  577.         DstR := Rect(Offs, 0, Offs + Len, TmpBmp.Height)
  578.       else DstR := Rect(0, Offs, TmpBmp.Width, Offs + Len);
  579.       if I = 0 then Offs := 0
  580.       else
  581.         if I = N - 1 then Offs := FEdgeSize + B - C
  582.         else Offs := FEdgeSize;
  583.       if Orientation = soHorizontal then
  584.         BmpR := Rect(Offs, 0, Offs + DstR.Right - DstR.Left, TmpBmp.Height)
  585.       else
  586.         BmpR := Rect(0, Offs, TmpBmp.Width, Offs + DstR.Bottom - DstR.Top);
  587.       TmpBmp.Canvas.CopyRect(DstR, FImages[Index].Canvas, BmpR);
  588.     end;
  589.     FRuler.Assign(TmpBmp);
  590.   finally
  591.     TmpBmp.Free;
  592.   end;
  593. end;
  594.  
  595. procedure TRxCustomSlider.AdjustElements;
  596. var
  597.   SaveValue: Longint;
  598.   R: TRect;
  599. begin
  600.   SaveValue := Value;
  601.   R := SliderRect;
  602.   BuildRuler(R);
  603.   if Orientation = soHorizontal then begin
  604.     if FImages[siHThumb].Height > FRuler.Height then begin
  605.       FThumbRect := Bounds(R.Left + Indent, R.Top + Indent,
  606.         FImages[siHThumb].Width div NumThumbStates, FImages[siHThumb].Height);
  607.       FRulerOrg := Point(R.Left + Indent, R.Top + Indent +
  608.         (FImages[siHThumb].Height - FRuler.Height) div 2);
  609.       FPointsRect := Rect(FRulerOrg.X, R.Top + Indent +
  610.         FImages[siHThumb].Height + 1,
  611.         FRulerOrg.X + FRuler.Width, R.Bottom - R.Top - 1);
  612.     end
  613.     else begin
  614.       FThumbRect := Bounds(R.Left + Indent, R.Top + Indent +
  615.         (FRuler.Height - FImages[siHThumb].Height) div 2,
  616.         FImages[siHThumb].Width div NumThumbStates, FImages[siHThumb].Height);
  617.       FRulerOrg := Point(R.Left + Indent, R.Top + Indent);
  618.       FPointsRect := Rect(FRulerOrg.X, R.Top + Indent + FRuler.Height + 1,
  619.         FRulerOrg.X + FRuler.Width, R.Bottom - R.Top - 1);
  620.     end;
  621.   end
  622.   else begin { soVertical }
  623.     if FImages[siVThumb].Width div NumThumbStates > FRuler.Width then
  624.     begin
  625.       FThumbRect := Bounds(R.Left + Indent, R.Top + Indent,
  626.         FImages[siVThumb].Width div NumThumbStates, FImages[siVThumb].Height);
  627.       FRulerOrg := Point(R.Left + Indent + (FImages[siVThumb].Width div NumThumbStates -
  628.         FRuler.Width) div 2, R.Top + Indent);
  629.       FPointsRect := Rect(R.Left + Indent + FImages[siVThumb].Width div NumThumbStates + 1,
  630.         FRulerOrg.Y, R.Right - R.Left - 1, FRulerOrg.Y + FRuler.Height);
  631.     end
  632.     else begin
  633.       FThumbRect := Bounds(R.Left + Indent + (FRuler.Width -
  634.         FImages[siVThumb].Width div NumThumbStates) div 2, R.Top + Indent,
  635.         FImages[siVThumb].Width div NumThumbStates, FImages[siVThumb].Height);
  636.       FRulerOrg := Point(R.Left + Indent, R.Top + Indent);
  637.       FPointsRect := Rect(R.Left + Indent + FRuler.Width + 1, FRulerOrg.Y,
  638.         R.Right - R.Left - 1, FRulerOrg.Y + FRuler.Height);
  639.     end;
  640.   end;
  641.   Value := SaveValue;
  642.   Invalidate;
  643. end;
  644.  
  645. procedure TRxCustomSlider.Sized;
  646. begin
  647.   AdjustElements;
  648. end;
  649.  
  650. procedure TRxCustomSlider.Change;
  651. begin
  652.   if Assigned(FOnChange) then FOnChange(Self);
  653. end;
  654.  
  655. procedure TRxCustomSlider.Changed;
  656. begin
  657.   if Assigned(FOnChanged) then FOnChanged(Self);
  658. end;
  659.  
  660. procedure TRxCustomSlider.RangeChanged;
  661. begin
  662. end;
  663.  
  664. procedure TRxCustomSlider.DefineProperties(Filer: TFiler);
  665.  
  666. {$IFDEF WIN32}
  667.   function DoWrite: Boolean;
  668.   begin
  669.     if Assigned(Filer.Ancestor) then
  670.       Result := FUserImages <> TRxCustomSlider(Filer.Ancestor).FUserImages
  671.     else Result := FUserImages <> [];
  672.   end;
  673. {$ENDIF}
  674.  
  675. begin
  676.   if Filer is TReader then inherited DefineProperties(Filer);
  677.   Filer.DefineBinaryProperty('UserImages', ReadUserImages, WriteUserImages,
  678.     {$IFDEF WIN32} DoWrite {$ELSE} FUserImages <> [] {$ENDIF});
  679. end;
  680.  
  681. procedure TRxCustomSlider.ReadUserImages(Stream: TStream);
  682. begin
  683.   Stream.ReadBuffer(FUserImages, SizeOf(FUserImages));
  684. end;
  685.  
  686. procedure TRxCustomSlider.WriteUserImages(Stream: TStream);
  687. begin
  688.   Stream.WriteBuffer(FUserImages, SizeOf(FUserImages));
  689. end;
  690.  
  691. function TRxCustomSlider.StoreImage(Index: Integer): Boolean;
  692. begin
  693.   Result := TSliderImage(Index) in FUserImages;
  694. end;
  695.  
  696. function TRxCustomSlider.GetImage(Index: Integer): TBitmap;
  697. begin
  698.   Result := FImages[TSliderImage(Index)];
  699. end;
  700.  
  701. procedure TRxCustomSlider.SliderImageChanged(Sender: TObject);
  702. begin
  703.   if not (csCreating in ControlState) then Sized;
  704. end;
  705.  
  706. procedure TRxCustomSlider.SetImage(Index: Integer; Value: TBitmap);
  707. var
  708.   Idx: TSliderImage;
  709. begin
  710.   Idx := TSliderImage(Index);
  711.   if FImages[Idx] = nil then begin
  712.     FImages[Idx] := TBitmap.Create;
  713.     FImages[Idx].OnChange := SliderImageChanged;
  714.   end;
  715.   if Value = nil then begin
  716.     FImages[Idx].Handle := LoadBitmap(HInstance, ImagesResNames[Idx]);
  717.     Exclude(FUserImages, Idx);
  718.     if not (csReading in ComponentState) then begin
  719.       if Idx in [siHThumb, siVThumb] then Exclude(FOptions, soThumbOpaque)
  720.       else Exclude(FOptions, soRulerOpaque);
  721.       Invalidate;
  722.     end;
  723.   end
  724.   else begin
  725.     FImages[Idx].Assign(Value);
  726.     Include(FUserImages, Idx);
  727.   end;
  728. end;
  729.  
  730. procedure TRxCustomSlider.SetEdgeSize(Value: Integer);
  731. var
  732.   MaxSize: Integer;
  733. begin
  734.   if Orientation = soHorizontal then MaxSize := FImages[siHRuler].Width
  735.   else MaxSize := FImages[siVRuler].Height;
  736.   if Value * 2 < MaxSize then
  737.     if Value <> FEdgeSize then begin
  738.       FEdgeSize := Value;
  739.       Sized;
  740.     end;
  741. end;
  742.  
  743. function TRxCustomSlider.GetNumThumbStates: TNumThumbStates;
  744. begin
  745.   Result := FNumThumbStates;
  746. end;
  747.  
  748. procedure TRxCustomSlider.SetNumThumbStates(Value: TNumThumbStates);
  749. begin
  750.   if FNumThumbStates <> Value then begin
  751.     FNumThumbStates := Value;
  752.     AdjustElements;
  753.   end;
  754. end;
  755.  
  756. procedure TRxCustomSlider.SetBevelStyle(Value: TPanelBevel);
  757. begin
  758.   if Value <> FBevelStyle then begin
  759.     FBevelStyle := Value;
  760.     Sized;
  761.     Update;
  762.   end;
  763. end;
  764.  
  765. procedure TRxCustomSlider.SetOrientation(Value: TSliderOrientation);
  766. begin
  767.   if Orientation <> Value then begin
  768.     FOrientation := Value;
  769.     Sized;
  770.     if ComponentState * [csLoading {$IFDEF WIN32}, csUpdating {$ENDIF}] = [] then
  771.       SetBounds(Left, Top, Height, Width);
  772.   end;
  773. end;
  774.  
  775. procedure TRxCustomSlider.SetOptions(Value: TSliderOptions);
  776. begin
  777.   if Value <> FOptions then begin
  778.     FOptions := Value;
  779.     Invalidate;
  780.   end;
  781. end;
  782.  
  783. procedure TRxCustomSlider.SetRange(Min, Max: Longint);
  784. begin
  785.   if (Min < Max) or (csReading in ComponentState) then begin
  786.     FMinValue := Min;
  787.     FMaxValue := Max;
  788.     if not (csReading in ComponentState) then
  789.       if Min + Increment > Max then FIncrement := Max - Min;
  790.     if (soShowPoints in Options) then Invalidate;
  791.     Self.Value := FValue;
  792.     RangeChanged;
  793.   end;
  794. end;
  795.  
  796. procedure TRxCustomSlider.SetMinValue(Value: Longint);
  797. begin
  798.   if FMinValue <> Value then SetRange(Value, MaxValue);
  799. end;
  800.  
  801. procedure TRxCustomSlider.SetMaxValue(Value: Longint);
  802. begin
  803.   if FMaxValue <> Value then SetRange(MinValue, Value);
  804. end;
  805.  
  806. procedure TRxCustomSlider.SetIncrement(Value: Longint);
  807. begin
  808.   if not (csReading in ComponentState) and ((Value > MaxValue - MinValue) or
  809.     (Value < 1)) then
  810.     raise Exception.CreateFmt(ResStr(SOutOfRange), [1, MaxValue - MinValue]);
  811.   if (Value > 0) and (FIncrement <> Value) then begin
  812.     FIncrement := Value;
  813.     Self.Value := FValue;
  814.     Invalidate;
  815.   end;
  816. end;
  817.  
  818. function TRxCustomSlider.GetValueByOffset(Offset: Integer): Longint;
  819. var
  820.   Range: Double;
  821.   R: TRect;
  822. begin
  823.   R := SliderRect;
  824.   if Orientation = soVertical then
  825.     Offset := ClientHeight - Offset - FImages[siVThumb].Height;
  826.   Range := MaxValue - MinValue;
  827.   Result := Round((Offset - R.Left - Indent) * Range / GetRulerLength);
  828.   if not (soSmooth in Options) then
  829.     Result := Round(Result / Increment) * Increment;
  830.   Result := Min(MinValue + Max(Result, 0), MaxValue);
  831. end;
  832.  
  833. function TRxCustomSlider.GetOffsetByValue(Value: Longint): Integer;
  834. var
  835.   Range: Double;
  836.   R: TRect;
  837.   MinIndent: Integer;
  838. begin
  839.   R := SliderRect;
  840.   Range := MaxValue - MinValue;
  841.   if Orientation = soHorizontal then
  842.     MinIndent := R.Left + Indent
  843.   else
  844.     MinIndent := R.Top + Indent;
  845.   Result := Round((Value - MinValue) / Range * GetRulerLength) + MinIndent;
  846.   if Orientation = soVertical then
  847.     Result := R.Top + R.Bottom - Result - FImages[siVThumb].Height;
  848.   Result := Max(Result, MinIndent);
  849. end;
  850.  
  851. function TRxCustomSlider.GetThumbPosition(var Offset: Integer): TPoint;
  852. var
  853.   R: TRect;
  854.   MinIndent: Integer;
  855. begin
  856.   R := SliderRect;
  857.   if Orientation = soHorizontal then
  858.     MinIndent := R.Left + Indent
  859.   else
  860.     MinIndent := R.Top + Indent;
  861.   Offset := Min(GetOffsetByValue(GetValueByOffset(Min(Max(Offset, MinIndent),
  862.     MinIndent + GetRulerLength))), MinIndent + GetRulerLength);
  863.   if Orientation = soHorizontal then begin
  864.     Result.X := Offset;
  865.     Result.Y := FThumbRect.Top;
  866.   end
  867.   else begin
  868.     Result.Y := Offset;
  869.     Result.X := FThumbRect.Left;
  870.   end;
  871. end;
  872.  
  873. function TRxCustomSlider.GetThumbOffset: Integer;
  874. begin
  875.   if Orientation = soHorizontal then Result := FThumbRect.Left
  876.   else Result := FThumbRect.Top;
  877. end;
  878.  
  879. procedure TRxCustomSlider.InvalidateThumb;
  880. begin
  881.   if HandleAllocated then
  882.     InvalidateRect(Handle, @FThumbRect, not (csOpaque in ControlStyle));
  883. end;
  884.  
  885. procedure TRxCustomSlider.SetThumbOffset(Value: Integer);
  886. var
  887.   ValueBefore: Longint;
  888.   P: TPoint;
  889. begin
  890.   ValueBefore := FValue;
  891.   P := GetThumbPosition(Value);
  892.   InvalidateThumb;
  893.   FThumbRect := Bounds(P.X, P.Y, WidthOf(FThumbRect), HeightOf(FThumbRect));
  894.   InvalidateThumb;
  895.   if FSliding then begin
  896.     FValue := GetValueByOffset(Value);
  897.     if ValueBefore <> FValue then Change;
  898.   end;
  899. end;
  900.  
  901. function TRxCustomSlider.GetRulerLength: Integer;
  902. begin
  903.   if Orientation = soHorizontal then begin
  904.     Result := FRuler.Width;
  905.     Dec(Result, FImages[siHThumb].Width div NumThumbStates);
  906.   end
  907.   else begin
  908.     Result := FRuler.Height;
  909.     Dec(Result, FImages[siVThumb].Height);
  910.   end;
  911. end;
  912.  
  913. procedure TRxCustomSlider.SetValue(Value: Longint);
  914. var
  915.   ValueChanged: Boolean;
  916. begin
  917.   if Value > MaxValue then Value := MaxValue;
  918.   if Value < MinValue then Value := MinValue;
  919.   ValueChanged := FValue <> Value;
  920.   FValue := Value;
  921.   ThumbOffset := GetOffsetByValue(Value);
  922.   if ValueChanged then Change;
  923. end;
  924.  
  925. procedure TRxCustomSlider.SetReadOnly(Value: Boolean);
  926. begin
  927.   if FReadOnly <> Value then begin
  928.     if Value then begin
  929.       StopTracking;
  930.       if FSliding then ThumbMouseUp(mbLeft, [], 0, 0);
  931.     end;
  932.     FReadOnly := Value;
  933.   end;
  934. end;
  935.  
  936. procedure TRxCustomSlider.ThumbJump(Jump: TJumpMode);
  937. var
  938.   NewValue: Longint;
  939. begin
  940.   if Jump <> jmNone then begin
  941.     case Jump of
  942.       jmHome: NewValue := MinValue;
  943.       jmPrior:
  944.         NewValue := (Round(Value / Increment) * Increment) - Increment;
  945.       jmNext:
  946.         NewValue := (Round(Value / Increment) * Increment) + Increment;
  947.       jmEnd: NewValue := MaxValue;
  948.       else Exit;
  949.     end;
  950.     if NewValue >= MaxValue then NewValue := MaxValue
  951.     else if NewValue <= MinValue then NewValue := MinValue;
  952.     if (NewValue <> Value) then Value := NewValue;
  953.   end;
  954. end;
  955.  
  956. function TRxCustomSlider.JumpTo(X, Y: Integer): TJumpMode;
  957. begin
  958.   Result := jmNone;
  959.   if Orientation = soHorizontal then begin
  960.     if FThumbRect.Left > X then Result := jmPrior
  961.     else if FThumbRect.Right < X then Result := jmNext;
  962.   end
  963.   else if Orientation = soVertical then begin
  964.     if FThumbRect.Top > Y then Result := jmNext
  965.     else if FThumbRect.Bottom < Y then Result := jmPrior;
  966.   end;
  967. end;
  968.  
  969. procedure TRxCustomSlider.WMTimer(var Message: TMessage);
  970. begin
  971.   TimerTrack;
  972. end;
  973.  
  974. procedure TRxCustomSlider.CMEnabledChanged(var Message: TMessage);
  975. begin
  976.   inherited;
  977.   InvalidateThumb;
  978. end;
  979.  
  980. procedure TRxCustomSlider.CMFocusChanged(var Message: TCMFocusChanged);
  981. var
  982.   Active: Boolean;
  983. begin
  984.   with Message do Active := (Sender = Self);
  985.   if Active <> FFocused then begin
  986.     FFocused := Active;
  987.     if (soShowFocus in Options) then Invalidate;
  988.   end;
  989.   inherited;
  990. end;
  991.  
  992. procedure TRxCustomSlider.WMGetDlgCode(var Msg: TWMGetDlgCode);
  993. begin
  994.   Msg.Result := DLGC_WANTARROWS;
  995. end;
  996.  
  997. procedure TRxCustomSlider.WMSize(var Message: TWMSize);
  998. begin
  999.   inherited;
  1000.   if not (csReading in ComponentState) then Sized;
  1001. end;
  1002.  
  1003. procedure TRxCustomSlider.WMSetCursor(var Message: TWMSetCursor);
  1004. var
  1005.   P: TPoint;
  1006. begin
  1007.   GetCursorPos(P);
  1008.   if not (csDesigning in ComponentState) and PtInRect(FThumbRect,
  1009.     ScreenToClient(P)) then
  1010.   begin
  1011. {$IFDEF WIN32}
  1012.     Windows.SetCursor(Screen.Cursors[crHand]);
  1013. {$ELSE}
  1014.     WinProcs.SetCursor(Screen.Cursors[crHand]);
  1015. {$ENDIF}
  1016.   end
  1017.   else inherited;
  1018. end;
  1019.  
  1020. procedure TRxCustomSlider.StopTracking;
  1021. begin
  1022.   if FTracking then begin
  1023.     if FTimerActive then begin
  1024.       KillTimer(Handle, 1);
  1025.       FTimerActive := False;
  1026.     end;
  1027.     FTracking := False;
  1028.     MouseCapture := False;
  1029.     Changed;
  1030.   end;
  1031. end;
  1032.  
  1033. procedure TRxCustomSlider.TimerTrack;
  1034. var
  1035.   Jump: TJumpMode;
  1036. begin
  1037.   Jump := JumpTo(FMousePos.X, FMousePos.Y);
  1038.   if Jump = FStartJump then begin
  1039.     ThumbJump(Jump);
  1040.     if not FTimerActive then begin
  1041.       SetTimer(Handle, 1, JumpInterval, nil);
  1042.       FTimerActive := True;
  1043.     end;
  1044.   end;
  1045. end;
  1046.  
  1047. procedure TRxCustomSlider.MouseDown(Button: TMouseButton; Shift: TShiftState;
  1048.   X, Y: Integer);
  1049. var
  1050.   Rect: TRect;
  1051.   P: TPoint;
  1052. begin
  1053.   inherited MouseDown(Button, Shift, X, Y);
  1054.   if (Button = mbLeft) and not (ssDouble in Shift) then begin
  1055.     if CanFocus then SetFocus;
  1056.     P := Point(X, Y);
  1057.     if PointInRect(P, FThumbRect) then
  1058.       ThumbMouseDown(Button, Shift, X, Y)
  1059.     else begin
  1060.       with FRulerOrg, FRuler do
  1061.         Rect := Bounds(X, Y, Width, Height);
  1062.       InflateRect(Rect, Ord(Orientation = soVertical) * 3,
  1063.         Ord(Orientation = soHorizontal) * 3);
  1064.       if PointInRect(P, Rect) and CanModify and not ReadOnly then begin
  1065.         MouseCapture := True;
  1066.         FTracking := True;
  1067.         FMousePos := P;
  1068.         FStartJump := JumpTo(X, Y);
  1069.         TimerTrack;
  1070.       end;
  1071.     end;
  1072.   end;
  1073. end;
  1074.  
  1075. procedure TRxCustomSlider.MouseMove(Shift: TShiftState; X, Y: Integer);
  1076. begin
  1077.   if (csLButtonDown in ControlState) and FSliding then
  1078.     ThumbMouseMove(Shift, X, Y)
  1079.   else if FTracking then FMousePos := Point(X, Y);
  1080.   inherited MouseMove(Shift, X, Y);
  1081. end;
  1082.  
  1083. procedure TRxCustomSlider.MouseUp(Button: TMouseButton; Shift: TShiftState;
  1084.   X, Y: Integer);
  1085. begin
  1086.   StopTracking;
  1087.   if FSliding then ThumbMouseUp(Button, Shift, X, Y);
  1088.   inherited MouseUp(Button, Shift, X, Y);
  1089. end;
  1090.  
  1091. procedure TRxCustomSlider.KeyDown(var Key: Word; Shift: TShiftState);
  1092. var
  1093.   Jump: TJumpMode;
  1094. begin
  1095.   Jump := jmNone;
  1096.   if Shift = [] then begin
  1097.     if Key = VK_HOME then Jump := jmHome
  1098.     else if Key = VK_END then Jump := jmEnd;
  1099.     if Orientation = soHorizontal then begin
  1100.       if Key = VK_LEFT then Jump := jmPrior
  1101.       else if Key = VK_RIGHT then Jump := jmNext;
  1102.     end
  1103.     else begin
  1104.       if Key = VK_UP then Jump := jmNext
  1105.       else if Key = VK_DOWN then Jump := jmPrior;
  1106.     end;
  1107.   end;
  1108.   if (Jump <> jmNone) and CanModify and not ReadOnly then begin
  1109.     Key := 0;
  1110.     ThumbJump(Jump);
  1111.     Changed;
  1112.   end;
  1113.   inherited KeyDown(Key, Shift);
  1114. end;
  1115.  
  1116. procedure TRxCustomSlider.ThumbMouseDown(Button: TMouseButton;
  1117.   Shift: TShiftState; X, Y: Integer);
  1118. begin
  1119.   if CanFocus then SetFocus;
  1120.   if (Button = mbLeft) and CanModify and not ReadOnly then begin
  1121.     FSliding := True;
  1122.     FThumbDown := True;
  1123.     if Orientation = soHorizontal then FHit := X - FThumbRect.Left
  1124.     else FHit := Y - FThumbRect.Top;
  1125.     InvalidateThumb;
  1126.     Update;
  1127.   end;
  1128. end;
  1129.  
  1130. procedure TRxCustomSlider.ThumbMouseMove(Shift: TShiftState; X, Y: Integer);
  1131. begin
  1132.   if (csLButtonDown in ControlState) and CanModify and not ReadOnly then
  1133.   begin
  1134.     if Orientation = soHorizontal then ThumbOffset := X - FHit
  1135.     else ThumbOffset := Y - FHit;
  1136.   end;
  1137. end;
  1138.  
  1139. procedure TRxCustomSlider.ThumbMouseUp(Button: TMouseButton;
  1140.   Shift: TShiftState; X, Y: Integer);
  1141. begin
  1142.   if (Button = mbLeft) then begin
  1143.     FSliding := False;
  1144.     FThumbDown := False;
  1145.     InvalidateThumb;
  1146.     Update;
  1147.     if CanModify and not ReadOnly then Changed;
  1148.   end;
  1149. end;
  1150.  
  1151. { TRxCustomTrackBar }
  1152.  
  1153. constructor TRxCustomTrackBar.Create(AOwner: TComponent);
  1154. begin
  1155.   inherited Create(AOwner);
  1156.   FImages := TRxSliderImages.Create;
  1157.   FImages.FSlider := Self;
  1158. end;
  1159.  
  1160. destructor TRxCustomTrackBar.Destroy;
  1161. begin
  1162.   FImages.Free;
  1163.   inherited Destroy;
  1164. end;
  1165.  
  1166. { TRxSliderImages }
  1167.  
  1168. function TRxSliderImages.GetImage(Index: Integer): TBitmap;
  1169. begin
  1170.   Result := FSlider.GetImage(Index);
  1171. end;
  1172.  
  1173. procedure TRxSliderImages.SetImage(Index: Integer; Value: TBitmap);
  1174. begin
  1175.   FSlider.SetImage(Index, Value);
  1176. end;
  1177.  
  1178. function TRxSliderImages.StoreImage(Index: Integer): Boolean;
  1179. begin
  1180.   Result := FSlider.StoreImage(Index);
  1181. end;
  1182.  
  1183. function TRxSliderImages.GetNumThumbStates: TNumThumbStates;
  1184. begin
  1185.   Result := FSlider.NumThumbStates;
  1186. end;
  1187.  
  1188. procedure TRxSliderImages.SetNumThumbStates(Value: TNumThumbStates);
  1189. begin
  1190.   FSlider.NumThumbStates := Value;
  1191. end;
  1192.  
  1193. function TRxSliderImages.GetEdgeSize: Integer;
  1194. begin
  1195.   Result := FSlider.EdgeSize;
  1196. end;
  1197.  
  1198. procedure TRxSliderImages.SetEdgeSize(Value: Integer);
  1199. begin
  1200.   FSlider.EdgeSize := Value;
  1201. end;
  1202.  
  1203. end.
  1204.