1
0
Files
applications
bindings
components
acs
beepfp
chelper
cmdline
colorpalette
csvdocument
epiktimer
fpspreadsheet
freetypepascal
geckoport
gradcontrols
iphonelazext
jvcllaz
kcontrols
lazbarcodes
manualdock
mplayer
multithreadprocs
nvidia-widgets
onguard
orpheus
tests
ORBLUEDOT.bmp
ORBTNCAL.bmp
ORBTNCLC.bmp
ORCOLUMNMOVECURSOR.cur
ORLEFTARROW.bmp
ORLEFTARROWS.bmp
ORREDDOT.bmp
ORREVERT.bmp
ORRIGHTARROW.bmp
ORRIGHTARROWS.bmp
ORROWMOVECURSOR.cur
ORTCCHECKGLYPHS.bmp
ORTCCOMBOARROW.bmp
ORTODAY.bmp
OrphStatus.html
README.txt
TO32FLEXEDIT.bmp
TO32TCFLEXEDIT.bmp
TOVCCALENDAR.bmp
TOVCCONTROLLER.bmp
TOVCDATEEDIT.bmp
TOVCLABEL.bmp
TOVCROTATEDLABEL.bmp
TOVCSIMPLEFIELD.bmp
TOVCSPINNER.bmp
TOVCTABLE.bmp
TOVCTCBITMAP.bmp
TOVCTCCHECKBOX.bmp
TOVCTCCOLHEAD.bmp
TOVCTCCOMBOBOX.bmp
TOVCTCGLYPH.bmp
TOVCTCICON.bmp
TOVCTCMEMO.bmp
TOVCTCROWHEAD.bmp
TOVCTCSIMPLEFIELD.bmp
TOVCTCSTRING.bmp
TOVCURL.bmp
TOVCVIRTUALLISTBOX.bmp
alltests-carbon.sh
alltests-gtk.sh
alltests-win.bat
makebaseres.bat
makeregres.bat
mymin.pas
mymisc.pas
myovcreg.pas
myovctbpe1.lfm
myovctbpe1.lrs
myovctbpe1.pas
myovctbpe2.lfm
myovctbpe2.lrs
myovctbpe2.pas
o32bordr.pas
o32editf.pas
o32flxed.pas
o32intdeq.pas
o32intlst.pas
o32ovldr.pas
o32pvldr.pas
o32rxngn.pas
o32rxvld.pas
o32sr.inc
o32sr.pas
o32tcflx.pas
o32vldtr.pas
o32vlop1.pas
o32vlreg.pas
o32vpool.pas
orpheus.lpk
orpheus.pas
ovc.inc
ovcabot0.lfm
ovcabot0.lrs
ovcabot0.pas
ovcbase.lrs
ovcbase.pas
ovcbase.res
ovcbcalc.pas
ovcbordr.pas
ovccal.pas
ovccalc.pas
ovccaret.pas
ovcclrcb.pas
ovccmbx.pas
ovccmd.pas
ovccolor.pas
ovcconst.pas
ovcdata.pas
ovcdate.pas
ovcdrag.pas
ovcedcal.pas
ovcedclc.pas
ovceditf.pas
ovcedpop.pas
ovcedtim.pas
ovcef.pas
ovcexcpt.pas
ovcintl.pas
ovclabel.pas
ovclbl0.lfm
ovclbl0.lrs
ovclbl0.pas
ovclbl1.lfm
ovclbl1.lrs
ovclbl1.pas
ovclbl2.pas
ovcmisc.pas
ovcnf.pas
ovcpb.pas
ovcreg.lrs
ovcrlbl.pas
ovcsc.pas
ovcsf.pas
ovcspary.pas
ovcstr.pas
ovctable.pas
ovctbclr.pas
ovctbcls.pas
ovctbpe1.pas
ovctbpe2.pas
ovctbrws.pas
ovctcary.pas
ovctcbef.pas
ovctcbmp.pas
ovctcbox.pas
ovctccbx.pas
ovctcedt.pas
ovctcell.pas
ovctcgly.pas
ovctchdr.pas
ovctcico.pas
ovctcmmn.pas
ovctcsim.pas
ovctcstr.pas
ovctgpns.pas
ovctgres.pas
ovctsell.pas
ovcurl.pas
ovcuser.pas
ovcver.pas
ovcvlb.pas
powerpdf
rgbgraphics
richmemo
richview
rtfview
rx
smnetgradient
spktoolbar
svn
thtmlport
tparadoxdataset
tvplanit
virtualtreeview
virtualtreeview-new
xdev_toolkit
examples
lclbindings
wst
lazarus-ccr/components/orpheus/ovcmisc.pas

1116 lines
33 KiB
ObjectPascal
Raw Normal View History

{*********************************************************}
{* OVCMISC.PAS 4.06 *}
{*********************************************************}
{* ***** BEGIN LICENSE BLOCK ***** *}
{* Version: MPL 1.1 *}
{* *}
{* 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/ *}
{* *}
{* Software distributed under the License is distributed on an "AS IS" basis, *}
{* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License *}
{* for the specific language governing rights and limitations under the *}
{* License. *}
{* *}
{* The Original Code is TurboPower Orpheus *}
{* *}
{* The Initial Developer of the Original Code is TurboPower Software *}
{* *}
{* Portions created by TurboPower Software Inc. are Copyright (C) 1995-2002 *}
{* TurboPower Software Inc. All Rights Reserved. *}
{* *}
{* Contributor(s): *}
{* *}
{* ***** END LICENSE BLOCK ***** *}
(*Changes)
10/20/01- Hdc changed to TOvcHdc for BCB Compatibility
10/20/01- HWnd changed to TOvcHWnd for BCB Compatibility
*)
{$I OVC.INC}
{$B-} {Complete Boolean Evaluation}
{$I+} {Input/Output-Checking}
{$P+} {Open Parameters}
{$T-} {Typed @ Operator}
{.W-} {Windows Stack Frame}
{$X+} {Extended Syntax}
unit ovcmisc;
{-Miscellaneous functions and procedures}
interface
uses
{$IFNDEF LCL} Windows, Messages, {$ELSE} LclIntf, LMessages, LclType, MyMisc, {$ENDIF}
Buttons, Classes, Controls, ExtCtrls, Forms, Graphics,
SysUtils, {$IFNDEF LCL} Consts, {$ELSE} LclStrConsts, {$ENDIF} OvcData;
{ Hdc needs to be an Integer for BCB compatibility }
{$IFDEF CBuilder}
type
TOvcHdc = Integer;
TOvcHWND = Cardinal;
{$ELSE}
type
TOvcHdc = HDC;
TOvcHWND = HWND;
{$ENDIF}
{$IFNDEF LCL}
function LoadBaseBitmap(lpBitmapName : PAnsiChar) : HBITMAP;
{-load and return the handle to bitmap resource}
function LoadBaseCursor(lpCursorName : PAnsiChar) : HCURSOR;
{-load and return the handle to cursor resource}
{$ENDIF}
function CompStruct(const S1, S2; Size : Cardinal) : Integer;
{-compare two fixed size structures}
function DefaultEpoch : Integer;
{-return the current century}
function DrawButtonFrame(Canvas : TCanvas; const Client : TRect;
IsDown, IsFlat : Boolean; Style : TButtonStyle) : TRect;
{-produce a button similar to DrawFrameControl}
procedure FixRealPrim(P : PAnsiChar; DC : AnsiChar);
{-get a PChar string representing a real ready for Val()}
function GetDisplayString(Canvas : TCanvas; const S : string;
MinChars, MaxWidth : Integer) : string;
{-given a string, a minimum number of chars to display, and a max width,
find the string that can be displayed in that width - add ellipsis to
the end if necessary and possible}
function GetLeftButton: Byte;
{-return the mapped left button}
{ - HWnd changed to TOvcHWnd for BCB Compatibility }
function GetNextDlgItem(Ctrl : TOvcHWnd{hWnd}) : hWnd;
{-get handle of next control in the same form}
procedure GetRGB(Clr : TColor; var IR, IG, IB : Byte);
{-return component parts of the rgb value}
function GetShiftFlags : Byte;
{-get current shift flags, the high order bit is set if the key is down}
function CreateRotatedFont(F : TFont; Angle : Integer) : hFont;
{-create a rotated font based on the font object F}
function GetTopTextMargin(Font : TFont; BorderStyle : TBorderStyle;
Height : Integer; Ctl3D : Boolean) : Integer;
{-return the pixel top margin size}
function ExtractWord(N : Integer; const S : string; WordDelims : TCharSet) : string;
{-return the Nth word from S}
function IsForegroundTask : Boolean;
{-returns true if this task is currently in the foreground}
function TrimLeft(const S : string) : string;
{-return a string with leading white space removed}
function TrimRight(const S : string) : string;
{-return a string with trailing white space removed}
function QuotedStr(const S : string) : string;
{-return a quoted string string with internal quotes escaped}
function WordCount(const S : string; const WordDelims : TCharSet) : Integer;
{-return the word count given a set of word delimiters}
function WordPosition(const N : Integer; const S : string; const WordDelims : TCharSet) : Integer;
{-return start position of N'th word in S}
function PtrDiff(const P1, P2) : Word;
{-return the difference between P1 and P2}
procedure PtrInc(var P; Delta : Word);
{-increase P by Delta}
procedure PtrDec(var P; Delta : Word);
{-decrease P by Delta}
procedure FixTextBuffer(InBuf, OutBuf : PChar; OutSize : Integer);
{-replace orphan linefeeds with cr/lf pairs}
{ - Hdc changed to TOvcHdc for BCB Compatibility }
procedure TransStretchBlt(DstDC: TOvcHdc{HDC}; DstX, DstY, DstW, DstH: Integer;
SrcDC: TOvcHdc{HDC}; SrcX, SrcY, SrcW, SrcH: Integer;
MaskDC: TOvcHdc{HDC};
MaskX, MaskY : Integer);
function MaxL(A, B : LongInt) : LongInt;
function MinL(A, B : LongInt) : LongInt;
function MinI(X, Y : Integer) : Integer;
{-return the minimum of two integers}
function MaxI(X, Y : Integer) : Integer;
{-return the maximum of two integers}
{function GenerateComponentName(PF : TCustomForm; const Root : string) : string;}
function GenerateComponentName(PF : TWinControl; const Root : string) : string;
{-return a component name unique for this form}
function PartialCompare(const S1, S2 : string) : Boolean;
{-compare minimum length of S1 and S2 strings}
function PathEllipsis(const S : string; MaxWidth : Integer) : string;
function CreateDisabledBitmap(FOriginal : TBitmap; OutlineColor : TColor) : TBitmap;
procedure CopyParentImage(Control : TControl; Dest : TCanvas);
procedure DrawTransparentBitmap(Dest : TCanvas; X, Y, W, H : Integer;
Rect : TRect; Bitmap : TBitmap; TransparentColor : TColor);
function WidthOf(const R : TRect) : Integer;
{returnd R.Right - R.Left}
function HeightOf(const R : TRect) : Integer;
{returnd R.Bottom - R.Top}
procedure DebugOutput(const S : string);
{use OutputDebugString()}
implementation
uses
OvcBase, OvcStr;
{$IFNDEF LCL}
function LoadBaseBitmap(lpBitmapName : PAnsiChar) : HBITMAP;
begin
Result := LoadBitmap(FindClassHInstance(TOvcCustomControlEx), lpBitmapName);
end;
function LoadBaseCursor(lpCursorName : PAnsiChar) : HCURSOR;
begin
Result := LoadCursor(FindClassHInstance(TOvcCustomControlEx), lpCursorName);
end;
{$ENDIF}
{$IFDEF NoAsm}
function CompStruct(const S1, S2; Size : Cardinal) : Integer;
// Since CompStruct currently only used elsewhere to determine if
// two structures are different, just use CompareMem and don't
// worry about whether "greater than" or "less than".
begin
if CompareMem(@S1, @S2, Size) then {Structures identical?}
Result := 0
else {Structures not identical, so just return as though S1 > S2}
Result := 1;
end;
{$ELSE}
function CompStruct(const S1, S2; Size : Cardinal) : Integer; register;
{-compare two fixed size structures}
asm
push esi
push edi
mov esi, eax {pointer to S1}
mov edi, edx {pointer to S2}
xor eax, eax {eax holds temporary result (Equal)}
or ecx, ecx {size is already in ecx}
jz @@CSDone {make sure size isn't zero}
cld {go forward}
repe cmpsb {compare until no match or ecx = 0}
je @@CSDone {if equal, result is already in eax}
inc eax {prepare for greater}
ja @@CSDone {S1 greater? return +1}
mov eax, -1 {else S1 less, return -1}
@@CSDone:
pop edi
pop esi
end;
{$ENDIF}
procedure FixRealPrim(P : PAnsiChar; DC : AnsiChar);
{-Get a string representing a real ready for Val()}
var
DotPos : Cardinal;
EPos : Cardinal;
Len : Word;
Found : Boolean;
EFound : Boolean;
begin
TrimAllSpacesPChar(P);
Len := StrLen(P);
if Len > 0 then begin
if P[Len-1] = DC then begin
Dec(Len);
P[Len] := #0;
TrimAllSpacesPChar(P);
end;
{Val doesn't accept alternate decimal point chars}
Found := StrChPos(P, DC, DotPos);
{replace with '.'}
if Found and (DotPos > 0) then
P[DotPos] := '.'
else
Found := StrChPos(P, pmDecimalPt, DotPos);
if Found then begin
{check for 'nnnn.'}
if LongInt(DotPos) = Len-1 then begin
P[Len] := '0';
Inc(Len);
P[Len] := #0;
end;
{check for '.nnnn'}
if DotPos = 0 then begin
StrChInsertPrim(P, '0', 0);
Inc(Len);
Inc(DotPos);
end;
{check for '-.nnnn'}
if (Len > 1) and (P^ = '-') and (DotPos = 1) then begin
StrChInsertPrim(P, '0', 1);
Inc(DotPos);
end;
end;
{fix up numbers with exponents}
EFound := StrChPos(P, 'E', EPos);
if EFound and (EPos > 0) then begin
if not Found then begin
StrChInsertPrim(P, '.', EPos);
DotPos := EPos;
Inc(EPos);
end;
if EPos-DotPos < 12 then
StrStInsertPrim(P, '00000', EPos);
end;
{remove blanks before and after '.' }
if Found then begin
while (DotPos > 0) and (P[DotPos-1] = ' ') do begin
StrStDeletePrim(P, DotPos-1, 1);
Dec(DotPos);
end;
while P[DotPos+1] = ' ' do
StrStDeletePrim(P, DotPos+1, 1);
end;
end else begin
{empty string = '0'}
P[0] := '0';
P[1] := #0;
end;
end;
function GetLeftButton: Byte;
const
RLButton : array[Boolean] of Word = (VK_LBUTTON, VK_RBUTTON);
begin
Result := RLButton[GetSystemMetrics(SM_SWAPBUTTON) <> 0];
end;
{ - HWnd changed to TOvcHWnd for BCB Compatibility }
function GetNextDlgItem(Ctrl : TOvcHWnd{hWnd}) : hWnd;
{-Get handle of next control in the same form}
begin
{asking for previous returns next}
Result := GetNextWindow(Ctrl, GW_HWNDPREV);
if Result = 0 then begin
{asking for last returns first}
Result := GetWindow(Ctrl, GW_HWNDLAST);
if Result = 0 then
Result := Ctrl;
end;
end;
procedure GetRGB(Clr : TColor; var IR, IG, IB : Byte);
begin
if (Clr < 0) then begin
Clr := Clr + MaxLongInt + 1;
Clr := GetSysColor(Clr);
end;
IR := GetRValue(Clr);
IG := GetGValue(Clr);
IB := GetBValue(Clr);
end;
function GetShiftFlags : Byte;
{-get current shift flags, the high order bit is set if the key is down}
begin
Result := (Ord(GetKeyState(VK_CONTROL) < 0) * ss_Ctrl) +
(Ord(GetKeyState(VK_SHIFT ) < 0) * ss_Shift) +
(Ord(GetKeyState(VK_ALT ) < 0) * ss_Alt);
end;
function CreateRotatedFont(F : TFont; Angle : Integer) : hFont;
{-create a rotated font based on the font object F}
var
LF : TLogFont;
begin
FillChar(LF, SizeOf(LF), #0);
with LF do begin
lfHeight := F.Height;
lfWidth := 0;
lfEscapement := Angle*10;
lfOrientation := 0;
if fsBold in F.Style then
lfWeight := FW_BOLD
else
lfWeight := FW_NORMAL;
lfItalic := Byte(fsItalic in F.Style);
lfUnderline := Byte(fsUnderline in F.Style);
lfStrikeOut := Byte(fsStrikeOut in F.Style);
lfCharSet := DEFAULT_CHARSET;
StrPCopy(lfFaceName, F.Name);
lfQuality := DEFAULT_QUALITY;
{everything else as default}
lfOutPrecision := OUT_DEFAULT_PRECIS;
lfClipPrecision := CLIP_DEFAULT_PRECIS;
case F.Pitch of
fpVariable : lfPitchAndFamily := VARIABLE_PITCH;
fpFixed : lfPitchAndFamily := FIXED_PITCH;
else
lfPitchAndFamily := DEFAULT_PITCH;
end;
end;
Result := CreateFontIndirect(LF);
end;
function GetTopTextMargin(Font : TFont; BorderStyle : TBorderStyle;
Height : Integer; Ctl3D : Boolean) : Integer;
{-return the pixel top margin size}
var
I : Integer;
DC : hDC;
Metrics : TTextMetric;
SaveFont : hFont;
SysMetrics : TTextMetric;
begin
DC := GetDC(0);
try
GetTextMetrics(DC, SysMetrics);
SaveFont := SelectObject(DC, Font.Handle);
GetTextMetrics(DC, Metrics);
SelectObject(DC, SaveFont);
finally
ReleaseDC(0, DC);
end;
I := SysMetrics.tmHeight;
if I > Metrics.tmHeight then
I := Metrics.tmHeight;
if NewStyleControls then begin
if BorderStyle = bsNone then begin
Result := 0;
if I >= Height-2 then
Result := (Height-I-2) div 2 - Ord(Odd(Height-I));
end else if Ctl3D then begin
Result := 1;
if I >= Height-4 then
Result := (Height-I-4) div 2 - 1;
end else begin
Result := 1;
if I >= Height-4 then
Result := (Height-I-4) div 2 - Ord(Odd(Height-I));
end;
end else begin
Result := (Height-Metrics.tmHeight-1) div 2;
if I > Height-2 then begin
Dec(Result, 2);
if BorderStyle = bsNone then
Inc(Result, 1);
end;
end;
end;
function PtrDiff(const P1, P2) : Word;
{-return the difference between P1 and P2}
begin
{P1 and P2 are assumed to point within the same buffer}
Result := PAnsiChar(P1) - PAnsiChar(P2);
end;
procedure PtrInc(var P; Delta : Word);
{-increase P by Delta}
begin
Inc(PAnsiChar(P), Delta);
end;
procedure PtrDec(var P; Delta : Word);
{-increase P by Delta}
begin
Dec(PAnsiChar(P), Delta);
end;
{$IFDEF NoAsm}
function MinI(X, Y : Integer) : Integer;
begin
if X < Y then
Result := X
else
Result := Y;
end;
function MaxI(X, Y : Integer) : Integer;
begin
if X >= Y then
Result := X
else
Result := Y;
end;
{$ELSE}
function MinI(X, Y : Integer) : Integer;
asm
cmp eax, edx
jle @@Exit
mov eax, edx
@@Exit:
end;
function MaxI(X, Y : Integer) : Integer;
asm
cmp eax, edx
jge @@Exit
mov eax, edx
@@Exit:
end;
{$ENDIF}
function MaxL(A, B : LongInt) : LongInt;
begin
if (A < B) then
Result := B
else
Result := A;
end;
function MinL(A, B : LongInt) : LongInt;
begin
if (A < B) then
Result := A
else
Result := B;
end;
function TrimLeft(const S : string) : string;
var
I, L : Integer;
begin
L := Length(S);
I := 1;
while (I <= L) and (S[I] <= ' ') do
Inc(I);
Result := Copy(S, I, Length(S)-I+1);
end;
function TrimRight(const S : string) : string;
var
I : Integer;
begin
I := Length(S);
while (I > 0) and (S[I] <= ' ') do
Dec(I);
Result := Copy(S, 1, I);
end;
function QuotedStr(const S: string): string;
var
I : Integer;
begin
Result := S;
for I := Length(Result) downto 1 do
if Result[I] = '''' then Insert('''', Result, I);
Result := '''' + Result + '''';
end;
function WordCount(const S : string; const WordDelims : TCharSet) : Integer;
var
SLen, I : Integer;
begin
Result := 0;
I := 1;
SLen := Length(S);
while I <= SLen do begin
while (I <= SLen) and (S[I] in WordDelims) do
Inc(I);
if I <= SLen then
Inc(Result);
while (I <= SLen) and not(S[I] in WordDelims) do
Inc(I);
end;
end;
function ExtractWord(N : Integer; const S : string; WordDelims : TCharSet) : string;
var
I : Word;
Len : Integer;
begin
Len := 0;
I := WordPosition(N, S, WordDelims);
if I <> 0 then
{ find the end of the current word }
while (I <= Length(S)) and not(S[I] in WordDelims) do begin
{ add the I'th character to result }
Inc(Len);
SetLength(Result, Len);
Result[Len] := S[I];
Inc(I);
end;
SetLength(Result, Len);
end;
function WordPosition(const N : Integer; const S : string; const WordDelims : TCharSet) : Integer;
var
Count, I : Integer;
begin
Count := 0;
I := 1;
Result := 0;
while (I <= Length(S)) and (Count <> N) do begin
{skip over delimiters}
while (I <= Length(S)) and (S[I] in WordDelims) do
Inc(I);
{if we're not beyond end of S, we're at the start of a word}
if I <= Length(S) then
Inc(Count);
{if not finished, find the end of the current word}
if Count <> N then
while (I <= Length(S)) and not (S[I] in WordDelims) do
Inc(I)
else
Result := I;
end;
end;
function DrawButtonFrame(Canvas : TCanvas; const Client : TRect;
IsDown, IsFlat : Boolean; Style : TButtonStyle) : TRect;
var
NewStyle : Boolean;
begin
Result := Client;
NewStyle := (Style = bsNew) or (NewStyleControls and (Style = bsAutoDetect));
if IsDown then begin
if NewStyle then begin
Frame3D(Canvas, Result, clWindowFrame, clBtnHighlight, 1);
if not IsFlat then
Frame3D(Canvas, Result, clBtnShadow, clBtnFace, 1);
end else begin
if IsFlat then
Frame3D(Canvas, Result, clWindowFrame, clBtnHighlight, 1)
else begin
Frame3D(Canvas, Result, clWindowFrame, clWindowFrame, 1);
Canvas.Pen.Color := clBtnShadow;
Canvas.PolyLine([Point(Result.Left, Result.Bottom - 1),
Point(Result.Left, Result.Top), Point(Result.Right, Result.Top)]);
end;
end;
end else begin
if NewStyle then begin
if IsFlat then
Frame3D(Canvas, Result, clBtnHighlight, clBtnShadow, 1)
else begin
Frame3D(Canvas, Result, clBtnHighlight, clWindowFrame, 1);
Frame3D(Canvas, Result, clBtnFace, clBtnShadow, 1);
end;
end else begin
if IsFlat then
Frame3D(Canvas, Result, clBtnHighlight, clWindowFrame, 1)
else begin
Frame3D(Canvas, Result, clWindowFrame, clWindowFrame, 1);
Frame3D(Canvas, Result, clBtnHighlight, clBtnShadow, 1);
end;
end;
end;
InflateRect(Result, -1, -1);
end;
function GetDisplayString(Canvas : TCanvas; const S : string;
MinChars, MaxWidth : Integer) : string;
var
iDots, EllipsisWidth, Extent, Len, Width : Integer;
ShowEllipsis : Boolean;
begin
{be sure that the Canvas Font is set before entering this routine}
EllipsisWidth := Canvas.TextWidth('...');
Len := Length(S);
Result := S;
Extent := Canvas.TextWidth(Result);
ShowEllipsis := False;
Width := MaxWidth;
while (Extent > Width) do begin
ShowEllipsis := True;
Width := MaxWidth - EllipsisWidth;
if Len > MinChars then begin
Delete(Result, Len, 1);
dec(Len);
end else
break;
Extent := Canvas.TextWidth(Result);
end;
if ShowEllipsis then begin
Result := Result + '...';
inc(Len, 3);
Extent := Canvas.TextWidth(Result);
iDots := 3;
while (iDots > 0) and (Extent > MaxWidth) do begin
Delete(Result, Len, 1);
Dec(Len);
Extent := Canvas.TextWidth(Result);
Dec(iDots);
end;
end;
end;
type
PCheckTaskInfo = ^TCheckTaskInfo;
TCheckTaskInfo = packed record
FocusWnd: HWnd;
Found: Boolean;
end;
{ - HWnd changed to TOvcHWnd for BCB Compatibility }
function CheckTaskWindow(Window: TOvcHWnd{HWnd};
Data: Longint): WordBool; stdcall;
begin
Result := True;
if PCheckTaskInfo(Data)^.FocusWnd = Window then begin
Result := False;
PCheckTaskInfo(Data)^.Found := True;
end;
end;
function IsForegroundTask : Boolean;
var
Info : TCheckTaskInfo;
begin
Info.FocusWnd := GetActiveWindow;
Info.Found := False;
{$IFNDEF DARWIN}
EnumThreadWindows(GetCurrentThreadID, @CheckTaskWindow, Longint(@Info));
{$ELSE}
EnumThreadWindows(LongWord(GetCurrentThreadID), @CheckTaskWindow, Longint(@Info));
{$ENDIF}
Result := Info.Found;
end;
procedure FixTextBuffer(InBuf, OutBuf : PChar; OutSize : Integer);
var
I, P : Integer;
begin
P := 0;
for I := 0 to StrLen(InBuf) do begin
if (InBuf[I] = #10) and ((I = 0) or (InBuf[I-1] <> #13)) then begin
OutBuf[P] := #13;
Inc(P);
end;
OutBuf[P] := InBuf[I];
{is outbuf full?}
if P = OutSize-1 then begin
{if so, terminate and exit}
OutBuf[OutSize] := #0;
Break;
end;
Inc(P);
end;
end;
{ - Hdc changed to TOvcHdc for BCB Compatibility }
procedure TransStretchBlt(DstDC: TOvcHdc{HDC}; DstX, DstY, DstW, DstH: Integer;
SrcDC: TOvcHdc{HDC}; SrcX, SrcY, SrcW, SrcH: Integer;
MaskDC: TOvcHdc{HDC};
MaskX, MaskY : Integer);
var
MemDC : HDC;
MemBmp : HBITMAP;
Save : THandle;
crText, crBack : TColorRef;
SystemPalette16, SavePal : HPALETTE;
begin
SavePal := 0;
MemDC := CreateCompatibleDC(0);
try
MemBmp := CreateCompatibleBitmap(SrcDC, SrcW, SrcH);
Save := SelectObject(MemDC, MemBmp);
SystemPalette16 := GetStockObject(DEFAULT_PALETTE);
SavePal := SelectPalette(SrcDC, SystemPalette16, False);
SelectPalette(SrcDC, SavePal, False);
if SavePal <> 0 then
SavePal := SelectPalette(MemDC, SavePal, True)
else
SavePal := SelectPalette(MemDC, SystemPalette16, True);
RealizePalette(MemDC);
StretchBlt(MemDC, 0, 0, SrcW, SrcH, MaskDC, MaskX, MaskY,
SrcW, SrcH, SrcCopy);
StretchBlt(MemDC, 0, 0, SrcW, SrcH, SrcDC, SrcX, SrcY, SrcW, SrcH,
SrcErase);
crText := SetTextColor(DstDC, $0);
crBack := SetBkColor(DstDC, $FFFFFF);
StretchBlt(DstDC, DstX, DstY, DstW, DstH, MaskDC, MaskX, MaskY,
SrcW, SrcH, SrcAnd);
StretchBlt(DstDC, DstX, DstY, DstW, DstH, MemDC, 0, 0,
SrcW, SrcH, SrcInvert);
SetTextColor(DstDC, crText);
SetBkColor(DstDC, crBack);
if Save <> 0 then
SelectObject(MemDC, Save);
DeleteObject(MemBmp);
finally
if SavePal <> 0 then
SelectPalette(MemDC, SavePal, False);
DeleteDC(MemDC);
end;
end;
function DefaultEpoch : Integer;
var
ThisYear : Word;
ThisMonth : Word;
ThisDay : Word;
begin
DecodeDate(SysUtils.Date, ThisYear, ThisMonth, ThisDay);
Result := (ThisYear div 100) * 100;
end;
{function GenerateComponentName(PF : TCustomForm; const Root : string) : string;}
function GenerateComponentName(PF : TWinControl; const Root : string) : string;
var
I : Integer;
begin
if not IsValidIdent(Root) then
raise EComponentError.CreateFmt('''''%s'''' is not a valid component name',
[Root]);
I := 0;
repeat
Inc(I);
Result := Root + IntToStr(I);
until (PF.FindComponent(Result) = nil);
end;
function PartialCompare(const S1, S2 : string) : Boolean;
var
L : Integer;
begin
{and empty string matches nothing}
Result := False;
L := MinI(Length(S1), Length(S2));
if L > 0 then
Result := AnsiUpperCase(Copy(S1, 1, L)) = AnsiUpperCase(Copy(S2, 1, L));
end;
function PathEllipsis(const S : string; MaxWidth : Integer) : string;
{ PathEllipsis function. Trims a path down to the }
{ specified number of pixels. For example, }
{ 'd:\program files\my stuff\some long document.txt' }
{ becomes 'd:\...\some long...' or a variation thereof }
{ depending on the value of MaxWidth. }
var
R : TRect;
BM : TBitmap;
NCM : TNonClientMetrics;
begin
if MaxWidth = 0 then begin
Result := S;
Exit;
end;
NCM.cbSize := SizeOf(NCM);
SystemParametersInfo(
SPI_GETNONCLIENTMETRICS, NCM.cbSize, @NCM, 0);
BM := TBitmap.Create;
try
BM.Canvas.Font.Handle := CreateFontIndirect(NCM.lfMenuFont);
if BM.Canvas.TextWidth(S) < MaxWidth then begin
Result := S;
Exit;
end;
Result := ExtractFilePath(S);
Delete(Result, Length(Result), 1);
while BM.Canvas.TextWidth(Result + '\...\' + ExtractFileName(S)) > MaxWidth do begin
{ Start trimming the path, working backwards }
Result := ExtractFilePath(Result);
Delete(Result, Length(Result), 1);
{ Only drive letter left so break out of loop. }
if Length(Result) = 2 then
Break;
end;
{ Add the filename back onto the modified path. }
Result := Result + '\...\' + ExtractFileName(S);
{ Still too long? }
if BM.Canvas.TextWidth(Result) > MaxWidth then begin
R := Rect(0, 0, MaxWidth, 0);
DrawText(BM.Canvas.Handle, PChar(Result), -1,
R, DT_SINGLELINE or DT_END_ELLIPSIS or DT_MODIFYSTRING or DT_CALCRECT);
end;
finally
BM.Free;
end;
end;
function CreateDisabledBitmap(FOriginal : TBitmap; OutlineColor : TColor) : TBitmap;
{-create TBitmap object with disabled glyph}
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
Assign(FOriginal);
HandleType := bmDDB;
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 := clBtnFace;
FillRect(IRect);
Brush.Color := clBtnHighlight;
SetTextColor(Handle, clBlack);
SetBkColor(Handle, clWhite);
BitBlt(Handle, 1, 1, WidthOf(IRect), HeightOf(IRect),
MonoBmp.Canvas.Handle, 0, 0, ROP_DSPDxax);
Brush.Color := clBtnShadow;
SetTextColor(Handle, clBlack);
SetBkColor(Handle, clWhite);
BitBlt(Handle, 0, 0, WidthOf(IRect), HeightOf(IRect),
MonoBmp.Canvas.Handle, 0, 0, ROP_DSPDxax);
end;
finally
MonoBmp.Free;
end;
except
Result.Free;
raise;
end;
end;
type
TParentControl = class(TWinControl);
procedure CopyParentImage(Control : TControl; Dest : TCanvas);
var
I : Integer;
Count : Integer;
X, Y : Integer;
OldDC : Integer;
DC : hDC;
R : TRect;
SelfR : TRect;
CtlR : TRect;
begin
if Control.Parent = nil then
Exit;
Count := Control.Parent.ControlCount;
DC := Dest.Handle;
SelfR := Bounds(Control.Left, Control.Top, Control.Width, Control.Height);
X := -Control.Left; Y := -Control.Top;
{copy parent control image}
OldDC := SaveDC(DC);
SetViewportOrgEx(DC, X, Y, nil);
IntersectClipRect(DC, 0, 0, Control.Parent.ClientWidth, Control.Parent.ClientHeight);
TParentControl(Control.Parent).PaintWindow(DC);
RestoreDC(DC, OldDC);
{copy images of graphic controls}
for I := 0 to Count - 1 do begin
if (Control.Parent.Controls[I] <> nil) and
not (Control.Parent.Controls[I] is TWinControl) then begin
if Control.Parent.Controls[I] = Control then
Break;
with Control.Parent.Controls[I] do begin
CtlR := Bounds(Left, Top, Width, Height);
if Bool(IntersectRect(R, SelfR, CtlR)) and Visible then begin
OldDC := SaveDC(DC);
SetViewportOrgEx(DC, Left + X, Top + Y, nil);
IntersectClipRect(DC, 0, 0, Width, Height);
Perform(WM_PAINT, DC, 0);
RestoreDC(DC, OldDC);
end;
end;
end;
end;
end;
{ - Hdc changed to TOvcHdc for BCB Compatibility }
procedure DrawTransparentBitmapPrim(DC : TOvcHdc{HDC}; Bitmap : HBitmap;
xStart, yStart, Width, Height : Integer; Rect : TRect;
TransparentColor : TColorRef);
{-draw transparent bitmap}
var
{$IFNDEF LCL}
BM : Windows.TBitmap;
{$ELSE}
BM : LclType.tagBITMAP;
{$ENDIF}
cColor : TColorRef;
bmAndBack : hBitmap;
bmAndObject : hBitmap;
bmAndMem : hBitmap;
bmSave : hBitmap;
bmBackOld : hBitmap;
bmObjectOld : hBitmap;
bmMemOld : hBitmap;
bmSaveOld : hBitmap;
hdcMem : hDC;
hdcBack : hDC;
hdcObject : hDC;
hdcTemp : hDC;
hdcSave : hDC;
ptSize : TPoint;
ptRealSize : TPoint;
ptBitSize : TPoint;
ptOrigin : TPoint;
begin
hdcTemp := CreateCompatibleDC(DC);
SelectObject(hdcTemp, Bitmap);
GetObject(Bitmap, SizeOf(BM), @BM);
ptRealSize.x := MinL(Rect.Right - Rect.Left, BM.bmWidth - Rect.Left);
ptRealSize.y := MinL(Rect.Bottom - Rect.Top, BM.bmHeight - Rect.Top);
DPtoLP(hdcTemp, ptRealSize, 1);
ptOrigin.x := Rect.Left;
ptOrigin.y := Rect.Top;
{convert from device to logical points}
DPtoLP(hdcTemp, ptOrigin, 1);
{get width of bitmap}
ptBitSize.x := BM.bmWidth;
{get height of bitmap}
ptBitSize.y := BM.bmHeight;
DPtoLP(hdcTemp, ptBitSize, 1);
if (ptRealSize.x = 0) or (ptRealSize.y = 0) then begin
ptSize := ptBitSize;
ptRealSize := ptSize;
end else
ptSize := ptRealSize;
if (Width = 0) or (Height = 0) then begin
Width := ptSize.x;
Height := ptSize.y;
end;
{create DCs to hold temporary data}
hdcBack := CreateCompatibleDC(DC);
hdcObject := CreateCompatibleDC(DC);
hdcMem := CreateCompatibleDC(DC);
hdcSave := CreateCompatibleDC(DC);
{create a bitmap for each DC}
{monochrome DC}
bmAndBack := CreateBitmap(ptSize.x, ptSize.y, 1, 1, nil);
bmAndObject := CreateBitmap(ptSize.x, ptSize.y, 1, 1, nil);
bmAndMem := CreateCompatibleBitmap(DC, MaxL(ptSize.x, Width), MaxL(ptSize.y, Height));
bmSave := CreateCompatibleBitmap(DC, ptBitSize.x, ptBitSize.y);
{select a bitmap object to store pixel data}
bmBackOld := SelectObject(hdcBack, bmAndBack);
bmObjectOld := SelectObject(hdcObject, bmAndObject);
bmMemOld := SelectObject(hdcMem, bmAndMem);
bmSaveOld := SelectObject(hdcSave, bmSave);
SetMapMode(hdcTemp, GetMapMode(DC));
{save the bitmap sent here, it will be overwritten}
BitBlt(hdcSave, 0, 0, ptBitSize.x, ptBitSize.y, hdcTemp, 0, 0, SRCCOPY);
{set the background color of the source DC to the color,}
{contained in the parts of the bitmap that should be transparent}
cColor := SetBkColor(hdcTemp, TransparentColor);
{create the object mask for the bitmap by performing a BitBlt()}
{from the source bitmap to a monochrome bitmap}
BitBlt(hdcObject, 0, 0, ptSize.x, ptSize.y, hdcTemp, ptOrigin.x, ptOrigin.y, SRCCOPY);
{set the background color of the source DC back to the original color}
SetBkColor(hdcTemp, cColor);
{create the inverse of the object mask}
BitBlt(hdcBack, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, NOTSRCCOPY);
{copy the background of the main DC to the destination}
BitBlt(hdcMem, 0, 0, Width, Height, DC, xStart, yStart, SRCCOPY);
{mask out the places where the bitmap will be placed}
StretchBlt(hdcMem, 0, 0, Width, Height, hdcObject, 0, 0, ptSize.x, ptSize.y, SRCAND);
{mask out the transparent colored pixels on the bitmap}
BitBlt(hdcTemp, ptOrigin.x, ptOrigin.y, ptSize.x, ptSize.y, hdcBack, 0, 0, SRCAND);
{XOR the bitmap with the background on the destination DC}
StretchBlt(hdcMem, 0, 0, Width, Height, hdcTemp, ptOrigin.x, ptOrigin.y, ptSize.x, ptSize.y, SRCPAINT);
{copy the destination to the screen}
BitBlt(DC, xStart, yStart, MaxL(ptRealSize.x, Width), MaxL(ptRealSize.y, Height), hdcMem, 0, 0, SRCCOPY);
{place the original bitmap back into the bitmap sent}
BitBlt(hdcTemp, 0, 0, ptBitSize.x, ptBitSize.y, hdcSave, 0, 0, SRCCOPY);
{delete the memory bitmaps}
DeleteObject(SelectObject(hdcBack, bmBackOld));
DeleteObject(SelectObject(hdcObject, bmObjectOld));
DeleteObject(SelectObject(hdcMem, bmMemOld));
DeleteObject(SelectObject(hdcSave, bmSaveOld));
{delete the memory DCs}
DeleteDC(hdcMem);
DeleteDC(hdcBack);
DeleteDC(hdcObject);
DeleteDC(hdcSave);
DeleteDC(hdcTemp);
end;
procedure DrawTransparentBitmap(Dest : TCanvas; X, Y, W, H : Integer;
Rect : TRect; Bitmap : TBitmap; TransparentColor : TColor);
var
MemImage : TBitmap;
R : TRect;
begin
MemImage := TBitmap.Create;
try
R := Bounds(0, 0, Bitmap.Width, Bitmap.Height);
if TransparentColor = clNone then begin
if (WidthOf(Rect) <> 0) and (HeightOf(Rect) <> 0) then
R := Rect;
MemImage.Width := WidthOf(R);
MemImage.Height := HeightOf(R);
MemImage.Canvas.CopyRect(Bounds(0, 0, MemImage.Width, MemImage.Height),
Bitmap.Canvas, R);
if (W = 0) or (H = 0) then
Dest.Draw(X, Y, MemImage)
else
Dest.StretchDraw(Bounds(X, Y, W, H), MemImage);
end else begin
MemImage.Width := WidthOf(R);
MemImage.Height := HeightOf(R);
MemImage.Canvas.CopyRect(R, Bitmap.Canvas, R);
if TransparentColor = clDefault then
TransparentColor := MemImage.Canvas.Pixels[0, MemImage.Height - 1];
DrawTransparentBitmapPrim(Dest.Handle, MemImage.Handle, X, Y, W, H,
Rect, ColorToRGB(TransparentColor and not $02000000));
end;
finally
MemImage.Free;
end;
end;
function WidthOf(const R : TRect) : Integer;
begin
Result := R.Right - R.Left;
end;
function HeightOf(const R : TRect) : Integer;
begin
Result := R.Bottom - R.Top;
end;
procedure DebugOutput(const S : string);
begin
OutputDebugString(PChar(S));
OutputDebugString(#13#10);
end;
end.