📄 mmlabel.pas
字号:
SetDepth(0,1);
SetDepth(1,1);
end;
lsSunken:
begin
SetDirection(0,ldDownRight);
SetDirection(1,ldUpLeft);
SetDepth(0,1);
SetDepth(1,1);
end;
lsShadow:
begin
SetDirection(0,ldNone);
SetDirection(1,ldDownRight);
SetDepth(0,0);
SetDepth(1,2);
SetAsButton(False);
end;
lsFlying:
begin
SetDirection(0,ldDownRight);
SetDirection(1,ldDownRight);
SetDepth(0,1);
SetDepth(1,5);
SetColor(0,clGray); { Flying has two shadows }
SetAsButton(False);
end;
lsNone:
begin
SetDirection(0,ldNone);
SetDirection(1,ldNone);
SetDepth(0,0);
SetDepth(1,0);
SetAsButton(False);
end;
else SetAsButton(False);
Refresh;
end;
FChangingStyle := False; { So further changes set style to custom }
end;
end;
{-- TMMLabel ------------------------------------------------------------}
procedure TMMLabel.SetAsButton(aValue: Boolean);
begin
if (FAsButton <> aValue) then
begin
FAsButton := aValue;
{ If not already raised, raise it }
if aValue then SetEffect(lsRaised);
end;
end;
{-- TMMLabel ------------------------------------------------------------}
procedure TMMLabel.SetAngle(aValue: TMMAngle);
begin
if (FAngle <> aValue) then
begin
FAngle := aValue;
DCosAngle := Cos(FAngle * DDegToRad); { Calculate values for later use }
DCosSquared := DCosAngle * DCosAngle;
DSinAngle := Sin(FAngle * DDegToRad);
DSinSquared := DSinAngle * DSinAngle;
if FAngle <> 0 then Alignment := taLeftJustify; { Cannot align when rotated }
Invalidate;
end;
end;
{------------------------------------------------------------------------}
procedure GetRGB(Color: TColor; var IR, IG, IB: Byte);
begin
IR := GetRValue(Color);
IG := GetGValue(Color);
IB := GetBValue(Color);
end;
{-- TMMLabel ------------------------------------------------------------}
procedure TMMLabel.SetTextAngle(Canvas: TCanvas; aValue: TMMAngle);
var
FntLogRec: TLogFont; { Storage area for font information }
begin
{ Get the current font information. We only want to modify the angle }
GetObject(Canvas.Font.Handle, SizeOf(FntLogRec), Addr(FntLogRec));
{ Modify the angle. "The angle, in tenths of a degrees, between the base
line of a character and the x-axis." (Windows API Help file.)}
FntLogRec.lfEscapement := aValue * 10;
FntLogRec.lfOutPrecision := OUT_TT_ONLY_PRECIS; { Request TrueType precision }
{ Delphi will handle the deallocation of the old font handle }
Canvas.Font.Handle := CreateFontIndirect(FntLogRec);
end;
{-- TMMLabel ------------------------------------------------------------}
procedure TMMLabel.MouseDown(Button: TMouseButton; ssShift: TShiftState; X, Y: Integer);
begin
if AsButton then
begin { If left button and label isn't sunken }
if (Button = mbLeft) and (EffectStyle <> lsSunken) and Enabled then
SetEffect(lsSunken);
end;
inherited MouseDown(Button, ssShift, X, Y);
end;
{-- TMMLabel ------------------------------------------------------------}
procedure TMMLabel.MouseMove(ssShift: TShiftState; X, Y: Integer);
begin
if AsButton then
begin
if ssShift = [ssLeft] then { Left mouse button down }
begin { If within label's client area }
if (X >= 0) and (X <= ClientWidth) and (Y >= 0) and (Y <= ClientHeight) then
SetEffect(lsSunken)
else
SetEffect(lsRaised);
end;
end;
inherited MouseMove(ssShift, X, Y);
end;
{-- TMMLabel ------------------------------------------------------------}
procedure TMMLabel.MouseUp(Button: TMouseButton; ssShift: TShiftState; X, Y: Integer);
begin
if AsButton then
begin { If within label's client area }
if (X >= 0) and (X <= ClientWidth) and (Y >= 0) and (Y <= ClientHeight) then
SetEffect(lsRaised);
end;
inherited MouseUp(Button, ssShift, X, Y);
end;
{-- TMMLabel ------------------------------------------------------------}
procedure TMMLabel.Paint;
const
WAlignments: array [TAlignment] of word = (DT_LEFT, DT_RIGHT, DT_CENTER);
var
IMinOffset, IMaxOffset: Integer;
RctTemp: TRect;
StrText: array [0..255] of char;
I, IMid, IH, IW, IX, IY, ILimit: Integer;
I1, I2, I3, I4, IAdj: Integer;
P1, P2, P3, P4: TPoint;
IFromR, IFromG, IFromB: Byte;
RAdjustR, RAdjustG, RAdjustB: Real;
BmpTemp, BmpWork: TBitmap;
CnvWork: TCanvas;
OldPalette: HPalette;
begin
{ Find minimum and maximum of all offsets (including font itself) }
IMinOffset := Min(Min(Min(Min(IOffsets[DirectionHighlight, drX] * DepthHighlight,
IOffsets[DirectionShadow, drX] * DepthShadow),
IOffsets[DirectionHighlight, drY] * DepthHighlight),
IOffsets[DirectionShadow, drY] * DepthShadow), 0);
IMaxOffset := Max(Max(Max(Max(IOffsets[DirectionHighlight, drX] * DepthHighlight,
IOffsets[DirectionShadow, drX] * DepthShadow),
IOffsets[DirectionHighlight, drY] * DepthHighlight),
IOffsets[DirectionShadow, drY] * DepthShadow), 0);
case Alignment of
taLeftJustify: IAdj := 0;
taCenter: IAdj := (IMaxOffset - IMinOffset) div 2;
taRightJustify: IAdj := IMaxOffset - IMinOffset;
end;
{ Create temporary drawing surfaces }
BmpTemp := TBitmap.Create;
BmpWork := TBitmap.Create;
try
BmpTemp.Height := Self.Height;
BmpTemp.Width := Self.Width;
BmpTemp.Canvas.Font := Self.Font;
BmpWork.Height := BmpTemp.Height;
BmpWork.Width := BmpTemp.Width;
BmpWork.Canvas.Font := Self.Font; { Ensure canvas font is set }
BmpWork.Canvas.CopyRect(ClientRect, Canvas, ClientRect);
if (Angle <> 0) then { Need to generate an angled font }
begin
SetTextAngle(BmpTemp.Canvas, Angle);
SetTextAngle(BmpWork.Canvas, Angle);
end;
with BmpWork.Canvas do
begin
{ Set starting point for text - IX, IY }
if Angle = 0 then
begin
IX := 0;
IY := 0;
end
else
begin
IW := TextWidth(Caption);
IH := TextHeight(Caption);
IMid := TextWidth(Caption+' ') div 2;
IX := IMid - Trunc(IW / 2 * DCosAngle) - Trunc(IH / 2 * DSinAngle);
IY := IMid + Trunc(IW / 2 * DSinAngle) - Trunc(IH / 2 * DCosAngle);
IMid := IMid + (IMaxOffset - IMinOffset + 4) div 2;
IW := IW + IMaxOffset + IMinOffset + 4;
IH := IH + IMaxOffset + IMinOffset + 4;
I1 := Trunc(IW / 2 * DCosAngle);
I2 := Trunc(IH / 2 * DSinAngle);
I3 := Trunc(IW / 2 * DSinAngle);
I4 := Trunc(IH / 2 * DCosAngle);
P1 := Point(IMid - I1 - I2 + 2, IMid + I3 - I4 + 2);
P2 := Point(IMid + I1 - I2 + 2, IMid - I3 - I4 + 2);
P3 := Point(IMid + I1 + I2 + 2, IMid - I3 + I4 + 2);
P4 := Point(IMid - I1 + I2 + 2, IMid + I3 + I4 + 2);
end;
if not Transparent then { Fill in background }
begin
Brush.Color := Self.Color;
Brush.Style := bsSolid;
if Angle = 0 then
FillRect(ClientRect) { Original label canvas }
else
Polygon([P1, P2, P3, P4]);
end;
Brush.Style := bsClear; { Don't overwrite background above }
end;
GetTextBuf(StrText, SizeOf(StrText)); { Get label's caption }
{ Prepare for extruding shadow, if requested }
GetRGB(ColourShadow, IFromR, IFromG, IFromB);
RAdjustR := 0; RAdjustG := 0; RAdjustB := 0;
if (StyleShadow <> loNormal) and (DepthShadow > 1) then
begin
ILimit := 1;
end
else ILimit := DepthShadow;
CnvWork := BmpWork.Canvas; { Work directly on label's canvas }
{ Process for each copy of the shadow - several if extruding }
for I := DepthShadow downto ILimit do
begin
CnvWork.Font.Color := RGB(IFromR+Round(RAdjustR*(DepthShadow-i)),
IFromG+Round(RAdjustG*(DepthShadow-i)),
IFromB+Round(RAdjustB*(DepthShadow-i)));
if Angle = 0 then
begin
{ Create a rect that is offset for the shadow }
RctTemp:= Rect(ClientRect.Left - IMinOffset -IAdj + IOffsets[DirectionShadow, drX] * I,
ClientRect.Top - IMinOffset + IOffsets[DirectionShadow, drY] * I,
ClientRect.Right - IMinOffset - IAdj + IOffsets[DirectionShadow, drX] * I,
ClientRect.Bottom - IMinOffset + IOffsets[DirectionShadow, drY] * I);
{ Draw shadow text with alignment }
DrawText(CnvWork.Handle, StrText, StrLen(StrText), RctTemp,
DT_EXPANDTABS or DT_WORDBREAK or WAlignments[Alignment]);
end
else
{ Draw angled shadow text without alignment }
CnvWork.TextOut(IX - IMinOffset + IOffsets[DirectionShadow, drX] * I,
IY - IMinOffset + IOffsets[DirectionShadow, drY] * I,
Caption);
end;
{ Prepare for extruding highlight, if requested }
GetRGB(ColourHighlight, IFromR, IFromG, IFromB);
RAdjustR := 0; RAdjustG := 0; RAdjustB := 0;
if (StyleHighlight <> loNormal) and (DepthHighlight > 1) then
begin
ILimit := 1;
end
else ILimit := DepthHighlight;
CnvWork := BmpWork.Canvas; { Work directly on label's canvas }
{ Process for each copy of the highlight - several if extruding }
for I := DepthHighlight downto ILimit do
begin
CnvWork.Font.Color := RGB(IFromR+Round(RAdjustR*(DepthHighlight-i)),
IFromG+Round(RAdjustG*(DepthHighlight-i)),
IFromB+Round(RAdjustB*(DepthHighlight-i)));
if Angle = 0 then
begin
{ Create a rect that is offset for the highlight }
RctTemp:= Rect(ClientRect.Left - IMinOffset - IAdj + IOffsets[DirectionHighlight, drX] * I,
ClientRect.Top - IMinOffset + IOffsets[DirectionHighlight, drY] * I,
ClientRect.Right - IMinOffset - IAdj + IOffsets[DirectionHighlight, drX] * I,
ClientRect.Bottom - IMinOffset + IOffsets[DirectionHighlight, drY] * I);
{ Draw highlight text with alignment }
DrawText(CnvWork.Handle, StrText, StrLen(StrText), RctTemp,
DT_EXPANDTABS or DT_WORDBREAK or WAlignments[Alignment]);
end
else
{ Draw angled highlight text without alignment }
CnvWork.TextOut(IX - IMinOffset + IOffsets[DirectionHighlight, drX] * I,
IY - IMinOffset + IOffsets[DirectionHighlight, drY] * I,
Caption);
end;
if not FBitmap.Empty then
begin
{ Fill the bitmap with white }
CnvWork := BmpTemp.Canvas;
CnvWork.Brush.Color := clWhite;
CnvWork.FillRect(Rect(0,0,BmpTemp.Width,BmpTemp.Height));
{ text color to black }
CnvWork.Font.Color := clBlack;
end
else
begin
CnvWork := BmpWork.Canvas;
{ Restore original font colour }
CnvWork.Font.Color := Font.Color;
end;
if Angle = 0 then
begin
{ Create a rect that is offset for the original text }
RctTemp:= Rect(ClientRect.Left - IMinOffset - IAdj,
ClientRect.Top - IMinOffset,
ClientRect.Right - IMinOffset - IAdj,
ClientRect.Bottom - IMinOffset);
{ Draw original text with alignment }
DrawText(CnvWork.Handle, StrText, StrLen(StrText), RctTemp,
DT_EXPANDTABS or DT_WORDBREAK or WAlignments[Alignment]);
end
else
{ Draw angled original text without alignment }
CnvWork.TextOut(IX - IMinOffset, IY - IMinOffset, Caption);
if not FBitmap.Empty then
begin
{ combine original canvas with bitmap (invert) }
TileBlt(BmpWork.Canvas.Handle,FBitmap.Handle,
Rect(0,0,BmpWork.Width, BmpWork.Height),SRCINVERT);
{ now draw black white font }
BitBlt(BmpWork.Canvas.Handle,0,0,BmpTemp.Width, BmpTemp.Height,
BmpTemp.Canvas.Handle,0,0,SRCAND);
{ combine original canvas with bitmap (invert again) }
TileBlt(BmpWork.Canvas.Handle,FBitmap.Handle,
Rect(0,0,BmpWork.Width, BmpWork.Height),SRCINVERT);
if (GetPalette <> 0) then
begin
OldPalette := SelectPalette(Canvas.Handle, GetPalette, True);
RealizePalette(Canvas.Handle);
end;
end;
{ Paint the bevel }
Bevel.PaintBevel(BmpWork.Canvas, ClientRect, True);
{ now copy to screen }
BitBlt(Canvas.Handle, 0, 0, Width ,Height,
BmpWork.Canvas.Handle, 0, 0, SRCCOPY);
if (GetPalette <> 0) then
begin
SelectPalette(Canvas.Handle, OldPalette, True);
RealizePalette(Canvas.Handle);
end;
finally
BmpTemp.Free;
BmpWork.Free;
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -