📄 rxctrls.pas
字号:
procedure TRxListBoxStrings.InternalSetHint(Index: Integer; Hint: String);
begin // No checks, just centralised asignment and so on
If Assigned(FhintStrings) then begin
{$IfDef RLBS_calc_hints}
if FHintStrings^[Index]<> '' then Dec(FHintQuantity);
if Hint <> '' then Inc(FHintQuantity);
{$EndIf}
FHintStrings^[Index]:=Hint;
end {$IfDef RLBS_calc_hints} else FHintQuantity:=0 {$EndIf} ;
end;
procedure TRxListBoxStrings.SetHint(Index: Integer; Hint: String);
var sz: integer;
begin
sz:=FHintCapacity; if sz=0 then sz:=GetCount;
if (Index<0) or (Index>=sz) then
Error(SListIndexError, Index);
if Hint <> '' then if FHintStrings = nil then AllocHints;
InternalSetHint(Index,Hint);
end;
constructor TRxListBoxStrings.Create;
begin
inherited;
FHintStrings:=nil; FHintCapacity:=0;
{$IfDef RLBS_calc_hints} FHintSetQuantity:=0; {$EndIf}
end;
destructor TRxListBoxStrings.Destroy;
begin
DropHints; // interesting, why TStrings.Destroy doesnt call Clear?
inherited;
end;
procedure TRxListBoxStrings.Assign(Source: TPersistent);
var i: integer;
begin
inherited;
DropHints;
if Source is TRxListBoxStrings then
With Source as TRxListBoxStrings do begin
if Assigned(FHintStrings) then
for i:=0 to GetCount-1 do
Self.SetHint(i,GetHint(i));
end;
end;
{ TRxCustomListBox }
procedure ListIndexError(Index: Integer);
function ReturnAddr: Pointer;
asm
MOV EAX,[EBP+4]
end;
begin
{$IFDEF RX_D3}
raise EStringListError.CreateFmt(SListIndexError, [Index]) at ReturnAddr;
{$ELSE}
raise EStringListError.CreateFmt('%s: %d', [LoadStr(SListIndexError),
Index]) at ReturnAddr;
{$ENDIF}
end;
constructor TRxCustomListBox.Create(AOwner: TComponent);
const
ListBoxStyle = [csSetCaption, csDoubleClicks];
begin
inherited Create(AOwner);
if NewStyleControls then ControlStyle := ListBoxStyle
else ControlStyle := ListBoxStyle + [csFramed];
Width := 121;
Height := 97;
TabStop := True;
ParentColor := False;
FItems := CreateItemList;
TRxListBoxStrings(FItems).ListBox := Self;
FCanvas := TControlCanvas.Create;
TControlCanvas(FCanvas).Control := Self;
FItemHeight := 16;
FBorderStyle := bsSingle;
FExtendedSelect := True;
FHintSource := hsDefault;
FOnGetItemHintEvent := nil;
end;
destructor TRxCustomListBox.Destroy;
begin
inherited Destroy;
FCanvas.Free;
FItems.Free;
FSaveItems.Free;
end;
function TRxCustomListBox.CreateItemList: TStrings;
begin
Result := TRxListBoxStrings.Create;
end;
function TRxCustomListBox.GetItemData(Index: Integer): LongInt;
begin
Result := SendMessage(Handle, LB_GETITEMDATA, Index, 0);
end;
procedure TRxCustomListBox.SetItemData(Index: Integer; AData: LongInt);
begin
SendMessage(Handle, LB_SETITEMDATA, Index, AData);
end;
procedure TRxCustomListBox.DeleteString(Index: Integer);
begin
If SendMessage(Handle, LB_DELETESTRING, Index, 0) //why not in TRxListBoxstrings as .Add and .Insert?
<> LB_ERR then if Fitems is TRxListBoxstrings
then (FItems as TRxListBoxstrings ).DeleteHintCell(Index);
end;
procedure TRxCustomListBox.SetHorizontalExtent;
begin
SendMessage(Handle, LB_SETHORIZONTALEXTENT, FMaxItemWidth, 0);
end;
function TRxCustomListBox.GetItemWidth(Index: Integer): Integer;
var
ATabWidth: Longint;
S: string;
begin
if (Style <> lbStandard) and Assigned(FOnGetItemWidth) and
Assigned(FOnDrawItem) then
begin
Result := 0;
FOnGetItemWidth(Self, Index, Result);
end
else begin
S := Items[Index] + 'x';
if TabWidth > 0 then begin
{if (FTabChar > #0) then
for I := 1 to Length(S) do
if S[I] = FTabChar then S[I] := #9;}
ATabWidth := Round((TabWidth * Canvas.TextWidth('0')) * 0.25);
Result := LoWord(GetTabbedTextExtent(Canvas.Handle, @S[1], Length(S),
1, ATabWidth));
end
else Result := Canvas.TextWidth(S);
end;
end;
procedure TRxCustomListBox.ResetHorizontalExtent;
var
I: Integer;
begin
FMaxItemWidth := 0;
for I := 0 to Items.Count - 1 do
FMaxItemWidth := Max(FMaxItemWidth, GetItemWidth(I));
SetHorizontalExtent;
end;
procedure TRxCustomListBox.ResetContent;
begin
SendMessage(Handle, LB_RESETCONTENT, 0, 0);
end;
procedure TRxCustomListBox.Clear;
begin
FItems.Clear;
end;
procedure TRxCustomListBox.SetColumnWidth;
begin
if FColumns > 0 then
SendMessage(Handle, LB_SETCOLUMNWIDTH, (Width + FColumns - 3) div
FColumns, 0);
end;
procedure TRxCustomListBox.SetColumns(Value: Integer);
begin
if FColumns <> Value then
if (FColumns = 0) or (Value = 0) then begin
FColumns := Value;
RecreateWnd;
end
else begin
FColumns := Value;
if HandleAllocated then SetColumnWidth;
end;
end;
function TRxCustomListBox.GetItemIndex: Integer;
begin
Result := SendMessage(Handle, LB_GETCURSEL, 0, 0);
end;
function TRxCustomListBox.GetSelCount: Integer;
begin
Result := SendMessage(Handle, LB_GETSELCOUNT, 0, 0);
end;
procedure TRxCustomListBox.SetItemIndex(Value: Integer);
begin
if GetItemIndex <> Value then
SendMessage(Handle, LB_SETCURSEL, Value, 0);
end;
procedure TRxCustomListBox.SetExtendedSelect(Value: Boolean);
begin
if Value <> FExtendedSelect then begin
FExtendedSelect := Value;
RecreateWnd;
end;
end;
procedure TRxCustomListBox.SetIntegralHeight(Value: Boolean);
begin
if Value <> FIntegralHeight then begin
FIntegralHeight := Value;
RecreateWnd;
end;
end;
function TRxCustomListBox.GetAutoScroll: Boolean;
begin
Result := FAutoScroll and (Columns = 0);
end;
procedure TRxCustomListBox.SetOnDrawItem(Value: TDrawItemEvent);
begin
if Assigned(FOnDrawItem) <> Assigned(Value) then begin
FOnDrawItem := Value;
Perform(WM_HSCROLL, SB_TOP, 0);
if HandleAllocated then
if AutoScroll then ResetHorizontalExtent
else SendMessage(Handle, LB_SETHORIZONTALEXTENT, 0, 0);
end
else FOnDrawItem := Value;
end;
procedure TRxCustomListBox.SetOnGetItemWidth(Value: TGetItemWidthEvent);
begin
if Assigned(FOnGetItemWidth) <> Assigned(Value) then begin
FOnGetItemWidth := Value;
Perform(WM_HSCROLL, SB_TOP, 0);
if HandleAllocated then
if AutoScroll then ResetHorizontalExtent
else SendMessage(Handle, LB_SETHORIZONTALEXTENT, 0, 0);
end
else FOnGetItemWidth := Value;
end;
procedure TRxCustomListBox.SetAutoScroll(Value: Boolean);
begin
if AutoScroll <> Value then begin
FAutoScroll := Value;
Perform(WM_HSCROLL, SB_TOP, 0);
if HandleAllocated then begin
if AutoScroll then ResetHorizontalExtent
else SendMessage(Handle, LB_SETHORIZONTALEXTENT, 0, 0);
end;
end;
end;
function TRxCustomListBox.GetItemHeight: Integer;
var
R: TRect;
begin
Result := FItemHeight;
if HandleAllocated and (FStyle = lbStandard) then begin
Perform(LB_GETITEMRECT, 0, Longint(@R));
Result := R.Bottom - R.Top;
end;
end;
procedure TRxCustomListBox.SetItemHeight(Value: Integer);
begin
if (FItemHeight <> Value) and (Value > 0) then begin
FItemHeight := Value;
RecreateWnd;
end;
end;
procedure TRxCustomListBox.SetTabWidth(Value: Integer);
begin
if Value < 0 then Value := 0;
if FTabWidth <> Value then begin
FTabWidth := Value;
RecreateWnd;
end;
end;
procedure TRxCustomListBox.SetMultiSelect(Value: Boolean);
begin
if FMultiSelect <> Value then begin
FMultiSelect := Value;
RecreateWnd;
end;
end;
function TRxCustomListBox.GetSelected(Index: Integer): Boolean;
var
R: Longint;
begin
R := SendMessage(Handle, LB_GETSEL, Index, 0);
if R = LB_ERR then ListIndexError(Index);
Result := LongBool(R);
end;
procedure TRxCustomListBox.SetSelected(Index: Integer; Value: Boolean);
begin
if MultiSelect then begin
if SendMessage(Handle, LB_SETSEL, Ord(Value), Index) = LB_ERR then
ListIndexError(Index);
end
else begin
if Value then SetItemIndex(Index)
else if (ItemIndex = Index) then SetItemIndex(-1);
end;
end;
procedure TRxCustomListBox.SetSorted(Value: Boolean);
begin
if FSorted <> Value then begin
FSorted := Value;
RecreateWnd;
end;
end;
procedure TRxCustomListBox.SetStyle(Value: TListBoxStyle);
begin
if FStyle <> Value then begin
FStyle := Value;
RecreateWnd;
end;
end;
function TRxCustomListBox.GetTopIndex: Integer;
begin
Result := SendMessage(Handle, LB_GETTOPINDEX, 0, 0);
end;
procedure TRxCustomListBox.SetBorderStyle(Value: TBorderStyle);
begin
if FBorderStyle <> Value then begin
FBorderStyle := Value;
RecreateWnd;
end;
end;
procedure TRxCustomListBox.SetTopIndex(Value: Integer);
begin
if GetTopIndex <> Value then SendMessage(Handle, LB_SETTOPINDEX, Value, 0);
end;
procedure TRxCustomListBox.SetGraySelection(Value: Boolean);
begin
if FGraySelection <> Value then begin
FGraySelection := Value;
if not Focused then Invalidate;
end;
end;
procedure TRxCustomListBox.SetItems(Value: TStrings);
begin
Items.Assign(Value);
end;
function TRxCustomListBox.ItemAtPos(Pos: TPoint; Existing: Boolean): Integer;
var
Count: Integer;
ItemRect: TRect;
begin
if PtInRect(ClientRect, Pos) then begin
Result := TopIndex;
Count := Items.Count;
while Result < Count do begin
Perform(LB_GETITEMRECT, Result, Longint(@ItemRect));
if PtInRect(ItemRect, Pos) then Exit;
Inc(Result);
end;
if not Existing then Exit;
end;
Result := -1;
end;
function TRxCustomListBox.ItemRect(Index: Integer): TRect;
var
Count: Integer;
begin
Count := Items.Count;
if (Index = 0) or (Index < Count) then
Perform(LB_GETITEMRECT, Index, Longint(@Result))
else if Index = Count then begin
Perform(LB_GETITEMRECT, Index - 1, Longint(@Result));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -