cxdrawtextutils.pas
来自「胜天进销存源码,国产优秀的进销存」· PAS 代码 · 共 994 行 · 第 1/3 页
PAS
994 行
ALeftIndent: Integer = 0; ARightIndent: Integer = 0): TRect;
begin
Result := R;
with Result do
begin
Dec(Left, ALeftIndent);
Inc(Right, ARightIndent);
end;
end;
{$WARNINGS OFF}
procedure cxTextRowsOutHighlight(AHandle: TCanvasHandle; const R: TRect;
const ATextParams: TcxTextParams; const ATextRows: TcxTextRows; ARowCount,
ASelStart, ASelLength: Integer; AColor, ATextColor: TColor; AForceEndEllipsis: Boolean);
procedure OutTextRow(const ATextRow: TcxTextRow);
var
Stub: Integer;
begin
with ATextRow do
if ATextParams.ExpandTabs then
begin
Stub := 0;
TabbedTextOut(AHandle, TextOriginX, TextOriginY, Text, TextLength, 0, Stub, TextOriginX);
end
else
TextOut(AHandle, TextOriginX, TextOriginY, Text, TextLength);
end;
procedure PrepareEndEllipsis(var ATextRow: TcxTextRow; var AWidth: Integer);
var
ACharNumber: Integer;
ASize: TSize;
begin
Dec(AWidth, ATextParams.EndEllipsisWidth);
if AWidth < 0 then AWidth := 0;
with ATextRow do
begin
if not GetTextExtentExPoint(AHandle, Text, TextLength, AWidth,
@ACharNumber, nil, ASize) then
ACharNumber := 0;
if ACharNumber = 0 then
ACharNumber := cxStrCharLength(Text);
TextLength := ACharNumber;
end;
cxCalcTextRowExtents(AHandle, ATextRow, ATextParams);
end;
procedure OutEndEllipsis(const ATextRow: TcxTextRow; var ARowRect: TRect);
const
ClipTexts: array[Boolean] of UINT = (0, ETO_CLIPPED);
var
fuOptions: UINT;
begin
Inc(ARowRect.Left, ATextRow.TextExtents.cx);
if ARowRect.Left < ARowRect.Right then
begin
fuOptions := ClipTexts[not ATextParams.NoClip and (ARowRect.Left + ATextParams.EndEllipsisWidth > ARowRect.Right)];
ExtTextOut(AHandle, ARowRect.Left, ATextRow.TextOriginY, fuOptions,
@ARowRect, PChar(cxEndEllipsisChars),
Length(cxEndEllipsisChars), nil);
end;
end;
function GetSubstringWidth(AText: PcxCaptionChar; ATextLength, ASubstringLength: Integer): Integer;
var
ACharExtents: array of Integer;
ATextSize: TSize;
begin
if ASubstringLength = 0 then
Result := 0
else
begin
SetLength(ACharExtents, ATextLength);
GetTextExtentExPoint(AHandle, AText, ATextLength, 0, nil, @ACharExtents[0], ATextSize);
Result := ACharExtents[ASubstringLength - 1];
end;
end;
var
ARowRect, AHighlightRect: TRect;
W, I, F, L: Integer;
ABreakExtra: Integer;
APrevBkMode: Integer;
ASaveTextColor: TColor;
ANeedClip, ANeedEndEllipsis: Boolean;
ATextRow: TcxTextRow;
AHighlightStart, AHighlightEnd: Integer;
ARgn, ASaveClipRgn: HRGN;
ABrush: HBRUSH;
begin
AColor := ColorToRGB(AColor);
ATextColor := ColorToRGB(ATextColor);
W := R.Right - R.Left;
ARowRect := R;
APrevBkMode := SetBkMode(AHandle, Windows.TRANSPARENT);
if (ASelLength > 0) and (AColor <> clNone) then
ABrush := CreateSolidBrush(AColor);
for I := 0 to ARowCount - 1 do
begin
ATextRow := ATextRows[I];
with ATextRow do
begin
if TextLength <> 0 then
begin
ARowRect.Top := TextOriginY;
ARowRect.Bottom := ARowRect.Top + ATextParams.FullRowHeight;
ANeedEndEllipsis := ATextParams.EndEllipsis and (I = ARowCount - 1) and
((TextExtents.cx > W) or AForceEndEllipsis);
ABreakExtra := 0;
if (ATextParams.TextAlignX in [taJustifyX, taDistributeX]) and not ANeedEndEllipsis then
begin
ABreakExtra := W - TextExtents.cX;
if (BreakCount <> 0) and (ABreakExtra > 0) then
SetTextJustification(AHandle, ABreakExtra, BreakCount);
end;
ANeedClip := not ATextParams.NoClip and ((TextExtents.cX > W) or
(ARowRect.Top < R.Top) or (ARowRect.Bottom > R.Bottom));
if ANeedClip then
begin
if ARowRect.Top < R.Top then ARowRect.Top := R.Top;
if ARowRect.Bottom > R.Bottom then ARowRect.Bottom := R.Bottom;
ARgn := IntersectClipRect(AHandle, ARowRect);
end;
if ANeedEndEllipsis then
PrepareEndEllipsis(ATextRow, W);
if ASelLength > 0 then
begin
if not ((ASelStart >= StartOffset + TextLength) or
(ASelStart + ASelLength <= StartOffset)) then
begin
F := Max(ASelStart, StartOffset);
L := Min(ASelStart + ASelLength, StartOffset + TextLength);
Dec(F, StartOffset);
Dec(L, StartOffset);
if L > F then
begin
AHighlightStart := GetSubstringWidth(Text, TextLength, F);
AHighlightEnd := GetSubstringWidth(Text, TextLength, L);
if cxGetWritingDirection(ATextParams.CharSet, Text) = coRightToLeft then
begin
AHighlightRect.Left := TextOriginX + TextExtents.cx - AHighlightEnd;
AHighlightRect.Right := TextOriginX + TextExtents.cx - AHighlightStart;
end
else
begin
AHighlightRect.Left := TextOriginX + AHighlightStart;
AHighlightRect.Right := TextOriginX + AHighlightEnd;
end;
AHighlightRect.Top := ARowRect.Top;
AHighlightRect.Bottom := ARowRect.Bottom;
if not IsRectEmpty(AHighlightRect) then
begin
ASaveClipRgn := IntersectClipRect(AHandle, AHighlightRect);
if AColor <> clNone then
FillRect(AHandle, AHighlightRect, ABrush);
ASaveTextColor := SetTextColor(AHandle, ATextColor);
OutTextRow(ATextRow);
SetTextColor(AHandle, ASaveTextColor);
RestoreClipRgn(AHandle, ASaveClipRgn);
with AHighlightRect do
ExcludeClipRect(AHandle, Left, Top, Right, Bottom);
if ANeedEndEllipsis and (ASelStart + ASelLength >= StartOffset + TextLength) then
begin
ANeedEndEllipsis := False;
ASaveTextColor := SetTextColor(AHandle, ATextColor);
OutEndEllipsis(ATextRow, ARowRect);
SetTextColor(AHandle, ASaveTextColor);
end;
end;
end;
end
end;
OutTextRow(ATextRow);
if ANeedEndEllipsis then
OutEndEllipsis(ATextRow, ARowRect);
if ANeedClip then
RestoreClipRgn(AHandle, ARgn);
if ABreakExtra > 0 then SetTextJustification(AHandle, 0, 0);
end
else
if AForceEndEllipsis and ATextParams.EndEllipsis and (I = ARowCount - 1) then
begin
ARowRect.Top := TextOriginY;
ARowRect.Bottom := ARowRect.Top + ATextParams.FullRowHeight;
PrepareEndEllipsis(ATextRow, W);
OutEndEllipsis(ATextRow, ARowRect);
end;
end;
end;
if (ASelLength > 0) and (AColor <> clNone) then
DeleteObject(ABrush);
SetBkMode(AHandle, APrevBkMode);
end;
{$WARNINGS ON}
function cxGetLongestTextRowWidth(const ATextRows: TcxTextRows; ARowCount: Integer): Integer;
var
I, V: Integer;
begin
if ARowCount > Length(ATextRows) then ARowCount := Length(ATextRows);
if ARowCount = 0 then
Result := 0
else
begin
Result := ATextRows[0].TextExtents.cx;
for I := 1 to ARowCount - 1 do
begin
V := ATextRows[I].TextExtents.cx;
if V > Result then Result := V;
end;
end;
end;
function cxTextOut(AHandle: TCanvasHandle; AText: PcxCaptionChar; var R: TRect;
AFormat: TcxTextOutFormat; ASelStart, ASelLength: Integer;
AColor, ATextColor: TColor; AMaxLineCount: Integer = 0;
ALeftIndent: Integer = 0; ARightIndent: Integer = 0): Integer;
function ProcessText(const ATextParams: TcxTextParams; const ATextRect: TRect): Boolean;
begin
if ATextParams.CalcRect then
Result := (ATextRect.Right - ATextRect.Left) > 0
else
Result := not IsRectEmpty(ATextRect);
end;
var
ATextHeight, ARowCount, ATextLength: Integer;
ATextParams: TcxTextParams;
ATextRect: TRect;
ATextRows: TcxTextRows;
AForceEndEllipsis: Boolean;
begin
Result := 0;
ATextLength := StrLen(AText);
if ATextLength = 0 then Exit;
ATextParams := cxCalcTextParams(AHandle, AFormat);
ATextRect := cxPrepareRect(R, ATextParams, ALeftIndent, ARightIndent);
ATextHeight := 0;
if ProcessText(ATextParams, ATextRect) then
begin
ATextRows := nil;
AForceEndEllipsis := not cxMakeTextRows(AHandle, (AText), ATextRect, ATextParams, ATextRows, ARowCount, AMaxLineCount);
if ARowCount <> 0 then
try
if ATextParams.CalcRect then
begin
if (AMaxLineCount > 0) and (AMaxLineCount < ARowCount) then
ARowCount := AMaxLineCount;
ATextRect.Right := ATextRect.Left + cxGetLongestTextRowWidth(ATextRows, ARowCount);
if not ATextParams.SingleLine then
begin
ATextRows := nil;
cxMakeTextRows(AHandle, (AText), ATextRect, ATextParams, ATextRows, ARowCount, AMaxLineCount);
end;
cxPlaceTextRows(AHandle, ATextRect, ATextParams, ATextRows, ARowCount);
ATextRect.Bottom := ATextRows[ARowCount - 1].TextOriginY + ATextParams.RowHeight;
R := cxUnprepareRect(ATextRect, ATextParams, ALeftIndent, ARightIndent);
end
else
begin
if (AMaxLineCount > 0) and (ARowCount >= AMaxLineCount) then
begin
ARowCount := AMaxLineCount;
with ATextParams do
AForceEndEllipsis := AForceEndEllipsis and EndEllipsis and EditControl and not SingleLine;
end
else
AForceEndEllipsis := False;
cxPlaceTextRows(AHandle, ATextRect, ATextParams, ATextRows, ARowCount);
if (ASelStart < 0) or (ASelStart >= ATextLength) then
ASelLength := 0
else
if (ASelLength + ASelStart) > ATextLength then
ASelLength := ATextLength - ASelStart;
cxTextRowsOutHighlight(AHandle, ATextRect, ATextParams, ATextRows,
ARowCount, ASelStart, ASelLength, AColor, ATextColor, AForceEndEllipsis);
end;
ATextHeight := ATextRows[ARowCount - 1].TextOriginY + ATextParams.RowHeight - ATextRect.Top;
finally
ATextRows := nil;
end;
end;
if ATextParams.CalcRowCount or (ATextHeight = 0) then
Result := ARowCount
else
Result := ATextHeight;
end;
function cxTextOut(ACanvas: TCanvas; AText: PcxCaptionChar; var R: TRect;
AFormat: TcxTextOutFormat; ASelStart, ASelLength: Integer;
AColor, ATextColor: TColor; AMaxLineCount: Integer = 0;
ALeftIndent: Integer = 0; ARightIndent: Integer = 0): Integer;
begin
Result := cxTextOut(ACanvas.Handle, AText, R, AFormat, ASelStart, ASelLength,
AColor, ATextColor, AMaxLineCount, ALeftIndent, ARightIndent);
end;
function cxTextOut(ACanvas: TCanvas; AText: PcxCaptionChar; var R: TRect;
AFormat: TcxTextOutFormat = CXTO_DEFAULT_FORMAT; AMaxLineCount: Integer = 0;
ALeftIndent: Integer = 0; ARightIndent: Integer = 0): Integer;
begin
Result := cxTextOut(ACanvas, AText, R, AFormat, 0, 0, ACanvas.Font.Color, clBlack,
AMaxLineCount, ALeftIndent, ARightIndent);
end;
function cxTextOut(AHandle: TCanvasHandle; AText: PcxCaptionChar; var R: TRect;
AFormat: TcxTextOutFormat = CXTO_DEFAULT_FORMAT; AMaxLineCount: Integer = 0;
ALeftIndent: Integer = 0; ARightIndent: Integer = 0): Integer;
begin
Result := cxTextOut(AHandle, AText, R, AFormat, 0, 0, GetTextColor(AHandle), clBlack,
AMaxLineCount, ALeftIndent, ARightIndent);
end;
initialization
cxEndEllipsisCharsLength := Length(cxEndEllipsisChars);
end.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?