git-svn-id: https://192.168.0.254/svn/Componentes.Terceros.jvcl@12 7f62d464-2af8-f54e-996c-e91b33f51cbe
683 lines
18 KiB
ObjectPascal
683 lines
18 KiB
ObjectPascal
{-----------------------------------------------------------------------------
|
|
The contents of this file are subject to the Mozilla Public License
|
|
Version 1.1 (the "License"); you may not use this file except in compliance
|
|
with the License. You may obtain a copy of the License at
|
|
http://www.mozilla.org/MPL/MPL-1.1.html
|
|
|
|
Software distributed under the License is distributed on an "AS IS" basis,
|
|
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
|
|
the specific language governing rights and limitations under the License.
|
|
|
|
The Original Code is: JvClxUtils.pas released on 2003-10-25.
|
|
|
|
The Initial Developer of the Original Code is Marcel Bestebroer
|
|
Portions created by Andreas Hausladen are Copyright (C) 2003 Andreas Hausladen,
|
|
[Andreas dott Hausladen att gmx dott de] and André Snepvangers
|
|
All Rights Reserved.
|
|
|
|
Contributor(s):
|
|
|
|
Last Modified: 2003-10-31
|
|
|
|
You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
|
|
located at http://jvcl.sourceforge.net
|
|
|
|
Known Issues:
|
|
-----------------------------------------------------------------------------}
|
|
|
|
{$I jvcl.inc}
|
|
|
|
unit JvClxUtils;
|
|
|
|
interface
|
|
|
|
uses
|
|
{$IFDEF MSWINDOWS}
|
|
Windows,
|
|
{$ENDIF MSWINDOWS}
|
|
{$IFDEF LINUX}
|
|
Libc,
|
|
{$ENDIF LINUX}
|
|
{$IFDEF VCL}
|
|
Graphics,
|
|
{$ENDIF VCL}
|
|
{$IFDEF VisualCLX}
|
|
Qt, QTypes, Types, QGraphics,
|
|
{$ENDIF VisualCLX}
|
|
SysUtils, Classes;
|
|
|
|
{$IFDEF LINUX}
|
|
type
|
|
TColorRef = Integer;
|
|
{$ENDIF LINUX}
|
|
|
|
{$IFDEF VisualCLX}
|
|
|
|
const
|
|
VK_UP = Key_Up;
|
|
VK_DOWN = Key_Down;
|
|
VK_RIGHT = Key_Right;
|
|
VK_LEFT = Key_Left;
|
|
VK_ESCAPE = Key_Escape;
|
|
VK_TAB = Key_Tab;
|
|
VK_SPACE = Key_Space;
|
|
VK_ENTER = Key_Enter;
|
|
VK_RETURN = Key_Return;
|
|
VK_BACKTAB = Key_Backtab;
|
|
VK_BACKSPACE = Key_Backspace;
|
|
VK_PRIOR = Key_Prior;
|
|
VK_NEXT = Key_Next;
|
|
VK_HOME = Key_Home;
|
|
VK_END = Key_End;
|
|
VK_ADD = Key_Plus;
|
|
VK_SUBTRACT = Key_Minus;
|
|
|
|
function GetSysColor(Color: Integer): TColorRef;
|
|
|
|
procedure SetWindowPlacement(Handle: QWidgetH; W: PWindowPlacement);
|
|
procedure GetWindowPlacement(Handle: QWidgetH; W: PWindowPlacement);
|
|
function IsWindowVisible(Handle: QWidgetH): Boolean;
|
|
function IsWindowEnabled(Handle: QWidgetH): Boolean;
|
|
procedure EnableWindow(Handle: QWidgetH; Value: Boolean);
|
|
procedure SwitchToThisWindow(Handle: QWidgetH; Restore: Boolean);
|
|
procedure SetFocus(Handle: QWidgetH);
|
|
|
|
function RGB(Red, Green, Blue: Integer): TColorRef;
|
|
function GetBValue(Col: TColorRef): Integer;
|
|
function GetGValue(Col: TColorRef): Integer;
|
|
function GetRValue(Col: TColorRef): Integer;
|
|
|
|
{$IFDEF LINUX}
|
|
function GetTickCount: Cardinal;
|
|
function MakeIntResource(Value: Integer): PChar;
|
|
{$ENDIF LINUX}
|
|
|
|
type
|
|
TSysMetrics =
|
|
(
|
|
SM_CXSCREEN, SM_CYSCREEN,
|
|
SM_CXVSCROLL, SM_CYVSCROLL,
|
|
SM_CXSMICON, SM_CXICON,
|
|
SM_CXBORDER, SM_CYBORDER,
|
|
SM_CXFRAME, SM_CYFRAME
|
|
);
|
|
|
|
// limited implementation of
|
|
|
|
function GetSystemMetrics(PropItem: TSysMetrics): Integer;
|
|
|
|
function TruncatePath(const FilePath: string; Canvas: TCanvas; MaxLen: Integer): string;
|
|
function TruncateName(const Name: String; Canvas: TCanvas; MaxLen: Integer): string;
|
|
|
|
const
|
|
// constants for Canvas.TextRect converted from enummeration
|
|
AlignLeft = 1; // $0001
|
|
AlignRight = 2; // $0002
|
|
AlignHCenter = 4; // $0004
|
|
AlignTop = 8; // $0008
|
|
AlignBottom = 16; // $0010
|
|
AlignVCenter = 32; // $0020
|
|
AlignCenter = 36; // $0024
|
|
SingleLine = 64; // $0040
|
|
DontClip = 128; // $0080
|
|
ExpandTabs = 256; // $0100
|
|
ShowPrefix = 512; // $0200
|
|
WordBreak = 1024; // $0400
|
|
ModifyString = 2048; // $0800 // not supported by TextRect but by ClxDrawText
|
|
DontPrint = 4096; // $1000
|
|
ClipPath = 8192; // $2000 // not supported by TextRect but by ClxDrawText
|
|
ClipName = 16384; // $4000 // not supported by TextRect but by ClxDrawText
|
|
CalcRect = 32768; // $8000 // not supported by TextRect but by ClxDrawText
|
|
|
|
pf24bit = pf32bit;
|
|
|
|
{$ENDIF VisualCLX}
|
|
|
|
const
|
|
DT_ELLIPSIS = DT_END_ELLIPSIS;
|
|
|
|
{$IFDEF LINUX}
|
|
const
|
|
{ ClxDrawText() Format Flags }
|
|
DT_TOP = 0; // default
|
|
DT_LEFT = 0; // default
|
|
DT_CENTER = 1;
|
|
DT_RIGHT = 2;
|
|
DT_VCENTER = 4;
|
|
DT_BOTTOM = 8;
|
|
DT_WORDBREAK = $10;
|
|
DT_SINGLELINE = $20;
|
|
DT_EXPANDTABS = $40;
|
|
//DT_TABSTOP = $80;
|
|
DT_NOCLIP = $100;
|
|
//DT_EXTERNALLEADING = $200;
|
|
DT_CALCRECT = $400;
|
|
DT_NOPREFIX = $800;
|
|
//DT_INTERNAL = $1000;
|
|
//DT_HIDEPREFIX = $00100000;
|
|
//DT_PREFIXONLY = $00200000;
|
|
|
|
//DT_EDITCONTROL = $2000;
|
|
DT_PATH_ELLIPSIS = $4000;
|
|
DT_END_ELLIPSIS = $8000;
|
|
DT_ELLIPSIS = DT_END_ELLIPSIS;
|
|
DT_MODIFYSTRING = $10000;
|
|
// DT_RTLREADING = $20000;
|
|
// DT_WORD_ELLIPSIS = $40000;
|
|
|
|
{ ClxExtTextOut() Format Flags }
|
|
ETO_OPAQUE = 2;
|
|
ETO_CLIPPED = 4;
|
|
//ETO_GLYPH_INDEX = $10;
|
|
ETO_RTLREADING = $80; // ignored
|
|
//ETO_NUMERICSLOCAL = $400;
|
|
//ETO_NUMERICSLATIN = $800;
|
|
//ETO_IGNORELANGUAGE = $1000;
|
|
//ETO_PDY = $2000;
|
|
|
|
{ ShowWindow() Commands }
|
|
SW_HIDE = 0;
|
|
SW_SHOWNORMAL = 1;
|
|
SW_NORMAL = 1;
|
|
SW_SHOWMINIMIZED = 2;
|
|
SW_SHOWMAXIMIZED = 3;
|
|
SW_MAXIMIZE = 3;
|
|
SW_SHOWNOACTIVATE = 4;
|
|
SW_SHOW = 5;
|
|
SW_MINIMIZE = 6;
|
|
SW_SHOWMINNOACTIVE = 7;
|
|
SW_SHOWNA = 8;
|
|
SW_RESTORE = 9;
|
|
SW_SHOWDEFAULT = 10;
|
|
SW_MAX = 10;
|
|
{$ENDIF LINUX}
|
|
|
|
|
|
function ClxDrawText(Canvas: TCanvas; var Caption: string; var R: TRect;
|
|
Flags: Integer): Integer;
|
|
function ClxDrawTextW(Canvas: TCanvas; var Caption: WideString; var R: TRect;
|
|
Flags: Integer): Integer;
|
|
|
|
function ClxExtTextOut(Canvas: TCanvas; X, Y: Integer; Flags: Integer;
|
|
Rect: PRect; const Text: string; lpDx: Pointer): Boolean;
|
|
function ClxExtTextOutW(Canvas: TCanvas; X, Y: Integer; Flags: Integer;
|
|
Rect: PRect; const Text: WideString; lpDx: Pointer): Boolean;
|
|
|
|
implementation
|
|
|
|
{$IFDEF VisualCLX}
|
|
|
|
var
|
|
SysColorPalette: TPalette = nil;
|
|
|
|
function GetSysColor(Color: Integer): TColorRef;
|
|
begin
|
|
if not Assigned(SysColorPalette) then
|
|
SysColorPalette := TPalette.Create;
|
|
Result := TColorRef(SysColorPalette.GetColor(Color));
|
|
end;
|
|
|
|
procedure EnableWindow(Handle: QWidgetH; Value: Boolean);
|
|
begin
|
|
QWidget_setEnabled(Handle, Value);
|
|
end;
|
|
|
|
procedure SetWindowPlacement(Handle: QWidgetH; W: PWindowPlacement);
|
|
begin
|
|
with W.rcNormalPosition do
|
|
QWidget_setGeometry(Handle, Left, Top, Right - Left, Bottom - Top);
|
|
case W.ShowCmd of
|
|
SW_MINIMIZE, SW_SHOWMINIMIZED, SW_SHOWMINNOACTIVE:
|
|
QWidget_showMinimized(Handle);
|
|
SW_MAXIMIZE:
|
|
QWidget_showMaximized(Handle);
|
|
SW_HIDE:
|
|
QWidget_hide(Handle);
|
|
else
|
|
QWidget_showNormal(Handle);
|
|
end;
|
|
end;
|
|
|
|
procedure GetWindowPlacement(Handle: QWidgetH; W: PWindowPlacement);
|
|
var
|
|
R : TRect;
|
|
begin
|
|
QWidget_geometry(Handle, @R);
|
|
W.rcNormalPosition.Left := R.Left;
|
|
W.rcNormalPosition.Top := R.Top;
|
|
W.rcNormalPosition.Right := R.Right;
|
|
W.rcNormalPosition.Bottom := R.Left;
|
|
if QWidget_isMinimized(Handle) then
|
|
W.showCmd := SW_SHOWMINIMIZED
|
|
else
|
|
if QWidget_isMaximized(Handle) then
|
|
W.showCmd := SW_SHOWMAXIMIZED
|
|
else
|
|
if not QWidget_isVisible(Handle) then
|
|
W.showCmd := SW_HIDE
|
|
else
|
|
W.showCmd := SW_SHOWNORMAL;
|
|
end;
|
|
|
|
function IsWindowVisible(Handle: QWidgetH): Boolean;
|
|
begin
|
|
Result := QWidget_isVisible(Handle);
|
|
end;
|
|
|
|
function IsWindowEnabled(Handle: QWidgetH): Boolean;
|
|
begin
|
|
Result := QWidget_isEnabled(Handle);
|
|
end;
|
|
|
|
procedure SetFocus(Handle: QWidgetH);
|
|
begin
|
|
QWidget_setFocus(Handle);
|
|
end;
|
|
|
|
procedure SetForegroundWindow(Handle: QWidgetH);
|
|
begin
|
|
QWidget_raise(Handle);
|
|
end;
|
|
|
|
procedure SwitchToThisWindow(Handle: QWidgetH; Restore: Boolean);
|
|
begin
|
|
if Restore then
|
|
QWidget_Show(Handle);
|
|
QWidget_setActiveWindow(Handle);
|
|
end;
|
|
|
|
// limited implementation of
|
|
|
|
function GetSystemMetrics(PropItem: TSysMetrics): Integer;
|
|
var
|
|
Size: TSize;
|
|
begin
|
|
case PropItem of
|
|
SM_CXVSCROLL:
|
|
begin
|
|
QStyle_scrollBarExtent(QApplication_style, @Size);
|
|
Result := Size.cx;
|
|
end;
|
|
SM_CYVSCROLL:
|
|
begin
|
|
QStyle_scrollBarExtent(QApplication_style, @Size);
|
|
Result := Size.cy;
|
|
end;
|
|
SM_CXSMICON:
|
|
Result := 16;
|
|
SM_CXICON:
|
|
Result := 32;
|
|
SM_CXSCREEN:
|
|
Result := QWidget_width(QApplication_desktop);
|
|
SM_CYSCREEN:
|
|
Result := QWidget_height(QApplication_desktop);
|
|
SM_CXBORDER, SM_CYBORDER:
|
|
Result := QClxStyle_defaultFrameWidth(QClxStyleH(QApplication_style)); // (probably) wrong ?
|
|
SM_CXFRAME, SM_CYFRAME:
|
|
Result := QClxStyle_defaultFrameWidth(QClxStyleH(QApplication_style)); // or this one
|
|
else
|
|
Result := 0;
|
|
end;
|
|
end;
|
|
|
|
function RGB(Red, Green, Blue: Integer): TColorRef;
|
|
begin
|
|
Result := (Blue shl 16) or (Green shl 8) or Red;
|
|
end;
|
|
|
|
function GetBValue(Col: TColorRef): Integer;
|
|
begin
|
|
Result := (Col shr 16) and $FF;
|
|
end;
|
|
|
|
function GetGValue(Col: TColorRef): Integer;
|
|
begin
|
|
Result := (Col shr 8) and $FF;
|
|
end;
|
|
|
|
function GetRValue(Col: TColorRef): Integer;
|
|
begin
|
|
Result := Col and $FF;
|
|
end;
|
|
|
|
{$IFDEF LINUX}
|
|
|
|
function GetTickCount: Cardinal;
|
|
var
|
|
Info: TSysInfo;
|
|
TimeVal: TTimeVal;
|
|
begin
|
|
sysinfo(Info);
|
|
gettimeofday(TimeVal, nil);
|
|
Result := Cardinal((Int64(Info.uptime) * 1000) + Round(TimeVal.tv_usec / 1000));
|
|
end;
|
|
|
|
function MakeIntResource(Value: Integer): PChar;
|
|
begin
|
|
Result := PChar(Value and $0000ffff);
|
|
end;
|
|
|
|
{$ENDIF LINUX}
|
|
|
|
const
|
|
cEllipsis = '...';
|
|
|
|
function TruncatePath(const FilePath: string; Canvas: TCanvas; MaxLen: Integer): string;
|
|
var
|
|
Paths: TStringList;
|
|
K, I, Start: Integer;
|
|
CurPath: string;
|
|
begin
|
|
if Canvas.TextWidth(FilePath) <= MaxLen then
|
|
Result := FilePath
|
|
else
|
|
begin // FilePath too long
|
|
Paths := TStringList.Create;
|
|
try
|
|
Paths.Delimiter := PathDelim;
|
|
Paths.DelimitedText := FilePath; // splits the filepath
|
|
if Length(Paths[0]) = 0 then
|
|
Start := 1
|
|
else
|
|
Start := 0;
|
|
for K := Start to Paths.Count - 2 do
|
|
begin
|
|
CurPath := Paths[K];
|
|
if Length(CurPath) > 2 then // this excludes ~ ..
|
|
begin
|
|
Paths[K] := cEllipsis; // replace with ellipsis
|
|
I := 1;
|
|
while Canvas.TextWidth(Paths.DelimitedText) <= MaxLen do
|
|
begin
|
|
Paths[K] := Copy(CurPath, I, MaxInt) + cEllipsis; // add a character
|
|
Inc(I);
|
|
end;
|
|
if I <> 1 then
|
|
begin
|
|
// remove last added character
|
|
Paths[K] := Copy(Paths[K], 2, MaxInt);
|
|
Result := Paths.DelimitedText ; // something /.../P../bin/file.tst
|
|
Exit; // ready
|
|
end;
|
|
end
|
|
end;
|
|
// not succeeded.
|
|
// replace /.../.../.../<filename> with .../<filename>
|
|
// before starting to minimize filename
|
|
for K := Paths.Count - 2 downto 1 do
|
|
Paths.Delete(K);
|
|
Paths[0] := cEllipsis;
|
|
if Canvas.TextWidth(Paths.DelimitedText) > MaxLen then
|
|
begin
|
|
CurPath := Paths[1];
|
|
Paths[1] := cEllipsis; // replace with ellipsis
|
|
I := 1 ;
|
|
while Canvas.TextWidth(Paths.DelimitedText) <= MaxLen do
|
|
begin
|
|
Paths[1] := Copy(CurPath, I, MaxInt) + cEllipsis;
|
|
Inc(I);
|
|
end;
|
|
if I <> 1 then
|
|
Paths[1] := Copy(Paths[1], 2, MaxInt);
|
|
end;
|
|
Result := Paths.DelimitedText; // will be something .../Progr...
|
|
finally
|
|
Paths.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TruncateName(const Name: String; Canvas: TCanvas; MaxLen: Integer): string;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if Canvas.TextWidth(Name) <= MaxLen then
|
|
Result := Name
|
|
else
|
|
begin
|
|
Result := cEllipsis; // replace with ellipsis
|
|
I := 1;
|
|
while Canvas.TextWidth(Result) <= MaxLen do
|
|
begin
|
|
Result := Copy(Name, I, MaxInt) + cEllipsis; // add a character
|
|
Inc(I);
|
|
end;
|
|
if I <> 1 then
|
|
// remove last added character
|
|
Delete(Result, 1, 1);
|
|
end;
|
|
end;
|
|
|
|
{$ENDIF VisualCLX}
|
|
|
|
type
|
|
TOpenCanvas = class(TCanvas);
|
|
|
|
function ClxDrawText(Canvas: TCanvas; var Caption: string; var R: TRect;
|
|
Flags: Integer): Integer;
|
|
{$IFNDEF VCL}
|
|
var
|
|
W: WideString;
|
|
{$ENDIF VCL}
|
|
begin
|
|
{$IFDEF VCL}
|
|
TOpenCanvas(Canvas).Changing;
|
|
Result := DrawText(Canvas.Handle, PChar(Caption), Length(Caption), R, Flags);
|
|
TOpenCanvas(Canvas).Changed;
|
|
{$ELSE}
|
|
W := Caption;
|
|
Result := ClxDrawTextW(Canvas, W, R, Flags);
|
|
if Flags and DT_MODIFYSTRING <> 0 then
|
|
Caption := W;
|
|
{$ENDIF VCL}
|
|
end;
|
|
|
|
function ClxDrawTextW(Canvas: TCanvas; var Caption: WideString; var R: TRect;
|
|
Flags: Integer): Integer;
|
|
{$IFDEF VisualCLX}
|
|
var
|
|
Flgs: Word;
|
|
Text: string;
|
|
{$ENDIF VisualCLX}
|
|
begin
|
|
{$IFDEF VCL}
|
|
TOpenCanvas(Canvas).Changing;
|
|
Result := DrawTextW(Canvas.Handle, PWideChar(Caption), Length(Caption), R, Flags);
|
|
TOpenCanvas(Canvas).Changed;
|
|
{$ENDIF VCL}
|
|
{$IFDEF VisualCLX}
|
|
Text := Caption;
|
|
with Canvas do
|
|
begin
|
|
Flgs := 0;
|
|
if Flags and DT_SINGLELINE <> 0 then
|
|
Flgs := SingleLine;
|
|
if Flags and DT_WORDBREAK <> 0 then
|
|
Flgs := Flgs or WordBreak;
|
|
if Flags and DT_EXPANDTABS <> 0 then
|
|
Flgs := Flgs or ExpandTabs;
|
|
if Flags and DT_NOPREFIX = 0 then
|
|
Flgs := Flgs or ShowPrefix;
|
|
if Flags and DT_RIGHT <> 0 then
|
|
Flgs := Flgs or AlignRight
|
|
else
|
|
if Flags and DT_CENTER <> 0 then
|
|
Flgs := Flgs or AlignHCenter
|
|
else
|
|
Flgs := Flgs or AlignLeft ; // default
|
|
// vertical alignment
|
|
if Flags and DT_BOTTOM <> 0 then
|
|
Flgs := Flgs or AlignTop
|
|
else
|
|
if Flags and DT_VCENTER <> 0 then
|
|
Flgs := Flgs or AlignVCenter
|
|
else
|
|
Flgs := Flgs or AlignTop; // default
|
|
|
|
if Flags and DT_ELLIPSIS <> 0 then
|
|
Text := TruncateName(Text, Canvas, R.Right - R.Left)
|
|
else
|
|
if Flags and DT_PATH_ELLIPSIS <> 0 then
|
|
Text := TruncatePath(Text, Canvas, R.Right - R.Left)
|
|
else
|
|
if Flags and DT_CALCRECT <> 0 then
|
|
begin
|
|
TextExtent(Caption, R, Flgs);
|
|
Result := R.Bottom - R.Top;
|
|
Exit;
|
|
end;
|
|
Canvas.TextRect(R, R.Left, R.Top, Text, Flgs);
|
|
if Flags and DT_MODIFYSTRING <> 0 then
|
|
Caption := Text;
|
|
end;
|
|
Result := 1;
|
|
{$ENDIF VisualCLX}
|
|
end;
|
|
|
|
function ClxExtTextOut(Canvas: TCanvas; X, Y: Integer; Flags: Integer; Rect: PRect;
|
|
const Text: string; lpDx: Pointer): Boolean;
|
|
begin
|
|
{$IFDEF VCL}
|
|
TOpenCanvas(Canvas).Changing;
|
|
Result := ExtTextOut(Canvas.Handle, X, Y, Flags, Rect, PChar(Text),
|
|
Length(Text), lpDx);
|
|
TOpenCanvas(Canvas).Changed;
|
|
{$ELSE}
|
|
Result := ClxExtTextOutW(Canvas, X, Y, Flags, Rect, WideString(Text), lpDx);
|
|
{$ENDIF VCL}
|
|
end;
|
|
|
|
function ClxExtTextOutW(Canvas: TCanvas; X, Y: Integer; Flags: Integer;
|
|
Rect: PRect; const Text: WideString; lpDx: Pointer): Boolean;
|
|
{$IFDEF VisualCLX}
|
|
{ TODO missing feature: horizontal text alignment }
|
|
var
|
|
RecallBrush: TBrush;
|
|
RecallPenPos: TPoint;
|
|
WS: WideString;
|
|
Index, Width: Integer;
|
|
Dx: PInteger;
|
|
R, CellRect: TRect;
|
|
TextLen: Integer;
|
|
{$ENDIF VisualCLX}
|
|
begin
|
|
{$IFDEF VCL}
|
|
TOpenCanvas(Canvas).Changing;
|
|
Result := ExtTextOutW(Canvas.Handle, X, Y, Flags, Rect, PWideChar(Text),
|
|
Length(Text), lpDx);
|
|
TOpenCanvas(Canvas).Changed;
|
|
{$ENDIF VCL}
|
|
{$IFDEF VisualCLX}
|
|
Canvas.Start;
|
|
try
|
|
with Canvas do
|
|
begin
|
|
Result := False;
|
|
if (Text = '') then
|
|
Exit;
|
|
if (Flags and ETO_CLIPPED <> 0) and (Rect = nil) then
|
|
Flags := Flags and not ETO_CLIPPED;
|
|
|
|
RecallPenPos := PenPos;
|
|
Result := True;
|
|
RecallBrush := nil;
|
|
try
|
|
if Flags and ETO_OPAQUE <> 0 then
|
|
begin
|
|
if Brush.Style <> bsSolid then
|
|
begin
|
|
RecallBrush := TBrush.Create;
|
|
RecallBrush.Assign(Brush);
|
|
Brush.Style := bsSolid;
|
|
end;
|
|
if Rect <> nil then
|
|
FillRect(Rect^);
|
|
end
|
|
else
|
|
if Brush.Style = bsSolid then
|
|
begin
|
|
RecallBrush := TBrush.Create;
|
|
RecallBrush.Assign(Brush);
|
|
Brush.Style := bsClear;
|
|
end;
|
|
|
|
if lpDx = nil then
|
|
begin
|
|
if (Flags and ETO_CLIPPED <> 0) then
|
|
TextRect(Rect^, X, Y, Text)
|
|
else
|
|
TextOut(X, Y, Text);
|
|
end
|
|
else
|
|
begin
|
|
// put each char in its cell
|
|
TextLen := Length(Text);
|
|
if (Flags and ETO_OPAQUE <> 0) and (Rect = nil) then
|
|
begin
|
|
Dx := lpDx;
|
|
Width := 0;
|
|
for Index := 1 to TextLen do
|
|
begin
|
|
Inc(Width, Dx^);
|
|
Inc(Dx);
|
|
end;
|
|
R.Left := X;
|
|
R.Right := X + Width;
|
|
R.Top := Y;
|
|
R.Bottom := Y + TextHeight(Text);
|
|
FillRect(R);
|
|
end;
|
|
|
|
Dx := lpDx;
|
|
SetLength(WS, 1);
|
|
for Index := 1 to TextLen do
|
|
begin
|
|
if (Rect <> nil) and (X >= Rect^.Right) then
|
|
Break;
|
|
|
|
WS[1] := Text[Index];
|
|
if Flags and ETO_CLIPPED <> 0 then
|
|
begin
|
|
CellRect.Left := X;
|
|
CellRect.Right := X + Dx^;
|
|
CellRect.Top := Rect^.Top;
|
|
CellRect.Bottom := Rect^.Bottom;
|
|
if CellRect.Right > Rect^.Right then
|
|
CellRect.Right := Rect^.Right;
|
|
TextRect(R, X, Y, WS);
|
|
end
|
|
else
|
|
TextOut(X, Y, WS);
|
|
|
|
if Index = TextLen then
|
|
Break;
|
|
|
|
Inc(X, Dx^);
|
|
Inc(Dx);
|
|
end;
|
|
end;
|
|
finally
|
|
if Assigned(RecallBrush) then
|
|
begin
|
|
Brush.Assign(RecallBrush);
|
|
RecallBrush.Free;
|
|
end;
|
|
end;
|
|
PenPos := RecallPenPos;
|
|
end;
|
|
finally
|
|
Canvas.Stop;
|
|
end;
|
|
{$ENDIF VisualCLX}
|
|
end;
|
|
|
|
|
|
{$IFDEF VisualCLX}
|
|
initialization
|
|
|
|
finalization
|
|
FreeAndNil(SysColorPalette);
|
|
{$ENDIF VisualCLX}
|
|
|
|
end.
|