📄 jvcolorcombo.pas
字号:
end;
procedure TJvColorComboBox.SetOptions(Value: TJvColorComboOptions);
begin
if FOptions <> Value then
begin
if (coCustomColors in FOptions) and (Items.Count > 0) then
Items.Delete(Items.Count - 1);
FOptions := Value;
{ if coText in FOptions then
begin
Exclude(FOptions,coHex);
Exclude(FOptions,coRGB);
end
else
if coHex in Value then
Exclude(FOptions,coRGB); }
if coCustomColors in FOptions then
InternalInsertColor(Items.Count, $000001, FColorDialogText);
Invalidate;
end;
end;
procedure TJvColorComboBox.SetColorDialogText(Value: string);
var
I: Integer;
begin
if FColorDialogText <> Value then
begin
I := Items.IndexOf(FColorDialogText);
while I > -1 do
begin
Items[I] := Value;
I := Items.IndexOf(FColorDialogText);
end;
FColorDialogText := Value;
end;
end;
procedure TJvColorComboBox.SetColorWidth(Value: Integer);
begin
if FColorWidth <> Value then
begin
FColorWidth := Value;
Invalidate;
end;
end;
procedure TJvColorComboBox.SetColorValue(Value: TColor);
var
I: Integer;
begin
I := FindColor(Value);
if I >= 0 then
begin
FColorValue := Value;
if ItemIndex <> I then
begin
ItemIndex := I;
Change;
end;
Exit;
end
else
if coCustomColors in Options then
begin
InsertColor(Items.Count - 1, Value, Format(FNewColorText, [FCustomColorCount]));
// Items.InsertObject(Items.Count, FNewColorText + IntToStr(FCustomColorCount), TObject(Value))
FColorValue := Value;
ItemIndex := Items.Count - 2;
end
else
begin
AddColor(Value, Format(FNewColorText, [FCustomColorCount]));
FColorValue := Value;
ItemIndex := Items.Count - 1;
Change;
end;
// Items.AddObject(FNewColorText + IntToStr(FCustomColorCount), TObject(Value));
end;
function TJvColorComboBox.DoNewColor(Color: TColor; var DisplayName: string): Boolean;
begin
Result := FindColor(Color) = -1;
if Assigned(FNewColor) then
FNewColor(Self, Color, DisplayName, Result);
end;
procedure TJvColorComboBox.CNDrawItem(var Msg: TWMDrawItem);
var
State: TOwnerDrawState;
begin
with Msg.DrawItemStruct^ do
begin
State := ItemStateToOwnerDrawState(itemState);
Canvas.Handle := hDC;
Canvas.Font := Font;
Canvas.Brush := Brush;
if (Integer(itemID) >= 0) and (odSelected in State) then
begin
Canvas.Brush.Color := FHiliteColor;
Canvas.Font.Color := FHiliteText;
end;
if Integer(itemID) >= 0 then
DrawItem(itemID, rcItem, State)
else
Canvas.FillRect(rcItem);
Canvas.Handle := 0;
end;
end;
procedure TJvColorComboBox.DrawItem(Index: Integer; R: TRect;
State: TOwnerDrawState);
var
aRect: TRect;
AColor: TColor;
S: string;
begin
aRect := R;
Inc(aRect.Top, 2);
Inc(aRect.Left, 2);
Dec(aRect.Bottom, 2);
if (coText in FOptions) or (coHex in FOptions) or (coRGB in FOptions) or
((coCustomColors in FOptions) and (Index = Items.Count - 1)) then
aRect.Right := aRect.Left + FColorWidth
else
Dec(aRect.Right, 3);
with Canvas do
begin
AColor := Brush.Color;
Brush.Color := Color;
FillRect(R);
Brush.Color := clGray;
OffsetRect(aRect, 2, 2);
FillRect(aRect);
OffsetRect(aRect, -2, -2);
Brush.Color := TColor(Items.Objects[Index]);
try
Rectangle(aRect);
finally
Brush.Color := AColor;
end;
if (coCustomColors in FOptions) and (Index = Items.Count - 1) then
begin
S := FColorDialogText;
DoGetDisplayName(Index, TColor(Items.Objects[Index]), S);
Brush.Color := Self.Color;
FillRect(R);
R.Left := R.Left + 2;
R.Right := R.Left + TextWidth(S) + 2;
Brush.Color := AColor;
FillRect(R);
SetBkMode(Canvas.Handle, TRANSPARENT);
DrawText(Canvas.Handle, PChar(S), Length(S), R, DT_SINGLELINE or DT_VCENTER or DT_NOPREFIX);
end
else
if (coText in FOptions) or (coHex in FOptions) or (coRGB in FOptions) then
begin
S := Items[Index];
DoGetDisplayName(Index, TColor(Items.Objects[Index]), S);
if S <> FColorDialogText then
begin
if coHex in FOptions then
S := Format('0x%.6x', [ColorToRGB(TColor(Items.Objects[Index]))])
else
if coRGB in FOptions then
S := Format('(%d,%d,%d)', [GetRValue(TColor(Items.Objects[Index])), GetGValue(TColor(Items.Objects[Index])),
GetBValue(TColor(Items.Objects[Index]))]);
end;
R.Left := R.Left + FColorWidth + 6;
R.Right := R.Left + TextWidth(S) + 6;
FillRect(R);
OffsetRect(R, 2, 0);
SetBkMode(Canvas.Handle, TRANSPARENT);
DrawText(Canvas.Handle, PChar(S), Length(S), R, DT_SINGLELINE or
DT_VCENTER or DT_NOPREFIX);
OffsetRect(R, -2, 0);
end
else
FrameRect(R);
if odSelected in State then
DrawFocusRect(R);
end;
end;
procedure TJvColorComboBox.Click;
var
S, Tmp: string;
CD: TColorDialog;
begin
if FExecutingDialog then
Exit;
if (ItemIndex = Items.Count - 1) and (coCustomColors in FOptions) then
begin
FExecutingDialog := True;
CD := TColorDialog.Create(Self);
with CD do
try
CD.Color := ColorValue;
Options := Options + [cdFullOpen, cdPreventFullOpen];
S := FNewColorText;
if Execute then
begin
if DoNewColor(CD.Color, S) then
Inc(FCustomColorCount);
Tmp := FNewColorText;
try
FNewColorText := S;
ColorValue := CD.Color;
finally
FNewColorText := Tmp;
end;
Change;
end
else
ItemIndex := Items.Count - 2;
finally
Free;
end;
end
else
if ItemIndex >= 0 then
ColorValue := TColor(Items.Objects[ItemIndex]);
inherited Click;
FExecutingDialog := False;
end;
procedure TJvColorComboBox.FontChanged;
begin
inherited FontChanged;
ResetItemHeight;
RecreateWnd;
end;
procedure TJvColorComboBox.ResetItemHeight;
begin
ItemHeight := Max(GetItemHeight(Font), 9);
end;
procedure TJvColorComboBox.AddColor(AColor: TColor; const DisplayName: string);
var
S: string;
begin
S := DisplayName;
if DoNewColor(AColor, S) then
begin
if coCustomColors in Options then
Inc(FCustomColorCount);
InternalInsertColor(Items.Count - Ord(coCustomColors in Options), AColor, S);
end;
end;
procedure TJvColorComboBox.DoGetDisplayName(Index: Integer; AColor: TColor;
var DisplayName: string);
begin
if Assigned(FOnGetDisplayName) then
FOnGetDisplayName(Self, Index, AColor, DisplayName)
else
DisplayName := GetColorName(AColor, DisplayName);
end;
procedure TJvColorComboBox.InsertColor(AIndex: Integer; AColor: TColor;
const DisplayName: string);
var
S: string;
begin
S := DisplayName;
if DoInsertColor(AIndex, AColor, S) then
InternalInsertColor(AIndex, AColor, S);
end;
function TJvColorComboBox.GetColorNameMap: TStrings;
begin
Result := FColorNameMap;
end;
function TJvColorComboBox.GetColor(Index: Integer): TColor;
begin
Result := TColor(Items.Objects[Index]);
end;
procedure TJvColorComboBox.SetColorNameMap(const Value: TStrings);
begin
FColorNameMap.Assign(Value);
Invalidate;
end;
function TJvColorComboBox.GetColorName(AColor: TColor; const Default: string): string;
var
Tmp: string;
begin
Tmp := ColorToString(AColor);
Result := FColorNameMap.Values[Tmp];
if Result = '' then
Result := FColorNameMap.Values['cl' + Tmp];
if Result = '' then
begin
if Default = '' then
begin
if (Length(Tmp) > 1) and AnsiSameText(Tmp[1], 'c') and AnsiSameText(Tmp[2], 'l') then
Result := Copy(Tmp, 3, MaxInt)
else
Result := Tmp;
end
else
Result := Default;
end;
end;
procedure TJvColorComboBox.InitColorNames;
var
I: Integer;
begin
FColorNameMap.BeginUpdate;
try
FColorNameMap.Clear;
for I := Low(ColorValues) to High(ColorValues) do
FColorNameMap.Add(ColorValues[I].Constant + '=' + ColorValues[I].Description);
for I := Low(SysColorValues) to High(SysColorValues) do
FColorNameMap.Add(SysColorValues[I].Constant + '=' + SysColorValues[I].Description);
finally
FColorNameMap.EndUpdate;
end;
end;
function TJvColorComboBox.DoInsertColor(AIndex: Integer; AColor: TColor;
var DisplayName: string): Boolean;
begin
Result := True;
if Assigned(FOnInsertColor) then
FOnInsertColor(Self, AColor, DisplayName, Result);
end;
procedure TJvColorComboBox.DoBeforeCustom;
begin
if Assigned(FOnBeforeCustom) then
FOnBeforeCustom(Self);
end;
procedure TJvColorComboBox.ChangeColor(AIndex: Integer; AColor: TColor;
const DisplayName: string);
begin
// raise Exception ?
if (AIndex >= 0) and (AIndex < Items.Count - Ord(coCustomColors in Options)) then
begin
Items[AIndex] := DisplayName;
Items.Objects[AIndex] := TObject(AColor);
end;
end;
function TJvColorComboBox.ColorName(AColor: TColor): string;
begin
Result := GetColorName(AColor, '');
if Result = '' then
DoGetDisplayName(-1, AColor, Result);
end;
function TJvColorComboBox.FindColor(AColor: TColor): Integer;
begin
Result := Items.IndexOfObject(TObject(AColor));
if (coCustomColors in Options) and (Result = Items.Count - 1) then
Result := -1;
end;
procedure TJvColorComboBox.GetCustomColors(AList: TList);
var
I, J: Integer;
begin
if AList = nil then
Exit;
J := Ord((coCustomColors in Options));
for I := Items.Count - (CustomColorCount + J) to pred(Items.Count - J) do
AList.Add(Items.Objects[I]);
end;
procedure TJvColorComboBox.InternalInsertColor(AIndex: Integer;
AColor: TColor; const DisplayName: string);
begin
Items.InsertObject(AIndex, DisplayName, TObject(AColor));
end;
procedure TJvColorComboBox.DoNameMapChange(Sender: TObject);
begin
Invalidate;
end;
procedure TJvColorComboBox.Loaded;
begin
inherited Loaded;
HandleNeeded;
if HandleAllocated then
GetColors;
end;
function TJvColorComboBox.GetDropDownWidth: Integer;
begin
Result := SendMessage(Handle, CB_GETDROPPEDWIDTH, 0, 0);
end;
procedure TJvColorComboBox.SetDropDownWidth(const Value: Integer);
begin
SendMessage(Handle, CB_SETDROPPEDWIDTH, Value, 0);
end;
procedure TJvColorComboBox.SetParent(AParent: TWinControl);
begin
inherited SetParent(AParent);
if (Parent <> nil) and HandleAllocated then
GetColors;
end;
//=== { TJvFontComboBox } ====================================================
constructor TJvFontComboBox.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FTrueTypeBmp := LoadInternalBitmap('JvFontComboBoxTTF');
FFixBmp := LoadInternalBitmap('JvFontComboBoxFIX');
FDeviceBmp := LoadInternalBitmap('JvFontComboBoxPRN');
FHiliteColor := clHighlight;
FHiliteText := clHighlightText;
FDevice := fdScreen;
FUseImages := True;
Style := csOwnerDrawFixed;
AutoComplete := False;
ResetItemHeight;
end;
destructor TJvFontComboBox.Destroy;
begin
FTrueTypeBmp.Free;
FDeviceBmp.Free;
FFixBmp.Free;
inherited Destroy;
end;
procedure TJvFontComboBox.GetFonts;
var
DC: HDC;
MRUItems: TStringList;
I: Integer;
begin
HandleNeeded;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -