cxlabel.pas
来自「胜天进销存源码,国产优秀的进销存」· PAS 代码 · 共 1,364 行 · 第 1/3 页
PAS
1,364 行
function GetTextDrawingParameters(ACanvas: TCanvas; ADrawingRect: TRect;
AAngle: Integer; out AStep: TSize): TPoint;
procedure CalcRotatedTextPos(ACanvas: TCanvas);
var
ARect: TRect;
AText: string;
begin
if AAngle <> 0 then
begin
ARect := ADrawingRect;
Dec(ARect.Right, DepthDeltaSize.cx);
Dec(ARect.Bottom, DepthDeltaSize.cy);
AText := Text;
if ShowAccelChar then
AText := RemoveAccelChars(AText);
cxDrawText(ACanvas.Handle, AText, ADrawingRect, DT_CALCRECT or DT_NOPREFIX);
Result.X := Round(
(ARect.Left + ARect.Right)/2 -
RectWidth(ADrawingRect) / 2 * Cos(AAngle * PI / 180) -
RectHeight(ADrawingRect) / 2 * Sin(AAngle * PI / 180));
Result.Y := Round(
(ARect.Top + ARect.Bottom)/2 +
RectWidth(ADrawingRect) / 2 * Sin(AAngle * PI / 180) -
RectHeight(ADrawingRect) / 2 * Cos(AAngle * PI / 180));
end;
end;
function GetSignByValue(AValue: Longint): ShortInt;
begin
Result := 0;
if AValue = 0 then
Exit;
if AValue > 0 then
Result := 1
else
Result := -1;
end;
var
ALabelStyleOffset: Integer;
begin
Result := Point(0, 0);
CalcRotatedTextPos(ACanvas);
AStep := Size(0, 0);
ALabelStyleOffset := GetLabelStyleOffset;
if (LabelEffect <> cxleNormal) and (FDepth <> 0) then
begin
AStep := DepthDeltaSize;
if Orientation in [cxoRight, cxoRightTop, cxoRightBottom] then
begin
Inc(Result.X, DepthDeltaSize.cx + ALabelStyleOffset);
AStep.cx := -AStep.cx;
end;
if Orientation in [cxoBottom, cxoLeftBottom , cxoRightBottom] then
begin
Inc(Result.Y, DepthDeltaSize.cy + ALabelStyleOffset);
AStep.cy := -AStep.cy;
end;
if LabelEffect in [cxleFun, cxleExtrude] then
begin
AStep.cx := GetSignByValue(AStep.cx);
AStep.cy := GetSignByValue(AStep.cy);
end;
end;
end;
procedure DrawActualText(ACanvas: TcxCanvas; const ADrawingRect: TRect;
const APosition: TPoint; AIsTextRotated: Boolean);
var
ATextRect: TRect;
AText: string;
begin
ATextRect := ADrawingRect;
if not AIsTextRotated then
begin
Dec(ATextRect.Right, DepthDeltaSize.cx);
Dec(ATextRect.Bottom, DepthDeltaSize.cy);
OffsetRect(ATextRect, APosition.X, APosition.Y);
ACanvas.DrawText(Text, ATextRect,
PrepareTextFlag(0, Alignment.Horz, TcxAlignmentVert(Ord(Alignment.Vert)),
(epoShowEndEllipsis in PaintOptions) and IsInplace,
WordWrap, 0, False, ShowAccelChar));
end
else
begin
AText := Text;
if ShowAccelChar then
AText := RemoveAccelChars(AText);
ExtTextOut(ACanvas.Handle, APosition.X, APosition.Y, 0,
@ATextRect, PChar(AText),
Length(AText), nil);
end;
end;
procedure DrawLabelEffect(ACanvas: TcxCanvas; const ADrawingRect: TRect;
var AStartPos: TPoint; const AStep: TSize; AIsTextRotated: Boolean);
var
AIterationCount, I: Integer;
begin
if (LabelEffect = cxleNormal) or (FDepth = 0) then
Exit;
if AStep.cx <> 0 then
AIterationCount := FDepth div Abs(AStep.cx)
else
AIterationCount := FDepth div Abs(AStep.cy);
if LabelEffect <> cxleFun then
ACanvas.Font.Color := ShadowedColor;
for I := 1 to AIterationCount do
begin
if LabelEffect = cxleFun then
ACanvas.Font.Color :=
GetColor(BackgroundColor, ShadowedColor, I, AIterationCount);
DrawActualText(ACanvas, ADrawingRect, AStartPos, AIsTextRotated);
Inc(AStartPos.X, AStep.cx);
Inc(AStartPos.Y, AStep.cy);
end;
end;
procedure DrawConventionalizedText(ACanvas: TcxCanvas; ARect: TRect;
const APosition: TPoint; AGlyph: TBitmap; AIsTrueType: Boolean;
AIsTextRotated: Boolean);
procedure DrawFilledText(XPosOffset, YPosOffset: Integer;
AGlyphOnly: Boolean = False);
begin
if not AGlyph.Empty and AIsTrueType and (AGlyph.Width > 0) and
(AGlyph.Height > 0) then
begin
BeginPath(ACanvas.Handle);
DrawActualText(ACanvas, ARect, Point(APosition.X + XPosOffset,
APosition.Y + YPosOffset), AIsTextRotated);
EndPath(ACanvas.Handle);
SelectClipPath(ACanvas.Handle, RGN_COPY);
ACanvas.FillRect(ARect, AGlyph);
SelectClipRgn(ACanvas.Handle, 0);
end
else
if not AGlyphOnly then
DrawActualText(ACanvas, ARect, Point(APosition.X + XPosOffset,
APosition.Y + YPosOffset), AIsTextRotated);
end;
begin
ACanvas.Font.Color := TextColor;
case LabelStyle of
cxlsNormal:
DrawFilledText(0, 0);
cxlsRaised:
begin
ACanvas.Font.Color := clBtnHighlight;
DrawActualText(ACanvas, ARect, APosition,
AIsTextRotated);
if Font.Size >= 12 then
begin
ACanvas.Font.Color := clBtnShadow;
DrawActualText(ACanvas, ARect, Point(APosition.X + 2, APosition.Y + 2),
AIsTextRotated);
end;
ACanvas.Font.Color := TextColor;
DrawFilledText(1, 1);
end;
cxlsLowered:
begin
if Font.Size >= 12 then
begin
ACanvas.Font.Color := clBtnShadow;
DrawActualText(ACanvas, ARect, APosition,
AIsTextRotated);
end;
ACanvas.Font.Color := clBtnHighlight;
DrawActualText(ACanvas, ARect, Point(APosition.X + 2, APosition.Y + 2),
AIsTextRotated);
ACanvas.Font.Color := TextColor;
DrawFilledText(1, 1);
end;
cxlsOutLine:
begin
DrawFilledText(0, 0, AIsTrueType);
if AIsTrueType then
begin
BeginPath(ACanvas.Handle);
DrawActualText(ACanvas, ARect, APosition, AIsTextRotated);
EndPath(ACanvas.Handle);
ACanvas.Pen.Color := TextColor;
ACanvas.Pen.Width := FPenWidth;
StrokePath(ACanvas.Handle);
ACanvas.Pen.Width := 1;
end;
end;
end;
end;
procedure AdjustTextPosWithLabelStyle(var APosition: TPoint;
const AStep: TSize);
var
ALabelStyleOffset: Integer;
begin
ALabelStyleOffset := GetLabelStyleOffset;
if AStep.cx < 0 then
Dec(APosition.X, ALabelStyleOffset);
if AStep.cy < 0 then
Dec(APosition.Y, ALabelStyleOffset);
end;
procedure AdjustTextRectWithOffset(var ATextRect: TRect);
begin
if IsInplace then
with DrawTextOffsets do
begin
Inc(ATextRect.Left, Left);
Inc(ATextRect.Top, Top);
Dec(ATextRect.Right, Right);
Dec(ATextRect.Bottom, Bottom);
end
else
if BorderStyle <> ebsNone then
InflateRect(ATextRect, -TextFromBorderOffset, 0);
end;
procedure InternalDrawLabel(ADrawCanvas: TcxCanvas;
const ABackgroundRect, ATextRect: TRect; const AParentBackgroundOffset: TPoint);
var
AIsTrueType: Boolean;
ARealAngle: Integer;
AStep: TSize;
AStartPos: TPoint;
begin
DrawBackground(ADrawCanvas, ABackgroundRect, AParentBackgroundOffset);
AIsTrueType := AdjustCanvasFont(ADrawCanvas.Canvas, Font, FAngle);
ARealAngle := Integer(AIsTrueType) * FAngle;
ARealAngle := (ARealAngle mod 360 + 360) mod 360;
AStartPos := GetTextDrawingParameters(ADrawCanvas.Canvas, ATextRect,
ARealAngle, AStep);
ADrawCanvas.Brush.Style := bsClear;
DrawLabelEffect(ADrawCanvas, ATextRect, AStartPos, AStep, ARealAngle <> 0);
AdjustTextPosWithLabelStyle(AStartPos, AStep);
DrawConventionalizedText(ADrawCanvas, ATextRect, AStartPos, FGlyph,
AIsTrueType, ARealAngle <> 0);
ADrawCanvas.Brush.Style := bsSolid;
end;
function InplaceOffsetChanged: Boolean;
begin
Result := (FInplaceOffset.X <> Left) or (FInplaceOffset.Y <> Top);
if Result then
begin
FInplaceOffset.X := Left;
FInplaceOffset.Y := Top;
end;
end;
var
ABitmapCanvas: TcxCanvas;
AContentRect, ATextRect: TRect;
APrevLogFont: TLogFont;
begin
SaveCanvasFont(ACanvas, APrevLogFont);
try
AContentRect := LabelTextRect;
ATextRect := LabelTextRect;
AdjustTextRectWithOffset(ATextRect);
if not IsInplace and Transparent and (csPaintCopy in Edit.ControlState) then
InternalDrawLabel(ACanvas, AContentRect, ATextRect, AContentRect.TopLeft)
else
begin
if not IsInplace and NativeStyle then
GetThemeBackgroundContentRect(OpenTheme(totEdit), ACanvas.Handle,
EP_EDITTEXT, NativeState, Bounds, AContentRect);
if InplaceOffsetChanged or FIsDrawBitmapDirty or Transparent then
begin
FDrawBitmap.Width := RectWidth(AContentRect);
FDrawBitmap.Height := RectHeight(AContentRect);
ABitmapCanvas := TcxCanvas.Create(FDrawBitmap.Canvas);
OffsetRect(ATextRect, -AContentRect.Left, -AContentRect.Top);
try
InternalDrawLabel(ABitmapCanvas, Rect(0, 0, FDrawBitmap.Width, FDrawBitmap.Height),
ATextRect, AContentRect.TopLeft);
finally
FreeAndNil(ABitmapCanvas);
end;
FIsDrawBitmapDirty := False;
end;
BitBlt(ACanvas.Handle, AContentRect.Left, AContentRect.Top,
FDrawBitmap.Width, FDrawBitmap.Height, FDrawBitmap.Canvas.Handle, 0, 0, SRCCOPY);
end;
finally
RestoreCanvasFont(ACanvas, APrevLogFont);
end;
end;
procedure TcxCustomLabelViewInfo.SetBackgroundColor(Value: TColor);
begin
inherited SetBackgroundColor(Value);
FIsDrawBitmapDirty := True;
end;
{ TcxCustomLabelViewData }
procedure TcxCustomLabelViewData.CalculateLabelViewInfoProps(AViewInfo: TcxCustomEditViewInfo);
begin
with TcxCustomLabelViewInfo(AViewInfo) do
begin
LabelEffect := Properties.LabelEffect;
LabelStyle := Properties.LabelStyle;
Orientation := Properties.Orientation;
Depth := Properties.Depth;
ShadowedColor := Properties.ShadowedColor;
ShowAccelChar := Properties.ShowAccelChar;
Angle := Properties.Angle;
PenWidth := Properties.PenWidth;
WordWrap := Properties.WordWrap;
Alignment.Assign(Properties.Alignment);
Glyph := Properties.Glyph;
end;
end;
procedure TcxCustomLabelViewData.Calculate(ACanvas: TcxCanvas; const ABounds: TRect;
const P: TPoint; Button: TcxMouseButton; Shift: TShiftState; AViewInfo: TcxCustomEditViewInfo;
AIsMouseEvent: Boolean);
var
ALabelViewInfo: TcxCustomLabelViewInfo;
begin
inherited Calculate(ACanvas, ABounds, P, Button, Shift, AViewInfo, AIsMouseEvent);
if ((ABounds.Bottom >= MaxInt) or (ABounds.Right >= MaxInt)) and IsInplace then
Exit;
ALabelViewInfo := TcxCustomLabelViewInfo(AViewInfo);
{Standart properties}
ALabelViewInfo.IsEditClass := GetIsEditClass;
ALabelViewInfo.DrawSelectionBar := False;
ALabelViewInfo.HasPopupWindow := False;
ALabelViewInfo.DrawTextFlags := GetDrawTextFlags;
if AreVisualStylesMustBeUsed(ALabelViewInfo.NativeStyle, totButton) and
(ALabelViewInfo.BorderStyle = ebsNone) then
ALabelViewInfo.NativeStyle := False;
if not IsInplace then
ALabelViewInfo.Transparent := TcxCustomLabel(Edit).Transparent;
{Label properties}
CalculateLabelViewInfoProps(ALabelViewInfo);
ALabelViewInfo.DepthDeltaSize := Properties.CalculateDepthDelta;
ALabelViewInfo.TextRect := AViewInfo.ClientRect;
ALabelViewInfo.LabelTextRect := AViewInfo.ClientRect;
CalculateCustomLabelViewInfo(ACanvas, Self, ALabelViewInfo);
if not IsInplace then ALabelViewInfo.DrawSelectionBar := False;
if Edit <> nil then
ALabelViewInfo.LeftTop := Point(Edit.Left, Edit.Top);
ALabelViewInfo.DrawTextOffsets := GetTextEditDrawTextOffset(Self);
ALabelViewInfo.FIsDrawBitmapDirty := True;
end;
procedure TcxCustomLabelViewData.EditValueToDrawValue(ACanvas: TcxCanvas;
const AEditValue: TcxEditValue; AViewInfo: TcxCustomEditViewInfo);
begin
TcxCustomLabelViewInfo(AViewInfo).Text := EditValueToDisplayText(AEditValue);
end;
function TcxCustomLabelViewData.GetEditContentSize(ACanvas: TcxCanvas;
const AEditValue: TcxEditValue; const AEditSizeProperties: TcxEditSizeProperties): TSize;
function CalculateLabelTextSize(ACanvas: TcxCanvas; const AText: string;
const ATextRect: TRect; AAngle: Integer; ADepthSize,
AContentSizeCorrection: TSize; ALabelStyleOffset: Integer; AIsInplace,
AWordWrap, AShowAccelChar: Boolean): TSize;
var
ARealAngle, ATextFlag, ATextWidth: Integer;
ARealText: string;
ARect: TRect;
ARealWordWrap: Boolean;
begin
ARect := Rect(0, 0, RectWidth(ATextRect), RectHeight(ATextRect));
ARealAngle := (AAngle mod 360 + 360) mod 360;
ARealWordWrap := AWordWrap and (ARealAngle = 0);
if ARect.Right < 0 then
begin
if AIsInplace then
ARealWordWrap := False;
end
else
begin
Dec(ARect.Right, ADepthSize.cx + ALabelStyleOffset);
if (Style.BorderStyle <> ebsNone) and not AIsInplace then
Dec(ARect.Right, TextFromBorderOffset * 2);
if AIsInplace then
Dec(ARect.Right, AContentSizeCorrection.cx);
end;
ATextFlag := PrepareTextFlag(DT_CALCRECT, TAlignment(0),
TcxAlignmentVert(0), False,
ARealWordWrap, 0, True, AShowAccelChar and (ARealAngle = 0));
ARealText := AText;
if (ARealAngle <> 0) and AShowAccelChar then
ARealText := RemoveAccelChars(AText);
cxDrawText(ACanvas.Handle, ARealText, ARect, ATextFlag);
if ARealAngle <> 0 then
begin
ATextWidth := ARect.Right;
ARect.Right := Trunc(Abs(ARect.Right * Cos(ARealAngle * PI / 180)) +
Abs(ARect.Bottom * Sin(ARealAngle * PI / 180)) + 0.5);
ARect.Bottom := Trunc(Abs(ATextWidth * Sin(ARealAngle * PI / 180)) +
Abs(ARect.Bottom * Cos(ARealAngle * PI / 180)) + 0.5);
end;
Result.cx := ARect.Right;
Result.cy := ARect.Bottom;
Result.cx := Result.cx + ADepthSize.cx + ALabelStyleOffset;
Result.cy := Result.cy + ADepthSize.cy + ALabelStyleOffset;
if (Style.BorderStyle <> ebsNone) and not AIsInplace then
Result.cx := Result.cx + TextFromBorderOffset * 2;
if AIsInplace then
begin
Result.cx := Result.cx + AContentSizeCorrection.cx;
Result.cy := Result.cy + AContentSizeCorrection.cy;
end;
end;
var
ADisplayText: string;
ALabelStyleOffset: Integer;
APrevLogFont: TLogFont;
ARealAngle: Integer;
ASizeDelta: TSize;
begin
SaveCanvasFont(ACanvas, APrevLogFont);
try
Result := Size(0, 0);
if Edit <> nil then
ADisplayText := TcxCustomLabel(Edit).ViewInfo.Text
else
ADisplayText := EditValueToDisplayText(AEditValue);
if ADisplayText = '' then
ADisplayText := ' ';
Result.cx := AEditSizeProperties.Width;
ARealAngle := Integer(AdjustCanvasFont(ACanvas.Canvas, Style.GetVisibleFont, Properties.Angle)) *
Properties.Angle;
ASizeDelta := Properties.CalculateDepthDelta;
if Properties.LabelStyle in [cxlsRaised, cxlsLowered] then
begin
if ACanvas.Font.Size >= 12 then
ALabelStyleOffset := 2
else
ALabelStyleOffset := 1;
end
else
ALabelStyleOffset := 0;
with Properties do
Result := CalculateLabelTextSize(ACanvas, ADisplayText,
Rect(0, 0, Result.cx, Result.cy), ARealAngle, ASizeDelta,
Self.GetEditContentSizeCorrection, ALabelStyleOffset, IsInplace,
WordWrap, Properties.ShowAccelChar);
finally
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?