📄 rxctrls.pas
字号:
procedure TRxCustomListBox.WMLButtonDown(var Message: TWMLButtonDown);
var
ItemNo: Integer;
ShiftState: TShiftState;
begin
ShiftState := KeysToShiftState(Message.Keys);
if (DragMode = dmAutomatic) and FMultiSelect then begin
if not (ssShift in ShiftState) or (ssCtrl in ShiftState) then begin
ItemNo := ItemAtPos(SmallPointToPoint(Message.Pos), True);
if (ItemNo >= 0) and (Selected[ItemNo]) then begin
BeginDrag(False);
Exit;
end;
end;
end;
inherited;
if (DragMode = dmAutomatic) and not (FMultiSelect and
((ssCtrl in ShiftState) or (ssShift in ShiftState))) then
BeginDrag(False);
end;
procedure TRxCustomListBox.WMNCHitTest(var Msg: TWMNCHitTest);
begin
if csDesigning in ComponentState then DefaultHandler(Msg)
else inherited;
end;
procedure TRxCustomListBox.CNCommand(var Message: TWMCommand);
begin
case Message.NotifyCode of
LBN_SELCHANGE:
begin
{$IFDEF RX_D3}
inherited Changed;
{$ENDIF}
Click;
end;
LBN_DBLCLK: DblClick;
end;
end;
procedure TRxCustomListBox.WMPaint(var Message: TWMPaint);
procedure PaintListBox;
var
DrawItemMsg: TWMDrawItem;
MeasureItemMsg: TWMMeasureItem;
DrawItemStruct: TDrawItemStruct;
MeasureItemStruct: TMeasureItemStruct;
R: TRect;
Y, I, H, W: Integer;
begin
{ Initialize drawing records }
DrawItemMsg.Msg := CN_DRAWITEM;
DrawItemMsg.DrawItemStruct := @DrawItemStruct;
DrawItemMsg.Ctl := Handle;
DrawItemStruct.CtlType := ODT_LISTBOX;
DrawItemStruct.itemAction := ODA_DRAWENTIRE;
DrawItemStruct.itemState := 0;
DrawItemStruct.hDC := Message.DC;
DrawItemStruct.CtlID := Handle;
DrawItemStruct.hwndItem := Handle;
{ Intialize measure records }
MeasureItemMsg.Msg := CN_MEASUREITEM;
MeasureItemMsg.IDCtl := Handle;
MeasureItemMsg.MeasureItemStruct := @MeasureItemStruct;
MeasureItemStruct.CtlType := ODT_LISTBOX;
MeasureItemStruct.CtlID := Handle;
{ Draw the listbox }
Y := 0;
I := TopIndex;
GetClipBox(Message.DC, R);
H := Height;
W := Width;
while Y < H do begin
MeasureItemStruct.itemID := I;
if I < Items.Count then
MeasureItemStruct.itemData := Longint(Pointer(Items.Objects[I]));
MeasureItemStruct.itemWidth := W;
MeasureItemStruct.itemHeight := FItemHeight;
DrawItemStruct.itemData := MeasureItemStruct.itemData;
DrawItemStruct.itemID := I;
Dispatch(MeasureItemMsg);
DrawItemStruct.rcItem := Rect(0, Y, MeasureItemStruct.itemWidth,
Y + Integer(MeasureItemStruct.itemHeight));
Dispatch(DrawItemMsg);
Inc(Y, MeasureItemStruct.itemHeight);
Inc(I);
if I >= Items.Count then break;
end;
end;
begin
if Message.DC <> 0 then PaintListBox
else inherited;
end;
procedure TRxCustomListBox.WMSize(var Message: TWMSize);
begin
inherited;
SetColumnWidth;
end;
procedure TRxCustomListBox.DragCanceled;
var
M: TWMMouse;
{$IFDEF WIN32}
MousePos: TPoint;
{$ENDIF}
begin
with M do begin
Msg := WM_LBUTTONDOWN;
{$IFDEF WIN32}
GetCursorPos(MousePos);
Pos := PointToSmallPoint(ScreenToClient(MousePos));
{$ELSE}
GetCursorPos(Pos);
Pos := ScreenToClient(Pos);
{$ENDIF}
Keys := 0;
Result := 0;
end;
DefaultHandler(M);
M.Msg := WM_LBUTTONUP;
DefaultHandler(M);
end;
procedure TRxCustomListBox.DefaultDrawText(X, Y: Integer; const S: string);
var
ATabWidth: Longint;
begin
{$IFDEF RX_D4}
TControlCanvas(FCanvas).UpdateTextFlags;
{$ENDIF}
if FTabWidth = 0 then FCanvas.TextOut(X, Y, S)
else begin
ATabWidth := Round((TabWidth * Canvas.TextWidth('0')) * 0.25);
TabbedTextOut(FCanvas.Handle, X, Y, @S[1], Length(S), 1, ATabWidth, X);
end;
end;
procedure TRxCustomListBox.DrawItem(Index: Integer; Rect: TRect;
State: TOwnerDrawState);
begin
if Assigned(FOnDrawItem) then FOnDrawItem(Self, Index, Rect, State)
else begin
FCanvas.FillRect(Rect);
if Index < Items.Count then begin
{$IFDEF RX_D4}
if not UseRightToLeftAlignment then Inc(Rect.Left, 2)
else Dec(Rect.Right, 2);
{$ELSE}
Inc(Rect.Left, 2);
{$ENDIF}
DefaultDrawText(Rect.Left, Max(Rect.Top, (Rect.Bottom +
Rect.Top - Canvas.TextHeight('Wy')) div 2), Items[Index]);
end;
end;
end;
procedure TRxCustomListBox.MeasureItem(Index: Integer; var Height: Integer);
begin
if Assigned(FOnMeasureItem) then FOnMeasureItem(Self, Index, Height)
end;
procedure TRxCustomListBox.CNDrawItem(var Message: TWMDrawItem);
var
State: TOwnerDrawState;
begin
with Message.DrawItemStruct^ do begin
{$IFDEF WIN32}
{$IFDEF RX_D5}
State := TOwnerDrawState(LongRec(itemState).Lo);
{$ELSE}
State := TOwnerDrawState(WordRec(LongRec(itemState).Lo).Lo);
{$ENDIF}
{$ELSE}
State := TOwnerDrawState(WordRec(itemState).Lo);
{$ENDIF}
FCanvas.Handle := hDC;
FCanvas.Font := Font;
FCanvas.Brush := Brush;
if (Integer(itemID) >= 0) and (odSelected in State) then begin
with FCanvas do
if not (csDesigning in ComponentState) and FGraySelection and
not Focused then
begin
Brush.Color := clBtnFace;
if ColorToRGB(Font.Color) = ColorToRGB(clBtnFace) then
Font.Color := clBtnText;
end
else begin
Brush.Color := clHighlight;
Font.Color := clHighlightText
end;
end;
if Integer(itemID) >= 0 then DrawItem(itemID, rcItem, State)
else FCanvas.FillRect(rcItem);
if odFocused in State then DrawFocusRect(hDC, rcItem);
FCanvas.Handle := 0;
end;
end;
procedure TRxCustomListBox.CNMeasureItem(var Message: TWMMeasureItem);
begin
with Message.MeasureItemStruct^ do begin
itemHeight := FItemHeight;
if FStyle = lbOwnerDrawVariable then
MeasureItem(itemID, Integer(itemHeight));
end;
end;
procedure TRxCustomListBox.WMKillFocus(var Msg: TWMKillFocus);
begin
inherited;
if FGraySelection and MultiSelect and (SelCount > 1) then Invalidate;
end;
procedure TRxCustomListBox.WMSetFocus(var Msg: TWMSetFocus);
begin
inherited;
if FGraySelection and MultiSelect and (SelCount > 1) then Invalidate;
end;
{$IFDEF WIN32}
procedure TRxCustomListBox.CMCtl3DChanged(var Message: TMessage);
begin
if NewStyleControls and (FBorderStyle = bsSingle) then RecreateWnd;
inherited;
end;
{$ENDIF}
{ TCheckListBoxItem }
type
TCheckListBoxItem = class
private
FData: LongInt;
FState: TCheckBoxState;
FEnabled: Boolean;
function GetChecked: Boolean;
public
constructor Create;
property Checked: Boolean read GetChecked;
property Enabled: Boolean read FEnabled write FEnabled;
property State: TCheckBoxState read FState write FState;
end;
constructor TCheckListBoxItem.Create;
begin
inherited Create;
FState := clbDefaultState;
FEnabled := clbDefaultEnabled;
end;
function TCheckListBoxItem.GetChecked: Boolean;
begin
Result := FState = cbChecked;
end;
{ TCheckListBoxStrings }
type
TCheckListBoxStrings = class(TRxListBoxStrings)
public
procedure Exchange(Index1, Index2: Integer); override;
procedure Move(CurIndex, NewIndex: Integer); override;
end;
procedure TCheckListBoxStrings.Exchange(Index1, Index2: Integer);
var
TempEnabled1, TempEnabled2: Boolean;
TempState1, TempState2: TCheckBoxState;
begin
with TRxCheckListBox(ListBox) do begin
TempState1 := State[Index1];
TempEnabled1 := EnabledItem[Index1];
TempState2 := State[Index2];
TempEnabled2 := EnabledItem[Index2];
inherited Exchange(Index1, Index2);
State[Index1] := TempState2;
EnabledItem[Index1] := TempEnabled2;
State[Index2] := TempState1;
EnabledItem[Index2] := TempEnabled1;
end;
end;
procedure TCheckListBoxStrings.Move(CurIndex, NewIndex: Integer);
var
TempEnabled: Boolean;
TempState: TCheckBoxState;
begin
with TRxCheckListBox(ListBox) do begin
TempState := State[CurIndex];
TempEnabled := EnabledItem[CurIndex];
inherited Move(CurIndex, NewIndex);
State[NewIndex] := TempState;
EnabledItem[NewIndex] := TempEnabled;
end;
end;
{ TRxCheckListBox }
const
FCheckBitmap: TBitmap = nil;
function CheckBitmap: TBitmap;
begin
if FCheckBitmap = nil then begin
FCheckBitmap := TBitmap.Create;
FCheckBitmap.Handle := LoadBitmap(hInstance, 'CHECK_IMAGES');
end;
Result := FCheckBitmap;
end;
procedure DestroyLocals; far;
begin
if FCheckBitmap <> nil then begin
FCheckBitmap.Free;
FCheckBitmap := nil;
end;
end;
const
InternalVersion = 202; { for backward compatibility only }
constructor TRxCheckListBox.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FAutoScroll := True;
with CheckBitmap do begin
FCheckWidth := Width div 6;
FCheckHeight := Height div 3;
end;
FDrawBitmap := TBitmap.Create;
with FDrawBitmap do begin
Width := FCheckWidth;
Height := FCheckHeight;
end;
FIniLink := TIniLink.Create;
FIniLink.OnSave := IniSave;
FIniLink.OnLoad := IniLoad;
end;
destructor TRxCheckListBox.Destroy;
begin
FSaveStates.Free;
FSaveStates := nil;
FDrawBitmap.Free;
FDrawBitmap := nil;
FIniLink.Free;
inherited Destroy;
end;
procedure TRxCheckListBox.Loaded;
begin
inherited Loaded;
UpdateCheckStates;
end;
function TRxCheckListBox.CreateItemList: TStrings;
begin
Result := TCheckListBoxStrings.Create;
end;
const
sCount = 'Count';
sItem = 'Item';
procedure TRxCheckListBox.InternalSaveStates(IniFile: TObject;
const Section: string);
var
I: Integer;
begin
IniEraseSection(IniFile, Section);
IniWriteInteger(IniFile, Section, sCount, Items.Count);
for I := 0 to Items.Count - 1 do
IniWriteInteger(IniFile, Section, sItem + IntToStr(I), Integer(State[I]));
end;
procedure TRxCheckListBox.InternalRestoreStates(IniFile: TObject;
const Section: string);
var
I: Integer;
ACount: Integer;
begin
ACount := Min(IniReadInteger(IniFile, Section, sCount, 0), Items.Count);
for I := 0 to ACount - 1 do begin
State[I] := TCheckBoxState(IniReadInteger(IniFile, Section,
sItem + IntToStr(I), Integer(clbDefaultState)));
if (State[I] = cbChecked) and (FCheckKind = ckRadioButtons) then Exit;
end;
end;
{$IFDEF WIN32}
procedure TRxCheckListBox.SaveStatesReg(IniFile: TRegIniFile);
begin
InternalSaveStates(IniFile, GetDefaultSection(Self));
end;
procedure TRxCheckListBox.RestoreStatesReg(IniFile: TRegIniFile);
begin
InternalRestoreStates(IniFile, GetDefaultSection(Self));
end;
{$ENDIF WIN32}
procedure TRxCheckListBox.SaveStates(IniFile: TIniFile);
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -