12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364 |
- unit TBXLists;
- // TBX Package
- // Copyright 2001-2004 Alex A. Denisov. All Rights Reserved
- // See TBX.chm for license and installation instructions
- //
- // Id: TBXLists.pas 7 2004-02-21 06:07:53Z
- interface
- {$I TB2Ver.inc}
- uses
- Windows, Messages, Classes, SysUtils, Controls, Forms, Graphics, TB2Item, TBX,
- TBXThemes, UxTheme, ImgList;
- type
- { TTBXScrollBar }
- TSBIncrement = 1..1000;
- TSBZone = (sbzEmpty, sbzPrev, sbzPagePrev, sbzHandle, sbzPageNext, sbzNext);
- TSBAutoScrollEvent = procedure(Sender: TObject; var Direction, Interval: Integer) of object;
- TTBXScrollBar = class
- private
- FBounds: TRect;
- FLeft: Integer;
- FHandle: HWND;
- FHeight: Integer;
- FIncrement: TSBIncrement;
- FKind: TScrollBarKind;
- FPosition: Integer;
- FRange: Integer;
- FRight: Integer;
- FTop: Integer;
- FWidth: Integer;
- FWindow: Integer;
- FOnChange: TNotifyEvent;
- FOnAutoScroll: TSBAutoScrollEvent;
- FOnRedrawRequest: TNotifyEvent;
- procedure SetBounds(const Value: TRect);
- procedure SetKind(Value: TScrollBarKind);
- procedure SetPosition(Value: Integer);
- procedure SetRange(Value: Integer);
- function GetHandle: HWND;
- protected
- AutoScrollDirection: Integer;
- AutoScrolling: Boolean;
- AutoScrollInterval: Integer;
- Zones: array [TSBZone] of TRect;
- MouseDownZone: TSBZone;
- MouseDownPoint: TPoint;
- MouseDownPosition: Integer;
- LastMousePoint: TPoint;
- PrevCapture: HWND;
- UserChange: Boolean;
- procedure AdjustPosition(var NewPosition: Integer);
- procedure CreateWnd;
- procedure DestroyWnd;
- function GetZone(X, Y: Integer): TSBZone;
- function GetEffectiveWindow: Integer;
- function GetEnabled: Boolean; virtual;
- procedure HandleZoneClick(AZone: TSBZone);
- procedure MouseDown(Button: TMouseButton; X, Y: Integer); virtual;
- procedure MouseMove(X, Y: Integer); virtual;
- procedure MouseUp(Button: TMouseButton; X, Y: Integer); virtual;
- procedure PaintButton(Canvas: TCanvas; Rect: TRect; Direction: Integer; Pushed, Enabled: Boolean);
- procedure PaintHandle(Canvas: TCanvas; Rect: TRect; Pushed, Enabled: Boolean);
- procedure PaintTrack(Canvas: TCanvas; Rect: TRect; IsNextZone, Pushed, Enabled: Boolean);
- procedure PaintTo(Canvas: TCanvas);
- procedure SBWndProc(var Message: TMessage);
- procedure StartAutoScroll(Direction, Interval: Integer);
- procedure StopAutoScroll;
- procedure StartTimer(ID: Integer; Elapse: Integer);
- procedure StopTimer(ID: Integer);
- procedure TimerElapsed(ID: Integer; var NewElapse: Integer); virtual;
- procedure UpdateZones;
- property Handle: HWND read GetHandle;
- public
- constructor Create;
- destructor Destroy; override;
- procedure Redraw; virtual;
- procedure UpdatePosition(NewPosition: Integer);
- property Kind: TScrollBarKind read FKind write SetKind;
- property Bounds: TRect read FBounds write SetBounds;
- property Left: Integer read FLeft;
- property Height: Integer read FHeight;
- property Increment: TSBIncrement read FIncrement write FIncrement;
- property Position: Integer read FPosition write SetPosition;
- property Range: Integer read FRange write SetRange;
- property Right: Integer read FRight;
- property Top: Integer read FTop;
- property Width: Integer read FWidth;
- property Window: Integer read FWindow write FWindow;
- property OnAutoScroll: TSBAutoScrollEvent read FOnAutoScroll write FOnAutoScroll;
- property OnChange: TNotifyEvent read FOnChange write FOnChange;
- property OnRedrawRequest: TNotifyEvent read FOnRedrawRequest write FOnRedrawRequest;
- end;
- { TTBXCustomList }
- TTBXCustomList = class;
- TTBXLMeasureHeight = procedure(Sender: TTBXCustomList; ACanvas: TCanvas; var AHeight: Integer) of object;
- TTBXLMeasureWidth = procedure(Sender: TTBXCustomList; ACanvas: TCanvas; AIndex: Integer; var AWidth: Integer) of object;
- TTBXLPaintEvent = procedure(Sender: TTBXCustomList; ACanvas: TCanvas; ARect: TRect; AIndex, AHoverIndex: Integer; var DrawDefault: Boolean) of object;
- TTBXLAdjustImageIndex = procedure(Sender: TTBXCustomList; AItemIndex: Integer; var ImageIndex: Integer) of object;
- TTBXCustomListViewer = class;
- TTBXCustomList = class(TTBXCustomItem)
- private
- FViewers: TList;
- FItemIndex: Integer;
- FMinWidth: Integer;
- FMaxWidth: Integer;
- FMaxVisibleItems: Integer;
- FShowImages: Boolean;
- FOnChange: TNotifyEvent;
- FOnClearItem: TTBXLPaintEvent;
- FOnDrawItem: TTBXLPaintEvent;
- FOnAdjustImageIndex: TTBXLAdjustImageIndex;
- FOnMeasureHeight: TTBXLMeasureHeight;
- FOnMeasureWidth: TTBXLMeasureWidth;
- procedure SetItemIndex(Value: Integer);
- protected
- function DoClearItem(ACanvas: TCanvas; ARect: TRect; AIndex, AHoverIndex: Integer): Boolean; virtual;
- function DoDrawItem(ACanvas: TCanvas; {MP} var ARect: TRect; AIndex, AHoverIndex: Integer): Boolean; virtual;
- procedure DoMeasureHeight(ACanvas: TCanvas; var AHeight: Integer); virtual;
- procedure DoMeasureWidth(ACanvas: TCanvas; AIndex: Integer; var AWidth: Integer); virtual;
- procedure DrawItem(ACanvas: TCanvas; AViewer: TTBXCustomListViewer; const ARect: TRect; AIndex, AHoverIndex: Integer); virtual;
- function GetImageIndex(ItemIndex: Integer): Integer; virtual;
- function GetItemViewerClass(AView: TTBView): TTBItemViewerClass; override;
- function GetItemText(Index: Integer): string; virtual; abstract;
- function GetCount: Integer; virtual; abstract;
- procedure HandleChange; virtual;
- procedure HandleHover(AIndex: Integer); virtual;
- procedure Notification(AComponent: TComponent; Operation: TOperation); override;
- public
- constructor Create(AOwner: TComponent); override;
- procedure MakeVisible(AIndex: Integer);
- procedure ChangeScale(M, D: Integer); override;
- property ItemIndex: Integer read FItemIndex write SetItemIndex default -1;
- property MaxVisibleItems: Integer read FMaxVisibleItems write FMaxVisibleItems default 8;
- property MaxWidth: Integer read FMaxWidth write FMaxWidth default 0;
- property MinWidth: Integer read FMinWidth write FMinWidth default 32;
- property ShowImages: Boolean read FShowImages write FShowImages default False;
- property OnAdjustImageIndex: TTBXLAdjustImageIndex read FOnAdjustImageIndex write FOnAdjustImageIndex;
- property OnChange: TNotifyEvent read FOnChange write FOnChange;
- property OnClearItem: TTBXLPaintEvent read FOnClearItem write FOnClearItem;
- property OnDrawItem: TTBXLPaintEvent read FOnDrawItem write FOnDrawItem;
- property OnMeasureHeight: TTBXLMeasureHeight read FOnMeasureHeight write FOnMeasureHeight;
- property OnMeasureWidth: TTBXLMeasureWidth read FOnMeasureWidth write FOnMeasureWidth;
- end;
- TTBXCustomListViewer = class(TTBXItemViewer)
- private
- FItemCount: Integer;
- FItemHeight: Integer;
- FHoverIndex: Integer;
- FHeight: Integer;
- FLastClientRect: TRect;
- FWheelAccumulator: Integer;
- FWidth: Integer;
- FOffset: Integer;
- FScrollBarWidth: Integer;
- FScrollBar: TTBXScrollBar;
- FVisibleItems: Integer;
- procedure ListChangeHandler(NewIndex: Integer);
- procedure SBAutoScrollHandler(Sender: TObject; var Direction, Interval: Integer);
- procedure SBChangeHandler(Sender: TObject);
- procedure SBRedrawHandler(Sender: TObject);
- protected
- MouseIsDown: Boolean;
- MouseInScrollBar: Boolean;
- IgnoreMouseUp: Boolean;
- IsChanging: Boolean;
- procedure AdjustAutoScrollHover(var AIndex: Integer; Direction: Integer); virtual;
- procedure CalcSize(const Canvas: TCanvas; var AWidth, AHeight: Integer); override;
- procedure DrawItems(const Canvas: TCanvas; const ClientAreaRect: TRect);
- function GetItemIndexAt(X, Y: Integer): Integer;
- function GetItemRect(Index: Integer): TRect;
- function GetItemHeight(ACanvas: TCanvas): Integer; virtual;
- function GetItemWidth(ACanvas: TCanvas; Index: Integer): Integer; virtual;
- procedure HandleAutoScroll(var Direction, Interval: Integer); virtual;
- procedure KeyDown(var Key: Word; Shift: TShiftState); override;
- procedure MakeVisible(Index: Integer);
- procedure MouseDown(Shift: TShiftState; X, Y: Integer; var MouseDownOnMenu: Boolean); override;
- procedure MouseMove(X, Y: Integer); override;
- procedure MouseUp(X, Y: Integer; MouseWasDownOnMenu: Boolean); override;
- procedure MouseWheel(WheelDelta: Integer; X, Y: Integer); override;
- procedure Paint(const Canvas: TCanvas; const ClientAreaRect: TRect; IsHoverItem, IsPushed, UseDisabledShadow: Boolean); override;
- procedure UpdateItems;
- property HoverIndex: Integer read FHoverIndex write FHoverIndex;
- property Offset: Integer read FOffset;
- property VisibleItems: Integer read FVisibleItems;
- public
- constructor Create(AView: TTBView; AItem: TTBCustomItem; AGroupLevel: Integer); override;
- destructor Destroy; override;
- end;
- { TTBXStringList }
- TTBXStringList = class(TTBXCustomList)
- private
- FStrings: TStrings;
- procedure SetStrings(Value: TStrings);
- protected
- function GetItemText(Index: Integer): string; override;
- function GetCount: Integer; override;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- published
- property ItemIndex;
- property MaxVisibleItems;
- property MaxWidth;
- property MinWidth;
- property Strings: TStrings read FStrings write SetStrings;
- property OnAdjustImageIndex;
- property OnChange;
- property OnClearItem;
- property OnClick;
- property OnDrawItem;
- property OnMeasureHeight;
- property OnMeasureWidth;
- end;
- TTBXStringListClass = class of TTBXStringList;
- implementation
- uses Types, PasTools;
- type TTBViewAccess = class(TTBView);
- const
- SCROLL_TIMER = 1;
- AUTO_SCROLL_TIMER = 2;
- MIN_SB_HANDLE_SIZE = 8;
- CImageSpacing = 4;
- //----------------------------------------------------------------------------//
- { TTBXScrollBar }
- procedure TTBXScrollBar.AdjustPosition(var NewPosition: Integer);
- var
- W: Integer;
- begin
- W := GetEffectiveWindow;
- if NewPosition + W > Range then NewPosition := Range - W;
- if NewPosition < 0 then NewPosition := 0;
- end;
- constructor TTBXScrollBar.Create;
- begin
- FIncrement := 1;
- end;
- procedure TTBXScrollBar.CreateWnd;
- begin
- if FHandle = 0 then FHandle := Classes.AllocateHWnd(SBWndProc);
- end;
- destructor TTBXScrollBar.Destroy;
- begin
- DestroyWnd;
- inherited;
- end;
- procedure TTBXScrollBar.DestroyWnd;
- begin
- if FHandle <> 0 then
- begin
- Classes.DeallocateHWnd(FHandle);
- FHandle := 0;
- end;
- end;
- function TTBXScrollBar.GetEffectiveWindow: Integer;
- begin
- if Window <= 0 then
- begin
- if Kind = sbVertical then Result := Height
- else Result := Width;
- end
- else Result := Window;
- end;
- function TTBXScrollBar.GetEnabled: Boolean;
- begin
- Result := Range > GetEffectiveWindow;
- end;
- function TTBXScrollBar.GetHandle: HWND;
- begin
- if FHandle = 0 then CreateWnd;
- Result := FHandle;
- end;
- function TTBXScrollBar.GetZone(X, Y: Integer): TSBZone;
- var
- I: Integer;
- Pt: TPoint;
- begin
- Pt.X := X;
- Pt.Y := Y;
- for I := Ord(sbzPrev) to Ord(sbzNext) do
- begin
- Result := TSBZone(I);
- if PtInRect(Zones[Result], Pt) then Exit;
- end;
- Result := sbzEmpty;
- end;
- procedure TTBXScrollBar.HandleZoneClick(AZone: TSBZone);
- begin
- UserChange := True;
- case AZone of
- sbzPrev: Position := Position - Increment;
- sbzPagePrev: Position := Position - GetEffectiveWindow;
- sbzPageNext: Position := Position + GetEffectiveWindow;
- sbzNext: Position := Position + Increment;
- end;
- UserChange := False;
- end;
- procedure TTBXScrollBar.MouseDown(Button: TMouseButton; X, Y: Integer);
- begin
- if Button = mbLeft then
- begin
- MouseDownZone := GetZone(X, Y);
- MouseDownPoint := Point(X, Y);
- MouseDownPosition := Position;
- LastMousePoint := MouseDownPoint;
- if MouseDownZone in [sbzPrev, sbzPagePrev, sbzPageNext, sbzNext] then
- begin
- HandleZoneClick(MouseDownZone);
- StartTimer(SCROLL_TIMER, 500);
- end;
- Redraw;
- end;
- end;
- procedure TTBXScrollBar.MouseMove(X, Y: Integer);
- var
- Delta: Integer;
- ClientSize, HandleSize: Integer;
- begin
- LastMousePoint := Point(X, Y);
- if MouseDownZone = sbzHandle then
- begin
- if Kind = sbVertical then
- begin
- Delta := Y - MouseDownPoint.Y;
- ClientSize := Zones[sbzPageNext].Bottom - Zones[sbzPagePrev].Top;
- end
- else
- begin
- Delta := X - MouseDownPoint.X;
- ClientSize := Zones[sbzPageNext].Right - Zones[sbzPagePrev].Left;
- end;
- HandleSize := Round(ClientSize * Window / Range);
- if HandleSize < MIN_SB_HANDLE_SIZE then
- Delta := Round(Delta * (Range - Window) / (ClientSize - MIN_SB_HANDLE_SIZE))
- else
- Delta := Round(Delta * Range / ClientSize);
- if MouseDownPosition + Delta <> Position then
- begin
- UserChange := True;
- Position := MouseDownPosition + Delta;
- UserChange := False;
- end;
- end;
- end;
- procedure TTBXScrollBar.MouseUp(Button: TMouseButton; X, Y: Integer);
- begin
- StopTimer(SCROLL_TIMER);
- if Button = mbLeft then
- begin
- MouseDownZone := sbzEmpty;
- Redraw;
- end;
- end;
- procedure TTBXScrollBar.PaintButton(Canvas: TCanvas; Rect: TRect;
- Direction: Integer; Pushed, Enabled: Boolean);
- const
- DirectionFlags: array [0..3] of Cardinal = (DFCS_SCROLLLEFT, DFCS_SCROLLUP,
- DFCS_SCROLLRIGHT, DFCS_SCROLLDOWN);
- EnabledFlags: array [Boolean] of Cardinal = (DFCS_INACTIVE, 0);
- PushedFlags: array [Boolean] of Cardinal = (0, DFCS_PUSHED or DFCS_FLAT);
- DirectionXPFlags: array [0..3] of Cardinal = (ABS_LEFTNORMAL, ABS_UPNORMAL,
- ABS_RIGHTNORMAL, ABS_DOWNNORMAL);
- var
- StateFlags: Cardinal;
- Theme: THandle;
- begin
- if USE_THEMES then
- begin
- StateFlags := DirectionXPFlags[Direction];
- if not Enabled then Inc(StateFlags, 3)
- else if Pushed then Inc(StateFlags, 2);
- Theme := OpenThemeData(Handle, 'SCROLLBAR');
- DrawThemeBackground(Theme, Canvas.Handle, SBP_ARROWBTN, StateFlags, Rect, nil);
- CloseThemeData(Theme);
- end
- else
- begin
- DrawFrameControl(Canvas.Handle, Rect, DFC_SCROLL,
- DirectionFlags[Direction] or EnabledFlags[Enabled] or PushedFlags[Pushed]);
- end;
- end;
- procedure TTBXScrollBar.PaintHandle(Canvas: TCanvas; Rect: TRect; Pushed, Enabled: Boolean);
- const
- PartXPFlags: array [TScrollBarKind] of Cardinal = (SBP_THUMBBTNHORZ, SBP_THUMBBTNVERT);
- var
- StateFlags: Cardinal;
- Theme: THandle;
- begin
- if USE_THEMES then
- begin
- StateFlags := SCRBS_NORMAL;
- if not Enabled then Inc(StateFlags, 3)
- else if Pushed then Inc(StateFlags, 2);
- Theme := OpenThemeData(Handle, 'SCROLLBAR');
- DrawThemeBackground(Theme, Canvas.Handle, PartXPFlags[Kind], StateFlags, Rect, nil);
- CloseThemeData(Theme);
- end
- else
- begin
- DrawEdge(Canvas.Handle, Rect, EDGE_RAISED, BF_RECT or BF_ADJUST);
- Canvas.Brush.Color := clBtnFace;
- Canvas.FillRect(Rect);
- end;
- end;
- procedure TTBXScrollBar.PaintTo(Canvas: TCanvas);
- var
- R: TRect;
- E, IsVert: Boolean;
- I: Integer;
- Dummy: TPoint;
- begin
- UpdateZones;
- IsVert := Kind = sbVertical;
- E := GetEnabled;
- OffsetWindowOrgEx(Canvas.Handle, -Bounds.Left, -Bounds.Top, Dummy);
- try
- if IsVert then I := 1 else I := 0;
- PaintButton(Canvas, Zones[sbzPrev], I, MouseDownZone = sbzPrev, E);
- PaintButton(Canvas, Zones[sbzNext], I + 2, MouseDownZone = sbzNext, E);
- if not IsRectEmpty(Zones[sbzEmpty]) then
- begin
- Canvas.Brush.Color := clScrollBar;
- Canvas.Brush.Style := bsSolid;
- Canvas.FillRect(Zones[sbzEmpty]);
- end;
- if not IsRectEmpty(Zones[sbzPagePrev]) or not IsRectEmpty(Zones[sbzPageNext]) then
- begin
- R := Zones[sbzPagePrev];
- PaintTrack(Canvas, R, False, MouseDownZone = sbzPagePrev, E);
- R := Zones[sbzPageNext];
- PaintTrack(Canvas, R, True, MouseDownZone = sbzPageNext, E);
- end;
- if not IsRectEmpty(Zones[sbzHandle]) then
- PaintHandle(Canvas, Zones[sbzHandle], MouseDownZone = sbzHandle, E);
- finally
- OffsetWindowOrgEx(Canvas.Handle, Bounds.Left, Bounds.Top, Dummy);
- end;
- end;
- procedure TTBXScrollBar.PaintTrack(Canvas: TCanvas; Rect: TRect;
- IsNextZone, Pushed, Enabled: Boolean);
- const
- PartXPFlags: array [Boolean, TScrollBarKind] of Cardinal =
- ((SBP_LOWERTRACKHORZ, SBP_LOWERTRACKVERT), (SBP_UPPERTRACKHORZ, SBP_UPPERTRACKVERT));
- var
- StateFlags: Cardinal;
- Theme: THandle;
- begin
- if USE_THEMES then
- begin
- StateFlags := SCRBS_NORMAL;
- if not Enabled then Inc(StateFlags, 3)
- else if Pushed then Inc(StateFlags, 2);
- Theme := OpenThemeData(Handle, 'SCROLLBAR');
- DrawThemeBackground(Theme, Canvas.Handle, PartXPFlags[IsNextZone, Kind],
- StateFlags, Rect, nil);
- CloseThemeData(Theme);
- end
- else
- begin
- if Pushed then Canvas.Brush.Color := cl3DDkShadow
- else Canvas.Brush.Bitmap := AllocPatternBitmap(clBtnHighlight, clScrollBar);
- Canvas.FillRect(Rect);
- end;
- end;
- procedure TTBXScrollBar.Redraw;
- begin
- if Assigned(FOnRedrawRequest) then FOnRedrawRequest(Self);
- end;
- procedure TTBXScrollBar.SBWndProc(var Message: TMessage);
- var
- I: Integer;
- procedure DefaultHandler;
- begin
- with Message do
- Result := DefWindowProc(FHandle, Msg, wParam, lParam);
- end;
- begin
- case Message.Msg of
- WM_TIMER: with TWMTimer(Message) do
- begin
- I := 0;
- TimerElapsed(TimerID, I);
- if I > 0 then StartTimer(TimerID, I)
- else StopTimer(TimerID);
- Result := 0;
- end;
- else
- DefaultHandler;
- end;
- end;
- procedure TTBXScrollBar.SetBounds(const Value: TRect);
- begin
- FBounds := Value;
- with Value do
- begin
- FLeft := Left;
- FTop := Top;
- FWidth := Right - Left;
- FHeight := Bottom - Top;
- end;
- UpdateZones;
- end;
- procedure TTBXScrollBar.SetKind(Value: TScrollBarKind);
- begin
- FKind := Value;
- UpdateZones;
- end;
- procedure TTBXScrollBar.SetPosition(Value: Integer);
- begin
- AdjustPosition(Value);
- if Value <> FPosition then
- begin
- FPosition := Value;
- if UserChange then
- begin
- Redraw;
- if Assigned(FOnChange) then FOnChange(Self);
- end;
- end;
- end;
- procedure TTBXScrollBar.SetRange(Value: Integer);
- begin
- if Value < 0 then Value := 0;
- if Value <> FRange then
- begin
- FRange := Value;
- Redraw;
- SetPosition(Position);
- end;
- end;
- procedure TTBXScrollBar.StartAutoScroll(Direction, Interval: Integer);
- begin
- if Direction <> 0 then
- begin
- AutoScrollDirection := Direction;
- AutoScrollInterval := Interval;
- if not AutoScrolling then
- begin
- StartTimer(AUTO_SCROLL_TIMER, Interval);
- AutoScrolling := True;
- end;
- end;
- end;
- procedure TTBXScrollBar.StartTimer(ID, Elapse: Integer);
- begin
- SetTimer(Handle, ID, Elapse, nil);
- end;
- procedure TTBXScrollBar.StopAutoScroll;
- begin
- if AutoScrolling then
- begin
- AutoScrolling := False;
- StopTimer(AUTO_SCROLL_TIMER);
- end;
- end;
- procedure TTBXScrollBar.StopTimer(ID: Integer);
- begin
- KillTimer(Handle, ID);
- end;
- procedure TTBXScrollBar.TimerElapsed(ID: Integer; var NewElapse: Integer);
- begin
- case ID of
- SCROLL_TIMER:
- if MouseDownZone <> sbzEmpty then
- if not (MouseDownZone in [sbzPagePrev, sbzPageNext]) or
- (GetZone(LastMousePoint.X, LastMousePoint.Y) = MouseDownZone) then
- begin
- HandleZoneClick(MouseDownZone);
- NewElapse := 100;
- end;
- AUTO_SCROLL_TIMER: if AutoScrolling then
- begin
- NewElapse := AutoScrollInterval;
- UpdatePosition(Position + AutoScrollDirection);
- if (Position = 0) or (Position + Window = Range) then NewElapse := 0;
- if Assigned(FOnAutoScroll) then
- FOnAutoScroll(Self, AutoScrollDirection, AutoScrollInterval);
- AutoScrolling := NewElapse > 0;
- end;
- end;
- end;
- procedure TTBXScrollBar.UpdatePosition(NewPosition: Integer);
- begin
- UserChange := True;
- if NewPosition < 0 then NewPosition := 0;
- if NewPosition > Range - Window then NewPosition := Range - Window;
- Position := NewPosition;
- UserChange := False;
- end;
- procedure TTBXScrollBar.UpdateZones;
- var
- SzL, SzT: Integer;
- ButtonSize: Integer;
- Lo, Hi: Integer;
- HandleSize, HandlePos: Integer;
- Window: Integer;
- IsVert: Boolean;
- procedure SetZone(var R: TRect; Lo, Hi: Integer);
- begin
- if IsVert then
- begin
- R.Left := 0;
- R.Right := Width;
- R.Top := Lo;
- R.Bottom := Hi;
- end
- else
- begin
- R.Left := Lo;
- R.Right := Hi;
- R.Top := 0;
- R.Bottom := Height;
- end;
- end;
- begin
- IsVert := Kind = sbVertical;
- Window := GetEffectiveWindow;
- if IsVert then
- begin
- SzL := Height;
- SzT := Width;
- end
- else
- begin
- SzL := Width;
- SzT := Height;
- end;
- { Buttons }
- ButtonSize := SzT;
- if ButtonSize * 2 >= SzL - 2 then ButtonSize := (SzL - 2) div 2;
- SetZone(Zones[sbzPrev], 0, ButtonSize);
- SetZone(Zones[sbzNext], SzL - ButtonSize, SzL);
- { Handle }
- Lo := ButtonSize;
- Hi := SzL - ButtonSize;
- if GetEnabled and (Hi - Lo > MIN_SB_HANDLE_SIZE + 4) then
- begin
- HandleSize := Round((Hi - Lo) * Window / Range);
- if HandleSize >= MIN_SB_HANDLE_SIZE then
- HandlePos := Round((Hi - Lo) * Position / Range)
- else
- begin
- HandleSize := MIN_SB_HANDLE_SIZE;
- HandlePos := Round((Hi - Lo - MIN_SB_HANDLE_SIZE) * Position / (Range - Window));
- end;
- Inc(HandlePos, Lo);
- SetZone(Zones[sbzHandle], HandlePos, HandlePos + HandleSize);
- SetZone(Zones[sbzPagePrev], Lo, HandlePos);
- SetZone(Zones[sbzPageNext], HandlePos + HandleSize, Hi);
- Zones[sbzEmpty].Right := -1;
- end
- else
- begin
- { Invalidate invisible zones }
- Zones[sbzPagePrev].Right := -1;
- Zones[sbzHandle].Right := -1;
- Zones[sbzPageNext].Right := -1;
- SetZone(Zones[sbzEmpty], Lo, Hi);
- end;
- end;
- //----------------------------------------------------------------------------//
- { TTBXCustomList }
- constructor TTBXCustomList.Create(AOwner: TComponent);
- begin
- inherited;
- FMinWidth := 32;
- FMaxWidth := 0;
- FMaxVisibleItems := 8;
- FItemIndex := -1;
- end;
- function TTBXCustomList.DoClearItem(ACanvas: TCanvas; ARect: TRect; AIndex, AHoverIndex: Integer): Boolean;
- begin
- Result := True;
- if Assigned(FOnClearItem) then FOnClearItem(Self, ACanvas, ARect, AIndex, AHoverIndex, Result);
- end;
- function TTBXCustomList.DoDrawItem(ACanvas: TCanvas; {MP} var ARect: TRect; AIndex, AHoverIndex: Integer): Boolean;
- begin
- Result := True;
- if Assigned(FOnDrawItem) then FOnDrawItem(Self, ACanvas, ARect, AIndex, AHoverIndex, Result);
- end;
- procedure TTBXCustomList.DoMeasureHeight(ACanvas: TCanvas; var AHeight: Integer);
- begin
- if Assigned(FOnMeasureHeight) then FOnMeasureHeight(Self, ACanvas, AHeight);
- end;
- procedure TTBXCustomList.DoMeasureWidth(ACanvas: TCanvas; AIndex: Integer; var AWidth: Integer);
- begin
- if Assigned(FOnMeasureWidth) then FOnMeasureWidth(Self, ACanvas, AIndex, AWidth);
- end;
- procedure TTBXCustomList.DrawItem(ACanvas: TCanvas; AViewer: TTBXCustomListViewer;
- const ARect: TRect; AIndex, AHoverIndex: Integer);
- const
- FillColors: array [Boolean] of TColor = (clWindow, clHighlight);
- TextColors: array [Boolean] of TColor = (clWindowText, clHighlightText);
- var
- S: string;
- R, R2: TRect;
- ImgList: TCustomImageList;
- begin
- ACanvas.Brush.Color := FillColors[AIndex = AHoverIndex];
- if DoClearItem(ACanvas, ARect, AIndex, AHoverIndex) then ACanvas.FillRect(ARect);
- ACanvas.Font.Color := TextColors[AIndex = AHoverIndex];
- R := ARect; {MP}
- if DoDrawItem(ACanvas, {MP} R, AIndex, AHoverIndex) then
- begin
- InflateRect(R, -4, 1);
- ImgList := AViewer.GetImageList;
- if ShowImages and (ImgList <> nil) then
- begin
- R2.Left := R.Left;
- R2.Top := (R.Top + R.Bottom - ImgList.Height) div 2;
- R2.Right := R2.Left + ImgList.Width;
- R2.Bottom := R2.Top + ImgList.Height;
- if Enabled then ImgList.Draw(ACanvas, R2.Left, R2.Top, GetImageIndex(AIndex))
- else DrawTBXImage(ACanvas, R2, ImgList, GetImageIndex(AIndex), ISF_DISABLED);
- Inc(R.Left, ImgList.Width + CImageSpacing);
- end;
- S := GetItemText(AIndex);
- if Length(S) > 0 then
- begin
- ACanvas.Brush.Style := bsClear;
- DrawText(ACanvas.Handle, PChar(S), Length(S), R, DT_SINGLELINE or DT_VCENTER {MP DEL});
- ACanvas.Brush.Style := bsSolid;
- end;
- end;
- end;
- function TTBXCustomList.GetImageIndex(ItemIndex: Integer): Integer;
- begin
- Result := ItemIndex;
- if Assigned(FOnAdjustImageIndex) then FOnAdjustImageIndex(Self, ItemIndex, Result);
- end;
- function TTBXCustomList.GetItemViewerClass(AView: TTBView): TTBItemViewerClass;
- begin
- Result := TTBXCustomListViewer;
- end;
- procedure TTBXCustomList.HandleChange;
- begin
- if Assigned(FOnChange) then FOnChange(Self);
- end;
- procedure TTBXCustomList.HandleHover(AIndex: Integer);
- begin
- end;
- procedure TTBXCustomList.MakeVisible(AIndex: Integer);
- var
- I: Integer;
- begin
- if FViewers <> nil then
- for I := 0 to FViewers.Count - 1 do
- TTBXCustomListViewer(FViewers[I]).MakeVisible(AIndex);
- end;
- procedure TTBXCustomList.Notification(AComponent: TComponent; Operation: TOperation);
- begin
- inherited Notification(AComponent, Operation);
- if (Operation = opRemove) and (AComponent = Images) then Images := nil;
- end;
- procedure TTBXCustomList.SetItemIndex(Value: Integer);
- var
- I: Integer;
- begin
- if Value < 0 then Value := -1;
- FItemIndex := Value;
- { Update viewers }
- if FViewers <> nil then
- for I := 0 to FViewers.Count - 1 do
- TTBXCustomListViewer(FViewers[I]).ListChangeHandler(Value);
- if Assigned(FOnChange) then FOnChange(Self);
- end;
- procedure TTBXCustomList.ChangeScale(M, D: Integer);
- begin
- inherited;
- MaxWidth := MulDiv(MaxWidth, M, D);
- MinWidth := MulDiv(MinWidth, M, D);
- end;
- //----------------------------------------------------------------------------//
- { TTBXCustomListViewer }
- procedure TTBXCustomListViewer.AdjustAutoScrollHover(var AIndex: Integer; Direction: Integer);
- begin
- AIndex := -1; // turn off hover when autoscrolling
- end;
- procedure TTBXCustomListViewer.CalcSize(const Canvas: TCanvas; var AWidth, AHeight: Integer);
- var
- Item: TTBXCustomList;
- I, W: Integer;
- AView: TTBView;
- begin
- Item := TTBXCustomList(Self.Item);
- Canvas.Font := TTBViewAccess(View).GetFont;
- FItemCount := Item.GetCount;
- FItemHeight := GetItemHeight(Canvas);
- FVisibleItems := FItemCount;
- if FVisibleItems > Item.MaxVisibleItems then FVisibleItems := Item.MaxVisibleItems
- else if FVisibleItems <= 0 then FVisibleItems := 1;
- AHeight := FVisibleItems * FItemHeight;
- AWidth := 0;
- for I := 0 to FItemCount - 1 do
- begin
- W := GetItemWidth(Canvas, I);
- if W > AWidth then AWidth := W;
- end;
- if FItemCount > FVisibleItems then
- begin
- // At this moment, this view window may not be parented yet, so use window of root view
- AView := View;
- while AView.ParentView <> nil do AView := AView.ParentView;
- FScrollBarWidth := GetSystemMetricsForControl(AView.Window, SM_CXVSCROLL);
- end
- else
- begin
- FScrollBarWidth := 0;
- end;
- Inc(AWidth, FScrollBarWidth);
- if AWidth < Item.MinWidth then AWidth := Item.MinWidth;
- if (Item.MaxWidth > Item.MinWidth) and (AWidth > Item.MaxWidth) then AWidth := Item.MaxWidth;
- end;
- constructor TTBXCustomListViewer.Create(AView: TTBView; AItem: TTBCustomItem; AGroupLevel: Integer);
- var
- Index: Integer;
- begin
- inherited;
- Index := TTBXCustomList(AItem).ItemIndex;
- FItemCount := TTBXCustomList(AItem).GetCount;
- if (Index >= 0) and (Index < FItemCount) then
- with TTBXCustomList(AItem) do
- begin
- FVisibleItems := GetCount;
- if FVisibleItems > MaxVisibleItems then FVisibleItems := MaxVisibleItems;
- if Index < FOffset then FOffset := Index
- else if Index >= FOffset + FVisibleItems then FOffset := Index - FVisibleItems + 1
- end;
- FHoverIndex := Index;
- if FHoverIndex > FItemCount then FHoverIndex := -1;
- AddToList(TTBXCustomList(AItem).FViewers, Self);
- end;
- destructor TTBXCustomListViewer.Destroy;
- begin
- RemoveFromList(TTBXCustomList(Item).FViewers, Self);
- if FScrollBar <> nil then FScrollBar.Free;
- inherited;
- end;
- procedure TTBXCustomListViewer.DrawItems(const Canvas: TCanvas; const ClientAreaRect: TRect);
- var
- I: Integer;
- R: TRect;
- begin
- R := ClientAreaRect;
- R.Bottom := FItemHeight;
- Dec(R.Right, FScrollBarWidth);
- Canvas.Font := TTBViewAccess(View).GetFont;
- for I := FOffset to FItemCount - 1 do
- begin
- if RectVisible(Canvas.Handle, R) then
- TTBXCustomList(Item).DrawItem(Canvas, Self, R, I, HoverIndex);
- R.Top := R.Bottom;
- Inc(R.Bottom, FItemHeight);
- if R.Bottom > FHeight then Break;
- end;
- if R.Top < ClientAreaRect.Bottom then
- begin
- R.Bottom := ClientAreaRect.Bottom;
- Canvas.Brush.Color := clWindow;
- Canvas.FillRect(R);
- end;
- end;
- function TTBXCustomListViewer.GetItemHeight(ACanvas: TCanvas): Integer;
- var
- ImgList: TCustomImageList;
- begin
- Result := ACanvas.TextHeight('Q') + 2;
- with TTBXStringList(Item) do
- begin
- ImgList := GetImageList;
- if ShowImages and (ImgList <> nil) and (Result < ImgList.Height + 2) then
- Result := ImgList.Height + 2;
- DoMeasureHeight(ACanvas, Result);
- end;
- end;
- function TTBXCustomListViewer.GetItemIndexAt(X, Y: Integer): Integer;
- begin
- if (X < 0) or (X > FWidth - FScrollBarWidth) then Result := -1
- else
- begin
- Result := (Y div FItemHeight) + FOffset;
- if (Result < FOffset) or (Result >= FOffset + FVisibleItems) or (Result >= FItemCount) then
- Result := - 1;
- end;
- end;
- function TTBXCustomListViewer.GetItemRect(Index: Integer): TRect;
- begin
- { Note this method works properly only after Draw is called }
- Result := FLastClientRect;
- Inc(Result.Top, (Index - FOffset) * FItemHeight);
- Result.Bottom := Result.Top + FItemHeight;
- Dec(Result.Right, FScrollBarWidth);
- end;
- function TTBXCustomListViewer.GetItemWidth(ACanvas: TCanvas; Index: Integer): Integer;
- var
- S: string;
- ImgList: TCustomImageList;
- begin
- with TTBXStringList(Item) do
- begin
- S := GetItemText(Index);
- Result := ACanvas.TextWidth(S);
- if ShowImages then
- begin
- ImgList := GetImageList;
- if ImgList <> nil then
- begin
- Inc(Result, ImgList.Width);
- if Length(S) > 0 then Inc(Result, CImageSpacing);
- end;
- end;
- Inc(Result, 8);
- DoMeasureWidth(ACanvas, Index, Result)
- end;
- end;
- procedure TTBXCustomListViewer.HandleAutoScroll(var Direction, Interval: Integer);
- begin
- // do nothing by default
- end;
- procedure TTBXCustomListViewer.KeyDown(var Key: Word; Shift: TShiftState);
- var
- OldIndex, NewIndex, Index: Integer;
- DAD: TTBDoneActionData;
- begin
- OldIndex := FHoverIndex;
- case Key of
- VK_UP: NewIndex := OldIndex - 1;
- VK_DOWN: NewIndex := OldIndex + 1;
- VK_PRIOR: NewIndex := OldIndex - FVisibleItems;
- VK_NEXT: NewIndex := OldIndex + FVisibleItems;
- VK_HOME: NewIndex := 0;
- VK_END: NewIndex := FItemCount - 1;
- VK_RETURN:
- begin
- TTBXCustomList(Item).ItemIndex := FHoverIndex;
- Exit;
- end;
- {MP}
- Word('A')..Word('Z'), Word('a')..Word('z'):
- begin
- NewIndex := OldIndex;
- for Index := FHoverIndex + 1 to FHoverIndex + FItemCount do
- begin
- if IsAccel(Key, TTBXStringList(Item).GetItemText(Index mod FItemCount)) then
- begin
- NewIndex := Index mod FItemCount;
- // exit modal loop
- DAD := TTBViewAccess(TTBViewAccess(View).GetRootView).DoneActionData;
- DAD.ClickItem := Item;
- DAD.DoneAction := tbdaClickItem;
- DAD.Sound := True;
- TTBViewAccess(TTBViewAccess(View).GetRootView).DoneActionData := DAD;
- Break;
- end;
- end;
- Key := 0;
- end;
- else
- Exit;
- end;
- Key := 0;
- if NewIndex < 0 then NewIndex := 0;
- if NewIndex >= FItemCount then NewIndex := FItemCount - 1;
- TTBXCustomList(Item).ItemIndex := NewIndex;
- end;
- procedure TTBXCustomListViewer.ListChangeHandler(NewIndex: Integer);
- begin
- if not IsChanging and (NewIndex <> HoverIndex) then
- begin
- IsChanging := True;
- HoverIndex := NewIndex;
- TTBXCustomList(Item).HandleHover(NewIndex);
- MakeVisible(HoverIndex);
- UpdateItems;
- IsChanging := False;
- end;
- end;
- procedure TTBXCustomListViewer.MakeVisible(Index: Integer);
- begin
- if (Index >= 0) and (Index < FItemCount) then
- begin
- if Index < FOffset then FScrollBar.UpdatePosition(Index)
- else if Index >= FOffset + FVisibleItems then FScrollBar.UpdatePosition(Index - FVisibleItems + 1);
- end;
- end;
- procedure TTBXCustomListViewer.MouseDown(Shift: TShiftState; X, Y: Integer; var MouseDownOnMenu: Boolean);
- begin
- if X > FWidth - FScrollBarWidth then
- begin
- Dec(X, FWidth - FScrollBarWidth);
- MouseInScrollBar := True;
- FScrollBar.MouseDown(mbLeft, X, Y);
- MouseDownOnMenu := False;
- end
- else
- begin
- MouseIsDown := True;
- MouseMove(X, Y);
- end;
- inherited;
- View.SetCapture;
- end;
- procedure TTBXCustomListViewer.MouseMove(X, Y: Integer);
- var
- NewHoverIndex, OldHoverIndex, IndexLo, IndexHi, I: Integer;
- R: TRect;
- Canvas: TCanvas;
- DC: HDC;
- V, Dir: Integer;
- begin
- if MouseInScrollBar then
- begin
- Dec(X, FWidth - FScrollBarWidth);
- FScrollBar.MouseMove(X, Y);
- Exit;
- end;
- if not View.Capture and (GetKeyState(VK_LBUTTON) < 0) then
- begin
- View.SetCapture;
- MouseIsDown := True;
- end;
- NewHoverIndex := GetItemIndexAt(X, Y);
- if FScrollBar <> nil then
- begin
- if MouseIsDown and ((Y < 0) or (Y >= FHeight)) then
- begin
- { Get AutoScroll Intervals }
- V := Y;
- if V >= FHeight then Dec(V, FHeight - 1);
- V := Abs(V);
- if Y < 0 then Dir := -1 else Dir := 1;
- case V of
- 0..9: V := 150;
- 10..29: V := 100;
- 30..50: begin V := 100; Dir := Dir * 2; end;
- else
- V := 100;
- Dir := Dir * 4;
- end;
- if ((Dir < 0) and (FOffset > 0)) or
- ((Dir > 0) and (FOffset + FVisibleItems < FItemCount)) then
- FScrollBar.StartAutoScroll(Dir, V)
- else
- FScrollBar.StopAutoScroll;
- AdjustAutoScrollHover(NewHoverIndex, Dir);
- end
- else FScrollBar.StopAutoScroll;
- end;
- if not MouseIsDown and (NewHoverIndex = -1) then Exit;
- if NewHoverIndex <> FHoverIndex then
- begin
- Canvas := TCanvas.Create;
- DC := GetDC(View.Window.Handle);
- OldHoverIndex := FHoverIndex;
- FHoverIndex := NewHoverIndex;
- try
- SetWindowOrgEx(DC, -BoundsRect.Left, -BoundsRect.Top, nil);
- Canvas.Handle := DC;
- Canvas.Font := TTBViewAccess(View).GetFont;
- IndexLo := OldHoverIndex;
- IndexHi := FHoverIndex;
- if FHoverIndex < OldHoverIndex then
- begin
- IndexLo := FHoverIndex;
- IndexHi := OldHoverIndex;
- end;
- for I := IndexLo to IndexHi do
- begin
- R := GetItemRect(I);
- if (R.Top >= 0) and (R.Bottom <= FHeight) and RectVisible(DC, R) then
- TTBXCustomList(Item).DrawItem(Canvas, Self, R, I, HoverIndex);
- end;
- finally
- Canvas.Handle := 0;
- Canvas.Free;
- ReleaseDC(View.Window.Handle, DC);
- end;
- TTBXCustomList(Item).HandleHover(FHoverIndex);
- end;
- end;
- procedure TTBXCustomListViewer.MouseUp(X, Y: Integer; MouseWasDownOnMenu: Boolean);
- var
- DAD: TTBDoneActionData;
- begin
- if FScrollBar <> nil then FScrollBar.StopAutoScroll;
- if MouseInScrollBar then
- begin
- inherited;
- Dec(X, FWidth - FScrollBarWidth);
- FScrollBar.MouseUp(mbLeft, X, Y);
- DAD := TTBViewAccess(TTBViewAccess(View).GetRootView).DoneActionData;
- DAD.DoneAction := tbdaNone;
- TTBViewAccess(TTBViewAccess(View).GetRootView).DoneActionData := DAD;
- MouseInScrollBar := False;
- end
- else if MouseIsDown then
- begin
- MouseIsDown := False;
- TTBXCustomList(Item).ItemIndex := FHoverIndex;
- inherited;
- DAD := TTBViewAccess(TTBViewAccess(View).GetRootView).DoneActionData;
- DAD.Sound := False;
- TTBViewAccess(TTBViewAccess(View).GetRootView).DoneActionData := DAD;
- end;
- end;
- procedure TTBXCustomListViewer.MouseWheel(WheelDelta, X, Y: Integer);
- var
- IsNegative: Boolean;
- begin
- if FScrollBar <> nil then
- begin
- Inc(FWheelAccumulator, WheelDelta);
- while Abs(FWheelAccumulator) >= WHEEL_DELTA do
- begin
- IsNegative := FWheelAccumulator < 0;
- FWheelAccumulator := Abs(FWheelAccumulator) - WHEEL_DELTA;
- if IsNegative then
- begin
- if FWheelAccumulator <> 0 then FWheelAccumulator := -FWheelAccumulator;
- FScrollBar.UpdatePosition(FScrollBar.Position + 1)
- end
- else
- FScrollBar.UpdatePosition(FScrollBar.Position - 1)
- end;
- end;
- end;
- procedure TTBXCustomListViewer.Paint(const Canvas: TCanvas;
- const ClientAreaRect: TRect; IsHoverItem, IsPushed, UseDisabledShadow: Boolean);
- begin
- { Cache some important info for later usage }
- FLastClientRect := ClientAreaRect;
- with ClientAreaRect do
- begin
- FWidth := Right - Left;
- FHeight := Bottom - Top;
- end;
- DrawItems(Canvas, ClientAreaRect);
- if FScrollBarWidth > 0 then
- begin
- if FScrollBar = nil then
- begin
- FScrollBar := TTBXScrollBar.Create;
- FScrollBar.Kind := sbVertical;
- FScrollBar.OnRedrawRequest := SBRedrawHandler;
- FScrollBar.OnChange := SBChangeHandler;
- FScrollBar.OnAutoScroll := SBAutoScrollHandler;
- end;
- FScrollBar.Bounds := Rect(ClientAreaRect.Right - FScrollBarWidth,
- ClientAreaRect.Top, ClientAreaRect.Right, ClientAreaRect.Bottom);
- FScrollBar.Range := FItemCount;
- FScrollBar.Window := FVisibleItems;
- FScrollBar.Position := FOffset;
- FScrollBar.PaintTo(Canvas);
- end;
- end;
- procedure TTBXCustomListViewer.SBAutoScrollHandler(Sender: TObject;
- var Direction, Interval: Integer);
- begin
- HandleAutoScroll(Direction, Interval);
- end;
- procedure TTBXCustomListViewer.SBChangeHandler(Sender: TObject);
- begin
- FOffset := FScrollBar.Position;
- UpdateItems;
- end;
- procedure TTBXCustomListViewer.SBRedrawHandler(Sender: TObject);
- var
- DC: HDC;
- Canvas: TCanvas;
- begin
- Canvas := TCanvas.Create;
- DC := GetDC(View.Window.Handle);
- try
- SetWindowOrgEx(DC, -BoundsRect.Left, -BoundsRect.Top, nil);
- Canvas.Handle := DC;
- FScrollBar.PaintTo(Canvas);
- finally
- Canvas.Handle := 0;
- Canvas.Free;
- ReleaseDC(View.Window.Handle, DC);
- end;
- end;
- procedure TTBXCustomListViewer.UpdateItems;
- var
- DC: HDC;
- Canvas: TCanvas;
- begin
- if Assigned(FScrollBar) then FOffset := FScrollBar.Position
- else FOffset := 0;
- Canvas := TCanvas.Create;
- DC := GetDC(View.Window.Handle);
- try
- SetWindowOrgEx(DC, -BoundsRect.Left, -BoundsRect.Top, nil);
- Canvas.Handle := DC;
- DrawItems(Canvas, FLastClientRect);
- finally
- Canvas.Handle := 0;
- Canvas.Free;
- ReleaseDC(View.Window.Handle, DC);
- end;
- end;
- //----------------------------------------------------------------------------//
- { TTBXStringList }
- constructor TTBXStringList.Create(AOwner: TComponent);
- begin
- inherited;
- FStrings := TStringList.Create;
- end;
- destructor TTBXStringList.Destroy;
- begin
- FStrings.Free;
- inherited;
- end;
- function TTBXStringList.GetCount: Integer;
- begin
- Result := FStrings.Count;
- end;
- function TTBXStringList.GetItemText(Index: Integer): string;
- begin
- Result := FStrings[Index];
- end;
- procedure TTBXStringList.SetStrings(Value: TStrings);
- begin
- FStrings.Assign(Value);
- end;
- end.
|