📄 lbutils.pas
字号:
unit LBUtils;
interface
uses
Windows, Classes, Graphics, Buttons;
type
TAdvColors = 0..100;
TColorCalcType = (lighten, darken);
TNumGlyphs = 1..4;
var
HSLRange: integer = 240;
function HSLtoRGB (H, S, L: double): TColor;
function HSLRangeToRGB (H, S, L : integer): TColor;
function CalcAdvancedColor (ParentColor, OriginalColor: TColor; Percent: Byte; ColorType: TColorCalcType): TColor;
function GetFontHeight(Font: TFont): Integer;
function GetFontMetrics(Font: TFont): TTextMetric;
function Min(val1, val2: Word): Word;
function RectInRect(R1, R2: TRect): Boolean;
function CreateDisabledBitmap (FOriginal: TBitmap; OutlineColor, BackColor, HighlightColor, ShadowColor: TColor; DrawHighlight: Boolean): TBitmap;
procedure CalcButtonLayout (Canvas: TCanvas; const Client: TRect; const Offset: TPoint; Layout: TButtonLayout;
Spacing, Margin: Integer; FGlyph: TBitmap; FNumGlyphs: Integer;
const Caption: string; var TextBounds: TRect; var GlyphPos: TPoint);
procedure RGBtoHSL (RGB: TColor; var H, S, L : double);
procedure RGBtoHSLRange (RGB: TColor; var H, S, L : integer);
implementation
function HSLtoRGB (H, S, L: double): TColor;
var
M1, M2: double;
function HueToColourValue (Hue: double) : byte;
var
V : double;
begin
if Hue < 0 then
Hue := Hue + 1
else
if Hue > 1 then
Hue := Hue - 1;
if 6 * Hue < 1 then
V := M1 + (M2 - M1) * Hue * 6
else
if 2 * Hue < 1 then
V := M2
else
if 3 * Hue < 2 then
V := M1 + (M2 - M1) * (2/3 - Hue) * 6
else
V := M1;
Result := round (255 * V)
end;
var
R, G, B: byte;
begin
if S = 0 then
begin
R := round (255 * L);
G := R;
B := R
end else begin
if L <= 0.5 then
M2 := L * (1 + S)
else
M2 := L + S - L * S;
M1 := 2 * L - M2;
R := HueToColourValue (H + 1/3);
G := HueToColourValue (H);
B := HueToColourValue (H - 1/3)
end;
Result := RGB (R, G, B)
end;
function HSLRangeToRGB (H, S, L : integer): TColor;
begin
Result := HSLToRGB (H / (HSLRange-1), S / HSLRange, L / HSLRange)
end;
// Convert RGB value (0-255 range) into HSL value (0-1 values)
procedure RGBtoHSL (RGB: TColor; var H, S, L : double);
function Max (a, b : double): double;
begin
if a > b then
Result := a
else
Result := b
end;
function Min (a, b : double): double;
begin
if a < b then
Result := a
else
Result := b
end;
var
R, G, B, D, Cmax, Cmin: double;
begin
R := GetRValue (RGB) / 255;
G := GetGValue (RGB) / 255;
B := GetBValue (RGB) / 255;
Cmax := Max (R, Max (G, B));
Cmin := Min (R, Min (G, B));
// calculate luminosity
L := (Cmax + Cmin) / 2;
if Cmax = Cmin then // it's grey
begin
H := 0; // it's actually undefined
S := 0
end else begin
D := Cmax - Cmin;
// calculate Saturation
if L < 0.5 then
S := D / (Cmax + Cmin)
else
S := D / (2 - Cmax - Cmin);
// calculate Hue
if R = Cmax then
H := (G - B) / D
else
if G = Cmax then
H := 2 + (B - R) /D
else
H := 4 + (R - G) / D;
H := H / 6;
if H < 0 then
H := H + 1
end
end;
procedure RGBtoHSLRange (RGB: TColor; var H, S, L : integer);
var
Hd, Sd, Ld: double;
begin
RGBtoHSL (RGB, Hd, Sd, Ld);
H := round (Hd * (HSLRange-1));
S := round (Sd * HSLRange);
L := round (Ld * HSLRange);
end;
function CalcAdvancedColor (ParentColor, OriginalColor: TColor; Percent: Byte; ColorType: TColorCalcType): TColor;
var
H, S, L: integer;
begin
if Percent <> 0 then
begin
RGBtoHSLRange(ColorToRGB(ParentColor), H, S, L);
inc(L, 10);
if ColorType = lighten then
if L + Percent > 100 then
L := 100
else
inc(L, Percent)
else
if L - Percent < 0 then
L := 0
else
dec(L, Percent);
Result := HSLRangeToRGB(H, S, L);
end
else
Result := OriginalColor;
end;
function GetFontHeight(Font: TFont): Integer;
begin
with GetFontMetrics(Font) do
Result := Round(tmHeight + tmHeight / 8);
end;
function GetFontMetrics(Font: TFont): TTextMetric;
var
DC: HDC;
SaveFont: HFont;
begin
DC := GetDC(0);
SaveFont := SelectObject(DC, Font.Handle);
GetTextMetrics(DC, Result);
SelectObject(DC, SaveFont);
ReleaseDC(0, DC);
end;
function Min(val1, val2: Word): Word;
begin
Result := val1;
if val1 > val2 then
Result := val2;
end;
function RectInRect(R1, R2: TRect): Boolean;
begin
Result := IntersectRect(R1, R1, R2);
end;
function CreateDisabledBitmap(FOriginal: TBitmap; OutlineColor, BackColor, HighlightColor, ShadowColor: TColor; DrawHighlight: Boolean): TBitmap;
const
ROP_DSPDxax = $00E20746;
var
MonoBmp: TBitmap;
IRect: TRect;
begin
IRect := Rect(0, 0, FOriginal.Width, FOriginal.Height);
Result := TBitmap.Create;
try
Result.Width := FOriginal.Width;
Result.Height := FOriginal.Height;
MonoBmp := TBitmap.Create;
try
with MonoBmp do begin
Width := FOriginal.Width;
Height := FOriginal.Height;
Canvas.CopyRect(IRect, FOriginal.Canvas, IRect);
{$IFDEF D4CB4}
HandleType := bmDDB;
{$ENDIF}
Canvas.Brush.Color := OutlineColor;
if Monochrome then begin
Canvas.Font.Color := clWhite;
Monochrome := False;
Canvas.Brush.Color := clWhite;
end;
Monochrome := True;
end;
with Result.Canvas do begin
Brush.Color := BackColor;
FillRect(IRect);
if DrawHighlight then begin
Brush.Color := HighlightColor;
SetTextColor(Handle, clBlack);
SetBkColor(Handle, clWhite);
BitBlt(Handle, 1, 1, IRect.Right - IRect.Left, IRect.Bottom - IRect.Top, MonoBmp.Canvas.Handle, 0, 0, ROP_DSPDxax);
end;
Brush.Color := ShadowColor;
SetTextColor(Handle, clBlack);
SetBkColor(Handle, clWhite);
BitBlt(Handle, 0, 0, IRect.Right - IRect.Left, IRect.Bottom - IRect.Top, MonoBmp.Canvas.Handle, 0, 0, ROP_DSPDxax);
end;
finally
MonoBmp.Free;
end;
except
Result.Free;
raise;
end;
end;
procedure CalcButtonLayout (Canvas: TCanvas; const Client: TRect; const Offset: TPoint; Layout: TButtonLayout;
Spacing, Margin: Integer; FGlyph: TBitmap; FNumGlyphs: Integer;
const Caption: string; var TextBounds: TRect; var GlyphPos: TPoint);
var
TextPos: TPoint;
ClientSize, GlyphSize, TextSize: TPoint;
TotalSize: TPoint;
begin
// calculate the item sizes
ClientSize := Point(Client.Right - Client.Left, Client.Bottom - Client.Top);
if FGlyph <> nil then
GlyphSize := Point(FGlyph.Width div FNumGlyphs, FGlyph.Height)
else
GlyphSize := Point(0, 0);
if Length(Caption) > 0 then
begin
TextBounds := Rect(0, 0, Client.Right - Client.Left, 0);
DrawText(Canvas.Handle, PChar(Caption), Length(Caption), TextBounds, DT_CALCRECT or DT_SINGLELINE);
TextSize := Point(TextBounds.Right - TextBounds.Left, TextBounds.Bottom - TextBounds.Top);
end
else
begin
TextBounds := Rect(0, 0, 0, 0);
TextSize := Point(0, 0);
end;
// If the layout has the glyph on the right or the left, then both the
// text and the glyph are centered vertically. If the glyph is on the top
// or the bottom, then both the text and the glyph are centered horizontally.
if Layout in [blGlyphLeft, blGlyphRight] then
begin
GlyphPos.Y := (ClientSize.Y - GlyphSize.Y + 1) div 2;
TextPos.Y := (ClientSize.Y - TextSize.Y + 1) div 2;
end
else
begin
GlyphPos.X := (ClientSize.X - GlyphSize.X + 1) div 2;
TextPos.X := (ClientSize.X - TextSize.X + 1) div 2;
end;
// if there is no text or no bitmap, then Spacing is irrelevant
if (TextSize.X = 0) or (GlyphSize.X = 0) then
Spacing := 0;
// adjust Margin and Spacing
if Margin = -1 then
begin
if Spacing = -1 then
begin
TotalSize := Point(GlyphSize.X + TextSize.X, GlyphSize.Y + TextSize.Y);
if Layout in [blGlyphLeft, blGlyphRight] then
Margin := (ClientSize.X - TotalSize.X) div 3
else
Margin := (ClientSize.Y - TotalSize.Y) div 3;
Spacing := Margin;
end
else
begin
TotalSize := Point(GlyphSize.X + Spacing + TextSize.X, GlyphSize.Y + Spacing + TextSize.Y);
if Layout in [blGlyphLeft, blGlyphRight] then
Margin := (ClientSize.X - TotalSize.X + 1) div 2
else
Margin := (ClientSize.Y - TotalSize.Y + 1) div 2;
end;
end
else
begin
if Spacing = -1 then
begin
TotalSize := Point(ClientSize.X - (Margin + GlyphSize.X), ClientSize.Y - (Margin + GlyphSize.Y));
if Layout in [blGlyphLeft, blGlyphRight] then
Spacing := (TotalSize.X - TextSize.X) div 2
else
Spacing := (TotalSize.Y - TextSize.Y) div 2;
end;
end;
case Layout of
blGlyphLeft:
begin
GlyphPos.X := Margin;
TextPos.X := GlyphPos.X + GlyphSize.X + Spacing;
end;
blGlyphRight:
begin
GlyphPos.X := ClientSize.X - Margin - GlyphSize.X;
TextPos.X := GlyphPos.X - Spacing - TextSize.X;
end;
blGlyphTop:
begin
GlyphPos.Y := Margin;
TextPos.Y := GlyphPos.Y + GlyphSize.Y + Spacing;
end;
blGlyphBottom:
begin
GlyphPos.Y := ClientSize.Y - Margin - GlyphSize.Y;
TextPos.Y := GlyphPos.Y - Spacing - TextSize.Y;
end;
end;
// fixup the result variables
with GlyphPos do
begin
Inc(X, Client.Left + Offset.X);
Inc(Y, Client.Top + Offset.Y);
end;
OffsetRect(TextBounds, TextPos.X + Client.Left + Offset.X, TextPos.Y + Client.Top + Offset.X);
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -