📄 jvlistcomb.pas
字号:
destructor TJvImageItem.Destroy;
var
S: TStrings;
begin
S := GetOwnerStrings;
// PRY 2002.06.04
//if (S <> nil) and not (csDestroying in TComponent(FOwner.GetWinControl).ComponentState) then
if (S <> nil) and not (csDestroying in GetWinControl.ComponentState) then
S.Delete(Index);
FFont.Free;
FGlyph.Free;
inherited Destroy;
end;
function TJvImageItem.GetDisplayName: string;
begin
if Text = '' then
Result := inherited GetDisplayName
else
Result := Text;
end;
procedure TJvImageItem.Change;
begin
if Assigned(FOwner) then
FOwner.Update(Self);
end;
procedure TJvImageItem.SetImageIndex(const Value: Integer);
begin
if FImageIndex <> Value then
begin
FImageIndex := Value;
Change;
end;
end;
procedure TJvImageItem.SetIndent(const Value: Integer);
begin
if FIndent <> Value then
begin
FIndent := Value;
Change;
end;
end;
function TJvImageItem.GetOwnerStrings: TStrings;
begin
Result := nil;
if Assigned(FOwner) then
Result := FOwner.FStrings;
end;
procedure TJvImageItem.SetText(const Value: string);
var
S: TStrings;
begin
S := GetOwnerStrings;
if S <> nil then
begin
while S.Count <= Index do
S.Add('');
if S[Index] <> Value then
begin
S[Index] := Value;
Change;
end;
end;
end;
function TJvImageItem.GetText: string;
var
S: TStrings;
begin
Result := '';
S := GetOwnerStrings;
if S <> nil then
begin
while S.Count <= Index do
S.Add('');
Result := S[Index];
end;
end;
procedure TJvImageItem.SetIndex(Value: Integer);
var
I: Integer;
S: TStrings;
begin
I := Index;
inherited SetIndex(Value);
S := GetOwnerStrings;
if (S <> nil) and (I >= 0) and (Value >= 0) and (I <> Value) then
begin
while I >= S.Count do
S.Add('');
S.Move(I, Value);
end;
end;
//=== { TJvImageItems } ======================================================
constructor TJvImageItems.Create(AOwner: TPersistent);
begin
inherited Create(AOwner, TJvImageItem);
end;
function TJvImageItems.Add: TJvImageItem;
begin
Result := TJvImageItem(inherited Add);
while FStrings.Count < Count do
FStrings.Add('');
end;
function TJvImageItems.Add(const Text: string): Integer;
var
Item: TJvImageItem;
begin
Item := Add;
Item.Text := Text;
Result := Item.Index;
end;
function TJvImageItems.Insert(Index: Integer): TJvImageItem;
begin
Result := TJvImageItem(inherited Insert(Index));;
end;
procedure TJvImageItems.Insert(Index: Integer; const Text: string);
begin
Insert(Index).Text := Text;
end;
procedure TJvImageItems.Move(CurIndex, NewIndex: Integer);
var
Item, NewItem: TJvImageItem;
ItemText: string;
ItemObject: TObject;
begin
if NewIndex < 0 then
NewIndex := 0;
if NewIndex > Count then
NewIndex := Count;
if CurIndex <> NewIndex then
begin
BeginUpdate;
try
while FStrings.Count < Count do
FStrings.Add('');
{ Save object data }
ItemText := FStrings.Strings[CurIndex];
ItemObject := FStrings.Objects[CurIndex];
Item := TJvImageItem.Create(nil);
try
Item.FNoTextAssign := True;
Item.Assign(Items[CurIndex]);
{ Delete item }
Delete(CurIndex);
{ Add new item on NewIndex }
if NewIndex < Count then
NewItem := Insert(NewIndex)
else
NewItem := Add;
{ restore data except property Text which is linked to FStrings[] }
NewItem.FNoTextAssign := True;
try
NewItem.Assign(Item);
finally
NewItem.FNoTextAssign := False;
end;
{ restore property Text }
NewItem.Text := ItemText;
while FStrings.Count < Count do
FStrings.Add('');
FStrings.Objects[NewIndex] := ItemObject;
finally
Item.Free;
end;
finally
EndUpdate;
end;
Changed;
end;
end;
procedure TJvImageItems.Assign(Source: TPersistent);
var
I: Integer;
begin
if Source is TJvImageItems then
begin
BeginUpdate;
try
Clear;
for I := 0 to TJvImageItems(Source).Count - 1 do
Add.Assign(TJvImageItems(Source)[I]);
finally
EndUpdate;
end;
end
else
if Source is TStrings then
begin
BeginUpdate;
try
Clear;
for I := 0 to TStrings(Source).Count - 1 do
Add.Text := TStrings(Source)[I];
if FStrings <> nil then
FStrings.Assign(Source);
finally
EndUpdate;
end;
end
else
inherited Assign(Source);
end;
function TJvImageItems.GetItems(Index: Integer): TJvImageItem;
begin
Result := TJvImageItem(inherited Items[Index])
end;
procedure TJvImageItems.SetItems(Index: Integer; const Value: TJvImageItem);
begin
inherited Items[Index] := Value;
end;
procedure TJvImageItems.Update(Item: TCollectionItem);
var
W: TPersistent;
Obj: IJvResetItemHeight;
begin
if UpdateCount <> 0 then
Exit;
inherited Update(Item);
W := GetOwner;
if Supports(W, IJvResetItemHeight, Obj) then
Obj.ResetItemHeight
else
if W is TWinControl then
TWinControl(W).Invalidate;
end;
//=== { TJvImageComboBox } ===================================================
constructor TJvImageComboBox.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FItems := TJvImageItems.Create(Self);
FItems.FStrings := inherited Items;
FImageWidth := 0;
FImageHeight := 0;
FImageList := nil;
FDefaultIndent := 0;
FButtonFrame := False;
Style := csOwnerDrawVariable;
Color := clWindow;
FColorHighlight := clHighlight;
FColorHighlightText := clHighlightText;
{$IFDEF VCL}
FCanvas := TControlCanvas.Create;
FCanvas.Control := Self;
ResetItemHeight;
{$ENDIF VCL}
FChangeLink := TChangeLink.Create;
FChangeLink.OnChange := ImageListChange;
end;
destructor TJvImageComboBox.Destroy;
begin
FItems.Free;
FChangeLink.Free;
inherited Destroy;
{$IFDEF VCL}
// (rom) destroy Canvas AFTER inherited Destroy
FCanvas.Free;
{$ENDIF VCL}
end;
{$IFDEF VCL}
function TJvImageComboBox.GetCanvas: TCanvas;
begin
Result := FCanvas;
end;
{$ENDIF VCL}
procedure TJvImageComboBox.ImageListChange(Sender: TObject);
begin
// Invalidate;
end;
procedure TJvImageComboBox.SetImageList(Value: TCustomImageList);
begin
if FImageList <> Value then
begin
if FImageList <> nil then
FImageList.UnRegisterChanges(FChangeLink);
FImageList := Value;
if FImageList <> nil then
FImageList.RegisterChanges(FChangeLink);
{ if Assigned(FImageList) then
begin
FWidth := FImageList.Width;
FHeight := FImageList.Height;
end
else
begin
FWidth := 0;
FHeight := 0;
end; }
{$IFDEF VCL}
ResetItemHeight;
RecreateWnd;
{$ENDIF VCL}
{$IFDEF VisualCLX}
RecreateWidget;
{$ENDIF VisualCLX}
end;
end;
{$IFDEF VCL}
procedure TJvImageComboBox.CreateWnd;
begin
inherited CreateWnd;
SetDroppedWidth(FDroppedWidth);
end;
procedure TJvImageComboBox.RecreateWnd;
begin
inherited RecreateWnd;
SetDroppedWidth(FDroppedWidth);
end;
{$ENDIF VCL}
{$IFDEF VisualCLX}
procedure TJvImageComboBox.CreateWidget;
begin
inherited CreateWidget;
SetDroppedWidth(FDroppedWidth);
end;
procedure TJvImageComboBox.RecreateWidget;
begin
inherited RecreateWidget;
SetDroppedWidth(FDroppedWidth);
end;
{$ENDIF VisualCLX}
procedure TJvImageComboBox.Notification(AComponent: TComponent; Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (AComponent = FImageList) then
FImageList := nil;
end;
{$IFDEF VCL}
procedure TJvImageComboBox.CNDrawItem(var Msg: TWMDrawItem);
var
State: TOwnerDrawState;
begin
if csDestroying in ComponentState then
Exit;
with Msg.DrawItemStruct^ do
begin
State := [];
if (itemState and ODS_CHECKED) <> 0 then
Include(State, odChecked);
if (itemState and ODS_COMBOBOXEDIT) <> 0 then
Include(State, odComboBoxEdit);
if (itemState and ODS_DEFAULT) <> 0 then
Include(State, odDefault);
if (itemState and ODS_DISABLED) <> 0 then
Include(State, odDisabled);
if (itemState and ODS_FOCUS) <> 0 then
Include(State, odFocused);
if (itemState and ODS_GRAYED) <> 0 then
Include(State, odGrayed);
if (itemState and ODS_SELECTED) <> 0 then
Include(State, odSelected);
FCanvas.Handle := hDC;
FCanvas.Font := Font;
FCanvas.Brush := Brush;
if (Integer(itemID) >= 0) and (odSelected in State) then
begin
FCanvas.Brush.Color := FColorHighlight;
FCanvas.Font.Color := FColorHighlightText;
end;
if Integer(itemID) >= 0 then
DrawItem(itemID, rcItem, State)
else
FCanvas.FillRect(rcItem);
FCanvas.Handle := 0;
end;
end;
procedure TJvImageComboBox.DrawItem(Index: Integer; R: TRect; State: TOwnerDrawState);
{$ENDIF VCL}
{$IFDEF VisualCLX}
function TJvImageComboBox.DrawItem(Index: Integer; R: TRect; State: TOwnerDrawState): Boolean;
{$ENDIF VisualCLX}
var
Offset, Tmp: Integer;
TmpCol: TColor;
TmpR, OrigR: TRect;
SavedColor: TColor;
begin
{$IFDEF VisualCLX}
Result := True; // Handled
{$ENDIF VisualCLX}
if csDestroying in ComponentState then
Exit;
{$IFDEF VisualCLX}
if odSelected in State then
begin
Canvas.Brush.Color := FColorHighlight;
Canvas.Font.Color := FColorHighlightText;
end;
{$ENDIF VisualCLX}
SavedColor := Canvas.Font.Color;
Canvas.Font.Assign(Items[Index].Font);
if odSelected in State then
begin
Canvas.Brush.Color := FColorHighlight;
Canvas.Font.Color := FColorHighlightText;
end;
if State <> [] then
Canvas.Font.Color := SavedColor;
OrigR := R;
with Canvas do
begin
TmpCol := Brush.Color;
Brush.Color := Color;
FillRect(R);
Brush.Color := TmpCol;
if not (odComboBoxEdit in State) or IndentSelected then // (p3) don't draw indentation for edit item unless explicitly told to do so
R.Left := R.Left + Items[Index].Indent;
if not Items[Index].Glyph.Empty then
begin
Offset := ((R.Bottom - R.Top) - GetImageHeight(Index)) div 2;
Canvas.Draw(R.Left + 2, R.Top + Offset, Items[Index].Glyph);
if FButtonFrame then
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -