{*******************************************************************} { } { Developer Express Visual Component Library } { ExpressPrinting System(tm) COMPONENT SUITE } { } { Copyright (C) 1998-2009 Developer Express Inc. } { ALL RIGHTS RESERVED } { } { The entire contents of this file is protected by U.S. and } { International Copyright Laws. Unauthorized reproduction, } { reverse-engineering, and distribution of all or any portion of } { the code contained in this file is strictly prohibited and may } { result in severe civil and criminal penalties and will be } { prosecuted to the maximum extent possible under the law. } { } { RESTRICTIONS } { } { THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES } { (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE } { SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS } { LICENSED TO DISTRIBUTE THE EXPRESSPRINTINGSYSTEM AND } { ALL ACCOMPANYING VCL CONTROLS AS PART OF AN } { EXECUTABLE PROGRAM ONLY. } { } { THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED } { FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE } { COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE } { AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT } { AND PERMISSION FROM DEVELOPER EXPRESS INC. } { } { CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON } { ADDITIONAL RESTRICTIONS. } { } {*******************************************************************} unit dxPSUtl; interface {$I cxVer.inc} uses {$IFDEF DELPHI6} Variants, {$ENDIF} Classes, Windows, SysUtils, Graphics, Messages, Controls, StdCtrls, ComCtrls, Dialogs, CommCtrl, Forms, Menus, ImgList, TypInfo, Registry, dxCore, cxClasses, cxControls, cxGraphics, dxPSGlbl, dxPrnDev; const // Marlett Font CheckMarkIndex = 98; CheckTopLeftArcOuterIndex = 99; CheckBottomRightArcOuterIndex = 100; CheckTopLeftArcInnerIndex = 101; CheckBottomRightArcInnerIndex = 102; CheckInteriorIndex = 103; RadioBeanIndex = 105; RadioTopLeftArcOuterIndex = 106; RadioBottomRightArcOuterIndex = 107; RadioTopLeftArcInnerIndex = 108; RadioBottomRightArcInnerIndex = 109; RadioInteriorIndex = 110; SortUpMarkIndex = 116; SortDownMarkIndex = 117; // Symbol Font PlusSignIndex = 43; MinusSignIndex = 45; InvalidFileNameChars = '<>:"|/\'; function Min(A, B: Integer): Integer; function Max(A, B: Integer): Integer; function MinMax(A, B, C: Integer): Integer; function SetLoWord(AValue: Integer; ALoWord: Word): Integer; function SetHiWord(AValue: Integer; AHiWord: Word): Integer; function SetLoHiWords(AValue: Integer; ALoWord, AHiWord: Word): Integer; function ScalePoint(const Pt: TPoint; Numerator, Denominator: Integer): TPoint; function ScaleRect(const R: TRect; ANumeratorW, ADenominatorW, ANumeratorH, ADenominatorH: Integer): TRect; overload; function ScaleRect(const R: TRect; ANumerator, ADenominator: Integer): TRect; overload; function ArePointsEqual(const Pt1, Pt2: TPoint): Boolean; // GDI function GetRgnData(ARgn: HRGN; out ARgnDataHeader: TRgnDataHeader; out ARects: TRects): Integer; function ExcludeClipRect(DC: HDC; const R: TRect): HRGN; overload; function ExcludeClipRect(DC: HDC; ALeft, ATop, ARight, ABottom: Integer): HRGN; overload; function IntersectClipRect(DC: HDC; const R: TRect; AlwaysClip: Boolean = False): HRGN; overload; function IntersectClipRect(DC: HDC; ALeft, ATop, ARight, ABottom: Integer; AlwaysClip: Boolean = False): HRGN; overload; function RectVisible(DC: HDC; const ARect: TRect): Boolean; procedure RestoreClipRgn(DC: HDC; var ARgn: HRGN); function dxAreBitmapsEqual(ABitmap1, ABitmap2: TBitmap): Boolean; function dxAreBrushesEqual(ABrush1, ABrush2: TBrush): Boolean; function dxAreGraphicsEqual(AGraphic1, AGraphic2: TGraphic): Boolean; function dxAreFontsEqual(AFont1, AFont2: TFont): Boolean; function dxArePensEqual(APen1, APen2: TPen): Boolean; function dxIsTrueTypeFont(AFont: TFont): Boolean; function FindNearestColor(AColor: TColor): TColor; function InvertColor(AColor: TColor): TColor; function OffsetColor(AColor: TColor; ARed, AGreen, ABlue: Byte): TColor; function IsDisplayDC(DC: HDC): Boolean; function IsMetafileDC(DC: HDC): Boolean; function IsPrinterDC(DC: HDC): Boolean; function PatternBrush: HBRUSH; procedure SetFontAsNonAntialiased(AFont: TFont); procedure ForcePictureToBitmap(APicture: TPicture); function CreateGraphic(AGraphicClass: TGraphicClass): TGraphic; function IconToBitmap(AnIcon: TIcon): TBitmap; function CreateArrowBitmap(AUpDownGlyph: TdxUpDownGlyph; AWidth: Integer = 16; AHeight: Integer = 16; AFontSize: Integer = 12): TBitmap; function CreateDoubleArrowBitmap(AUpDownGlyph: TdxUpDownGlyph; AWidth: Integer = 16; AHeight: Integer = 16; AFontSize: Integer = 8): TBitmap; function CreateGlyphBitmap(AGlyphIndex: Integer; AWidth: Integer = 16; AHeight: Integer = 16; AFontSize: Integer = 12): TBitmap; procedure DrawBlendedText(ACanvas: TCanvas; const R: TRect; const AText: string; AFont: TFont); procedure DrawGlyph(DC: HDC; const R: TRect; AGlyph: Byte); procedure DrawSizeGrip(DC: HDC; R: TRect); procedure TransparentDraw(DrawDC: HDC; Brush: HBRUSH; const R: TRect; ABitmap: TBitmap); // System function CopyDeviceMode(Src: HGLOBAL): HGLOBAL; function GetDesktopWorkArea: TRect; overload; function GetDesktopWorkArea(const P: TPoint): TRect; overload; function GetLongFileName(const Source: string): string; function GetMachineName: string; function GetUserName: string; function GetVolumeName(const APath: string): string; function IsIntelliMousePresent: Boolean; function IsNetworkPresent: Boolean; function IsVolume(const APath: string): Boolean; function IsWin32Version(AMajor: Integer; AMinor: Integer = 0): Boolean; function PopulateShellImages(FullInit: Boolean): Boolean; function ShellLargeImages: TImageList; function ShellSmallImages: TImageList; function ShowSystemSelectFolderDlg(var ADirPath: string): Boolean; function FormatFileSize(const AFileSize: Int64): string; function ValidateFileName(const FileName: string): Boolean; procedure Delay(Value: DWORD); //milliseconds procedure MessageError(const AMessage: string); procedure MessageWarning(const AMessage: string); function MessageQuestion(const AMessage: string): Boolean; // string processing function AddColon(const Source: string): string; function AddEndEllipsis(const Source: string): string; function DropAmpersand(const Source: string): string; function DropColon(const Source: string): string; function DropEndEllipsis(const Source: string): string; function DropT(const Source: string): string; function ReplaceSubStr(const Source, OldChars, NewChars: string): string; function ReplicateChar(const S: string; ACount: Integer): string; function dxBoolToStr(AValue: Boolean): string; function dxSameStr(const S1, S2: string): Boolean; function dxSameText(const S1, S2: string): Boolean; function FormatFontInfo(AFont: TFont): string; procedure FontInfoToText(AFont: TFont; AEdit: TEdit); function MakePageIndexes(const Source: string; out AnOutput: TIntegers): Boolean; // Number metrics conversation function Chars2Int(const AText: string; AnUpperCase: Boolean): Integer; function Int2Chars(AValue: Integer; AnUpperCase: Boolean): string; function Roman2Int(AText: string; AnUpperCase: Boolean): Integer; function Int2Roman(AValue: Integer; AnUpperCase: Boolean): string; //RTTI function HasPropertyEx(AClass: TClass; const AName: string; ATypeKinds: TTypeKinds): Boolean; overload; function HasPropertyEx(AnObject: TObject; const AName: string; ATypeKinds: TTypeKinds): Boolean; overload; function HasProperty(AClass: TClass; const AName: string): Boolean; overload; function HasProperty(AnObject: TObject; const AName: string): Boolean; overload; function GetProperty(AnObject: TObject; const AName: string): Variant; procedure SetProperty(AnObject: TObject; const AName: string; const AValue: Variant); procedure dxDrawComboBoxItem(ACanvas: TCanvas; const R: TRect; const AText: string; AnImageList: TCustomImageList; AnImageIndex: Integer; AState: TOwnerDrawState); procedure dxLoadStringsFromRegistry(const APath: string; AStrings: TStrings); procedure dxSaveStringsToRegistry(const APath: string; AStrings: TStrings); procedure dxLoadListViewColumnsFromRegistry(AListView: TListView; const APath: string); procedure dxSaveListViewColumnsToRegistry(AListView: TListView; const APath: string); procedure dxRestoreListViewSelection(AListView: TListView; ASelection: TList); procedure dxSaveListViewSelection(AListView: TListView; ASelection: TList); procedure CopyImages(ASourceHandle: HIMAGELIST; ADest: TCustomImageList); procedure PlaceButtons(const AButtons: array of TButton; ABtnOffsetX, ARightOrigin, ATopOrigin: Integer); procedure dxAppendList(ASource, ADest: TList); procedure dxCopyList(ASource, ADest: TList); procedure dxShiftIntegerListValues(AList: TList; AValue: Integer); function dxCheckStateImageIndexMap(AState: TCheckBoxState): Integer; procedure dxCreateCheckMarkImages(AnImageList: TCustomImageList); function dxPSDrawModeImages: TCustomImageList; {$IFNDEF DELPHI5} procedure FreeAndNil(var Obj); {$ENDIF} // VCL Helpers - introduced mostly because of Delphi.Net function dxAllocatehWnd(AMethod: TWndMethod): HWND; procedure dxDeallocatehWnd(AWnd: HWND); procedure dxRecreateWnd(AControl: TWinControl); function MakeBounds(ALeft, ATop, AWidth, AHeight: Integer): TRect; function MakePoint(X, Y: Integer): TPoint; function MakeRect(ALeft, ATop, ARight, ABottom: Integer): TRect; overload; function MakeRect(const ATopLeft, ABottomRight: TPoint): TRect; overload; function TTagToInt(AValue: Integer ): Integer; function TTagToObj(AValue: Integer ): TObject; function TTagToClass(AValue: Integer ): TClass; function MakeTTag(AValue: Integer): Integer ; overload; function MakeTTag(AValue: TObject): Integer ; overload; function MakeTTag(AValue: TClass): Integer ; overload; function Control_GetColor(AControl: TControl): TColor; function Control_GetControlStyle(AControl: TControl): TControlStyle; function Control_GetCtl3D(AControl: TWinControl): Boolean; function Control_GetFont(AControl: TControl): TFont; function Control_GetPopupMenu(AControl: TControl): TPopupMenu; function Control_GetText(AControl: TControl): string; procedure Control_SetParentBackground(AControl: TWinControl; Value: Boolean); procedure Control_DoContextPopup(AControl: TControl; const Pt: TPoint; var AHandled: Boolean); procedure Control_PaintWindow(AControl: TWinControl; DC: HDC); procedure Control_SendCancelMode(AControl, ASender: TControl); procedure Control_UpdateBoundsRect(AControl: TControl; const R: TRect); overload; procedure Control_UpdateBoundsRect(AControl: TControl; ALeft, ARight, AWidth, AHeight: Integer); overload; procedure PopupMenu_DoPopup(APopupMenu: TPopupMenu); function RichEdit_GetBorderStyle(AControl: TCustomRichEdit): TBorderStyle; function RichEdit_GetLines(AControl: TCustomRichEdit): TStrings; procedure Bitmap_LoadFromResourceName(ABitmap: TBitmap; const AResName: string; ABaseName: string = 'dxPSImgs'); procedure Icon_LoadFromResourceName(AIcon: TIcon; const AResName: string; ABaseName: string = 'dxPSImgs'); function IsDelphiObject(AData: DWORD): Boolean; implementation uses {$IFDEF DELPHI6} Types, StrUtils, {$ENDIF} {$IFDEF USEJPEGIMAGE} Jpeg, {$ENDIF} Consts, ActiveX, ShlObj, ShellAPI, FileCtrl, dxPSRes, dxPSImgs; const CharCount = 26; Chars: array[Boolean] of string[CharCount] = (('abcdefghijklmnopqrstuvwxyz'), ('ABCDEFGHIJKLMNOPQRSTUVWXYZ')); ColumnPath = '\ColumnWidths'; // Don't Localize ColumnPattern = 'Column%d'; // Don't Localize var FDrawModeImages: TCustomImageList; FPatternBrush: HBRUSH; FShellLargeImages: TImageList; FShellSmallImages: TImageList; FNonTrueTypeFonts: TStringList; FTrueTypeFonts: TStringList; type TControlAccess = class(TControl); TCustomRichEditAccess = class(TCustomRichEdit); TGraphicAccess = class(TGraphic); {$IFNDEF DELPHI6} TGraphicAccessClass = class of TGraphicAccess; {$ENDIF} {$IFDEF DELPHI5} TPopupMenuAccess = class(TPopupMenu); {$ENDIF} TWinControlAccess = class(TWinControl); function FontStyleNames(AFontStyle: TFontStyle): string; begin case AFontStyle of fsBold: Result := cxGetResourceString(@sdxFontStyleBold); fsItalic: Result := cxGetResourceString(@sdxFontStyleItalic); fsUnderline: Result := cxGetResourceString(@sdxFontStyleUnderline); else Result := cxGetResourceString(@sdxFontStyleStrikeOut); end; end; function NonTrueTypeFonts: TStringList; begin if FNonTrueTypeFonts = nil then begin FNonTrueTypeFonts := TStringList.Create; FNonTrueTypeFonts.Sorted := True; end; Result := FNonTrueTypeFonts; end; function TrueTypeFonts: TStringList; begin if FTrueTypeFonts = nil then begin FTrueTypeFonts := TStringList.Create; FTrueTypeFonts.Sorted := True; end; Result := FTrueTypeFonts; end; function Min(A, B: Integer): Integer; begin Result := A; if A > B then Result := B; end; function Max(A, B: Integer): Integer; begin Result := A; if B > A then Result := B; end; function MinMax(A, B, C: Integer): Integer; begin if B > C then Result := A else if A < B then Result := B else if A > C then Result := C else Result := A; end; function SetLoWord(AValue: Integer; ALoWord: Word): Integer; begin Result := (AValue and Integer($0000FFFF)) or (ALoWord shl 16); end; function SetHiWord(AValue: Integer; AHiWord: Word): Integer; begin Result := (AValue and Integer($FFFF0000)) or (AHiWord and $FFFF); end; function SetLoHiWords(AValue: Integer; ALoWord, AHiWord: Word): Integer; begin Result := SetHiWord(SetLoWord(AValue, ALoWord), AHiWord); end; function ScaleRect(const R: TRect; ANumeratorW, ADenominatorW, ANumeratorH, ADenominatorH: Integer): TRect; begin with Result do begin Left := MulDiv(R.Left, ANumeratorW, ADenominatorW); Top := MulDiv(R.Top, ANumeratorH, ADenominatorH); Right := MulDiv(R.Right, ANumeratorW, ADenominatorW); Bottom := MulDiv(R.Bottom, ANumeratorH, ADenominatorH); end; end; function ScaleRect(const R: TRect; ANumerator, ADenominator: Integer): TRect; begin Result := ScaleRect(R, ANumerator, ADenominator, ANumerator, ADenominator); end; function ScalePoint(const Pt: TPoint; Numerator, Denominator: Integer): TPoint; begin Result.X := MulDiv(Pt.X, Numerator, Denominator); Result.Y := MulDiv(Pt.Y, Numerator, Denominator); end; function ArePointsEqual(const Pt1, Pt2: TPoint): Boolean; begin Result := (Pt1.X = Pt2.X) and (Pt1.Y = Pt2.Y); end; function GetRgnData(ARgn: HRGN; out ARgnDataHeader: TRgnDataHeader; out ARects: TRects): Integer; var Size: Integer; RgnData: PRgnData; I: Integer; begin Size := GetRegionData(ARgn, 0, nil); RgnData := AllocMem(SizeOf(TRgnDataHeader) + SizeOf(TRect) * (Size - SizeOf(TRgnDataHeader))); try GetRegionData(ARgn, Size, RgnData); ARgnDataHeader := RgnData.rdh; Result := RgnData.rdh.nCount; SetLength(ARects, Result); for I := 0 to Result - 1 do Move(RgnData.Buffer[I * SizeOf(TRect)], ARects[I], SizeOf(TRect)); finally FreeMem(RgnData, Size); end; end; function ExcludeClipRect(DC: HDC; const R: TRect): HRGN; begin with R do Result := ExcludeClipRect(DC, Left, Top, Right, Bottom); end; function ExcludeClipRect(DC: HDC; ALeft, ATop, ARight, ABottom: Integer): HRGN; begin Result := Windows.CreateRectRgn(0, 0, 0, 0); if Windows.GetClipRgn(DC, Result) <> 1 then begin Windows.DeleteObject(Result); Result := 0; end; Windows.ExcludeClipRect(DC, ALeft, ATop, ARight, ABottom); end; function IntersectClipRect(DC: HDC; const R: TRect; AlwaysClip: Boolean = False): HRGN; begin with R do Result := IntersectClipRect(DC, Left, Top, Right, Bottom); end; function IntersectClipRect(DC: HDC; ALeft, ATop, ARight, ABottom: Integer; AlwaysClip: Boolean = False): HRGN; begin Result := Windows.CreateRectRgn(0, 0, 0, 0); if Windows.GetClipRgn(DC, Result) <> 1 then begin Windows.DeleteObject(Result); Result := 0; end else if IsMetaFileDC(DC) then begin Result := Windows.CreateRectRgn(0, 0, 320000, 320000); if Windows.SelectClipRgn(DC, Result) = ERROR then begin DeleteObject(Result); Result := 0; Exit; end; end; Windows.IntersectClipRect(DC, ALeft, ATop, ARight, ABottom); end; function RectVisible(DC: HDC; const ARect: TRect): Boolean; begin if IsMetafileDC(DC) then Result := True else Result := Windows.RectVisible(DC, ARect); end; procedure RestoreClipRgn(DC: HDC; var ARgn: HRGN); begin Windows.SelectClipRgn(DC, ARgn); if ARgn <> 0 then Windows.DeleteObject(ARgn); ARgn := 0; end; function dxBoolToStr(AValue: Boolean): string; begin {$IFDEF DELPHI6} Result := SysUtils.BoolToStr(AValue, True); {$ELSE} if AValue then Result := cxGetResourceString(@sdxTrue) else Result := cxGetResourceString(@sdxFalse); {$ENDIF} end; function dxSameStr(const S1, S2: string): Boolean; begin {$IFDEF DELPHI6} Result := AnsiSameStr(S1, S2); {$ELSE} Result := AnsiCompareStr(S1, S2) = 0; {$ENDIF} end; function dxSameText(const S1, S2: string): Boolean; begin {$IFDEF DELPHI6} Result := AnsiSameText(S1, S2); {$ELSE} Result := AnsiCompareText(S1, S2) = 0; {$ENDIF} end; function dxAreBitmapsEqual(ABitmap1, ABitmap2: TBitmap): Boolean; begin Result := dxAreGraphicsEqual(ABitmap1, ABitmap2); end; function dxAreBrushesEqual(ABrush1, ABrush2: TBrush): Boolean; begin Result := ((ABrush1 = nil) and (ABrush2 = nil)) or ((ABrush1 <> nil) and (ABrush2 <> nil) and (ABrush1.Color = ABrush2.Color) and (ABrush1.Style = ABrush2.Style)); end; function dxAreFontsEqual(AFont1, AFont2: TFont): Boolean; begin Result := ((AFont1 = nil) and (AFont2 = nil)) or ((AFont1 <> nil) and (AFont2 <> nil) and (AFont1.Color = AFont2.Color) and (AFont1.Name = AFont2.Name) and (AFont1.Pitch = AFont2.Pitch) and (AFont1.Style = AFont2.Style) and (AFont1.Size = AFont2.Size)); // and // (AFont1.Charset = AFont2.Charset)); end; function dxAreGraphicsEqual(AGraphic1, AGraphic2: TGraphic): Boolean; begin Result := (AGraphic1 = AGraphic2) or ((AGraphic1 <> nil) and TGraphicAccess(AGraphic1).Equals(AGraphic2)); end; function dxArePensEqual(APen1, APen2: TPen): Boolean; begin Result := ((APen1 = nil) and (APen2 = nil)) or ((APen1 <> nil) and (APen2 <> nil) and (APen1.Color = APen2.Color) and (APen1.Mode = APen2.Mode) and (APen1.Style = APen2.Style) and (APen1.Width = APen2.Width)); end; function FormatFontInfo(AFont: TFont): string; var S: string; FS: TFontStyle; begin Result := ''; if AFont = nil then Exit; Result := Format('%d %s %s ', [AFont.Size, cxGetResourceString(@sdxPt), AFont.Name]); if AFont.Style <> [] then begin Result := Result + ' ['; S := ''; for FS := Low(TFontStyle) to High(TFontStyle) do if FS in AFont.Style then begin if S <> '' then S := S + ', '; S := S + FontStyleNames(FS); end; Result := Result + S + ']'; end; end; procedure FontInfoToText(AFont: TFont; AEdit: TEdit); begin AEdit.Text := FormatFontInfo(AFont); if ColorToRGB(AFont.Color) <> ColorToRGB(AEdit.Color) then AEdit.Font.Color := AFont.Color else AEdit.Font.Color := clWindowText; end; type PSearchBuffer = ^TSearchBuffer; TSearchBuffer = record FontName: string; IsTrueType: Boolean; end; function EnumFontsProc(var AnEnumLogFont: TEnumLogFont; var ATextMetric: TNewTextMetric; AFontType: Integer; AData: LPARAM): Integer; stdcall; begin with AnEnumLogFont.elfLogFont do begin Result := Integer(not (StrIComp(PChar(PSearchBuffer(AData)^.FontName), PChar(@lfFaceName[0])) = 0)); if Result = 0 then PSearchBuffer(AData)^.IsTrueType := AFontType and TRUETYPE_FONTTYPE = TRUETYPE_FONTTYPE; end; end; function dxIsTrueTypeFont(AFont: TFont): Boolean; function CalculateIsTrueTypeFont(AFont: TFont): Boolean; var DC: HDC; SearchBuffer: PSearchBuffer; begin DC := GetDC(0); try try New(SearchBuffer); try SearchBuffer^.FontName := AFont.Name; EnumFontFamilies(DC, nil, @EnumFontsProc, LPARAM(SearchBuffer)); Result := SearchBuffer^.IsTrueType; finally Finalize(SearchBuffer^.FontName); Dispose(PSearchBuffer(SearchBuffer)); end; except Result := False; end; finally ReleaseDC(0, DC); end; end; begin Result := TrueTypeFonts.IndexOf(AFont.Name) <> -1; // found in TT Fonts if not Result then begin Result := NonTrueTypeFonts.IndexOf(AFont.Name) = -1; // not found in non TT Fonts if Result then begin Result := CalculateIsTrueTypeFont(AFont); if Result then TrueTypeFonts.Add(AFont.Name) else NonTrueTypeFonts.Add(AFont.Name); end; end; end; function FindNearestColor(AColor: TColor): TColor; var DC: HDC; begin DC := GetDC(0); Result := GetNearestColor(DC, AColor); ReleaseDC(0, DC); end; function InvertColor(AColor: TColor): TColor; begin Result := $FFFFFF xor ColorToRGB(AColor); end; function OffsetColor(AColor: TColor; ARed, AGreen, ABlue: Byte): TColor; var Red, Green, Blue: Integer; begin AColor := ColorToRGB(AColor); Red := GetRValue(AColor) + ARed; if Red > High(Byte) then Red := High(Byte); if Red < Low(Byte) then Red := Low(Byte); Green := GetGValue(AColor) + AGreen; if Green > High(Byte) then Green := High(Byte); if Green < Low(Byte) then Green := Low(Byte); Blue := GetBValue(AColor) + ABlue; if Blue > High(Byte) then Blue := High(Byte); if Blue < Low(Byte) then Blue := Low(Byte); Result := RGB(Red, Green, Blue); end; function IsDisplayDC(DC: HDC): Boolean; begin Result := GetDeviceCaps(DC, TECHNOLOGY) = DT_RASDISPLAY; end; function IsMetafileDC(DC: HDC): Boolean; begin Result := GetObjectType(DC) in [OBJ_METADC, OBJ_ENHMETADC]; end; function IsPrinterDC(DC: HDC): Boolean; begin Result := GetDeviceCaps(DC, TECHNOLOGY) = DT_RASPRINTER; end; function CreatePatternBrush: HBRUSH; var PatternBitmap: HBITMAP; DC: HDC; X, Y: Integer; begin PatternBitmap := CreateBitmap(8, 8, 1, 1, nil); try DC := CreateCompatibleDC(0); PatternBitmap := SelectObject(DC, PatternBitmap); for X := 0 to 7 do for Y := 0 to 7 do SetPixel(DC, X, Y, $FFFFFF * Byte(Odd(X) = Odd(Y))); PatternBitmap := SelectObject(DC, PatternBitmap); DeleteDC(DC); Result := Windows.CreatePatternBrush(PatternBitmap); finally DeleteObject(PatternBitmap); end; end; function PatternBrush: HBRUSH; begin if FPatternBrush = 0 then FPatternBrush := CreatePatternBrush; Result := FPatternBrush; end; procedure SetFontAsNonAntialiased(AFont: TFont); var LogFont: TLogFont; begin cxGetFontData(AFont.Handle, LogFont); LogFont.lfQuality := {LogFont.lfQuality and not} NONANTIALIASED_QUALITY; AFont.Handle := CreateFontIndirect(LogFont); end; procedure ForcePictureToBitmap(APicture: TPicture); var B: TBitmap; begin with APicture do if (Graphic <> nil) and not Graphic.InheritsFrom(TBitmap) then if not Graphic.InheritsFrom(TIcon) then begin B := TBitmap.Create; try B.Assign(Graphic); Bitmap := B; finally B.Free; end; end else Bitmap := IconToBitmap(TIcon(Graphic)); end; function CreateGraphic(AGraphicClass: TGraphicClass): TGraphic; begin {$IFDEF DELPHI6} Result := AGraphicClass.Create; {$ELSE} Result := TGraphicAccessClass(AGraphicClass).Create; {$ENDIF} end; function IconToBitmap(AnIcon: TIcon): TBitmap; //var // IconInfo: TIconInfo; begin Result := TBitmap.Create; with Result do begin Height := AnIcon.Height; Width := AnIcon.Width; //GetIconInfo(AnIcon.Handle, IconInfo); //MaskHandle := IconInfo.hbmMask; Transparent := True; Canvas.Draw(0, 0, AnIcon); end; end; function CreateArrowBitmap(AUpDownGlyph: TdxUpDownGlyph; AWidth: Integer = 16; AHeight: Integer = 16; AFontSize: Integer = 12): TBitmap; const GlyphIndexes: array[TdxUpDownGlyph] of Integer = (GLYPH_UPARROW, GLYPH_DOWNARROW); begin Result := CreateGlyphBitmap(GlyphIndexes[AUpDownGlyph], AWidth, AHeight, AFontSize); end; function CreateDoubleArrowBitmap(AUpDownGlyph: TdxUpDownGlyph; AWidth: Integer = 16; AHeight: Integer = 16; AFontSize: Integer = 8): TBitmap; const GlyphIndexes: array[TdxUpDownGlyph] of Integer = (GLYPH_UPARROW, GLYPH_DOWNARROW); OffsetUp = 2; OffsetDown = -1; var B1, B2: TBitmap; begin B1 := CreateGlyphBitmap(GlyphIndexes[AUpDownGlyph], AWidth, AHeight, AFontSize); try B1.Transparent := True; B2 := CreateGlyphBitmap(GlyphIndexes[AUpDownGlyph], AWidth, AHeight, AFontSize); try B2.Transparent := True; Result := TBitmap.Create; with Result do begin Width := AWidth; Height := AHeight; Canvas.Brush.Color := clBtnFace; Canvas.FillRect(Rect(0, 0, AWidth, AHeight)); Canvas.Draw(0, OffsetUp, B1); Canvas.Draw(0, OffsetDown, B2); end; finally B2.Free; end; finally B1.Free; end; end; function CreateGlyphBitmap(AGlyphIndex: Integer; AWidth: Integer = 16; AHeight: Integer = 16; AFontSize: Integer = 12): TBitmap; var W, H, X, Y: Integer; Ch: Char; begin W := AWidth; H := AHeight; if W = 0 then W := 16; if H = 0 then H := 16; Result := TBitmap.Create; with Result do begin Width := W; Height := H; Canvas.Brush.Color := clBtnFace; Canvas.FillRect(Rect(0, 0, Width, Height)); Canvas.Font.Name := 'Marlett'; Canvas.Font.Size := AFontSize; Canvas.Font.Color := clWindowText; Canvas.Font.Charset := SYMBOL_CHARSET; Ch := Chr(AGlyphIndex); X := 0; Y := 0; if (AWidth <> 0) and (AHeight <> 0) then begin X := (Width - Canvas.TextWidth(Ch)) div 2; Y := (Height - Canvas.TextHeight(Ch)) div 2; end else begin Width := Canvas.TextWidth(Ch); Height := Canvas.TextHeight(Ch); end; Canvas.TextOut(X, Y, Ch); end; end; procedure DrawBlendedText(ACanvas: TCanvas; const R: TRect; const AText: string; AFont: TFont); var MemDC: HDC; MemBitmap: HBITMAP; procedure PrepareOffScreenStructures(DC: HDC; ASize: TSize); begin MemBitmap := CreateCompatibleBitmap(DC, ASize.cX, ASize.cY); MemDC := CreateCompatibleDC(DC); MemBitmap := SelectObject(MemDC, MemBitmap); end; procedure CreateTextOutClipPath(const R: TRect; const AText: string; AFont: TFont); var F: HFONT; C: TColor; BkMode: Integer; begin FillRect(MemDC, R, GetStockObject(WHITE_BRUSH)); F := SelectObject(MemDC, AFont.Handle); C := SetTextColor(MemDC, $FFFFFF); BkMode := SetBkMode(MemDC, Windows.TRANSPARENT); BeginPath(MemDC); TextOut(MemDC, 0, 0, PChar(AText), Length(AText)); EndPath(MemDC); SetBkMode(MemDC, BkMode); SetTextColor(MemDC, C); SelectObject(MemDC, F); SelectClipPath(MemDC, RGN_COPY); end; procedure PatternTextOutClipPath(const R: TRect; ATextColor: TColor); var BkColor: COLORREF; begin ATextColor := SetTextColor(MemDC, ATextColor); BkColor := SetBkColor(MemDC, $FFFFFF); FillRect(MemDC, R, PatternBrush); SetTextColor(MemDC, ATextColor); SetBkColor(MemDC, BkColor); end; procedure UnprepareOffScreenStructures; begin MemBitmap := SelectObject(MemDC, MemBitmap); DeleteDC(MemDC); DeleteObject(MemBitmap); end; var DC: HDC; Size: TSize; MemRect: TRect; F: HFONT; X, Y: Integer; begin DC := ACanvas.Handle; F := SelectObject(DC, AFont.Handle); GetTextExtentPoint(DC, PChar(AText), Length(AText), Size); MemRect := MakeRect(0, 0, Size.cX, Size.cY); PrepareOffScreenStructures(DC, Size); try CreateTextOutClipPath(MemRect, AText, AFont); PatternTextOutClipPath(MemRect, ColorToRGB(AFont.Color)); SelectClipRgn(MemDC, 0); with R do begin X := Left + (Right - Left - Size.cX) div 2; Y := Top + (Bottom - Top - Size.cY) div 2; end; BitBlt(DC, X, Y, Size.cX, Size.cY, MemDC, 0, 0, SRCAND); finally UnprepareOffScreenStructures; end; SelectObject(DC, F); end; procedure DrawGlyph(DC: HDC; const R: TRect; AGlyph: Byte); var C: Char; begin C := Chr(AGlyph); ExtTextOut(DC, R.Left, R.Top, 0, @R, @C, 1, nil); end; procedure DrawSizeGrip(DC: HDC; R: TRect); var V: Integer; begin V := GetSystemMetrics(SM_CXVSCROLL); R := MakeRect(R.Right - V, R.Bottom - V, R.Right, R.Bottom); DrawFrameControl(DC, R, DFC_SCROLL, DFCS_SCROLLSIZEGRIP); end; procedure TransparentDraw(DrawDC: HDC; Brush: HBRUSH; const R: TRect; ABitmap: TBitmap); const ROP_DSPDxax = $00E20746; var BW, BH: Integer; DC, MaskDC: HDC; B, MaskHandle: HBITMAP; ATextColor, ABackColor: COLORREF; ABrush: HBRUSH; begin with R do begin BW := ABitmap.Width; BH := ABitmap.Height; DC := CreateCompatibleDC(DrawDC); B := SelectObject(DC, CreateCompatibleBitmap(DrawDC, BW, BH)); try BitBlt(DC, 0, 0, BW, BH, ABitmap.Canvas.Handle, 0, 0, SRCCOPY); MaskDC := CreateCompatibleDC(DrawDC); MaskHandle := SelectObject(MaskDC, CreateBitmap(BW, BH, 1, 1, nil)); try ABackColor := SetBkColor(DC, ColorToRGB(ABitmap.TransparentColor){GetPixel(DC, 0, BH - 1)}); BitBlt(MaskDC, 0, 0, BW, BH, DC, 0, 0, SRCCOPY); SetBkColor(DC, ABackColor); ATextColor := SetTextColor(DC, 0); ABackColor := SetBkColor(DC, $FFFFFF); ABrush := SelectObject(DC, Brush); BitBlt(DC, 0, 0, BW, BH, MaskDC, 0, 0, ROP_DSPDxax); SelectObject(DC, ABrush); SetTextColor(DC, ATextColor); SetBkColor(DC, ABackColor); finally DeleteObject(SelectObject(MaskDC, MaskHandle)); DeleteDC(MaskDC); end; BitBlt(DrawDC, Left, Top, Right - Left, Bottom - Top, DC, 0, 0, SRCCOPY); finally DeleteObject(SelectObject(DC, B)); DeleteDC(DC); end; end; end; {.$WARN SYMBOL_DEPRECATED OFF} function CopyDeviceMode(Src: HGLOBAL): HGLOBAL; var Size: Integer; SrcPtr, DestPtr: PChar; begin if Src <> 0 then begin Size := GlobalSize(Src); Result := GlobalAlloc(GHND, Size); if Result <> 0 then begin SrcPtr := GlobalLock(Src); if SrcPtr <> nil then try DestPtr := GlobalLock(Result); if DestPtr <> nil then try Move(SrcPtr^, DestPtr^, Size); finally GlobalUnlock(Result); end; finally GlobalUnlock(Src); end; end; end else Result := 0; end; {.$WARN SYMBOL_DEPRECATED ON} function GetDesktopWorkArea: TRect; function IntersectionArea(const ABounds: TRect; APoint: TPoint; var Area: TRect): Integer; var R: TRect; begin Area := GetDesktopWorkArea(APoint); if IntersectRect(R, ABounds, Area) then Result := Abs(R.Right - R.Left) * Abs(R.Bottom - R.Top) else Result := 0; end; var R, R1: TRect; begin if Application.MainForm <> nil then begin Result := Application.MainForm.BoundsRect; if IntersectionArea(Result, Result.TopLeft, R) > IntersectionArea(Result, Result.BottomRight, R1) then Result := R else Result := R1; end else SystemParametersInfo(SPI_GETWORKAREA, 0, @Result, 0); end; function GetDesktopWorkArea(const P: TPoint): TRect; const MONITOR_DEFAULTTONEAREST = $2; type HMONITOR = type Integer; PMonitorInfo = ^TMonitorInfo; TMonitorInfo = record cbSize: DWORD; rcMonitor: TRect; rcWork: TRect; dwFalgs: DWORD; end; var AUser32DLL: THandle; Info: TMonitorInfo; GetMonitorInfo: function(hMonitor: HMONITOR; lpMonitorInfo: PMonitorInfo): Boolean; stdcall; MonitorFromPoint: function(ptScreenCoords: TPoint; dwFlags: DWORD): HMONITOR; stdcall; begin AUser32DLL := LoadLibrary('USER32'); if AUser32DLL > 32 then begin GetMonitorInfo := GetProcAddress(AUser32DLL, 'GetMonitorInfoA'); MonitorFromPoint := GetProcAddress(AUser32DLL, 'MonitorFromPoint'); end else begin GetMonitorInfo := nil; MonitorFromPoint := nil; end; if @GetMonitorInfo = nil then SystemParametersInfo(SPI_GETWORKAREA, 0, @Result, 0) else begin Info.cbSize := SizeOf(Info); GetMonitorInfo(MonitorFromPoint(P, MONITOR_DEFAULTTONEAREST), @Info); Result := Info.rcWork; end; FreeLibrary(AUser32DLL); end; function GetLongFileName(const Source: string): string; var Handle: THandle; Proc: function(ShortPathName, LongPathName: PChar; cchBuffer: Integer): Integer; stdcall; Buffer: array[0..MAX_PATH] of Char; begin Handle := GetModuleHandle(kernel32); if Handle <> 0 then begin @Proc := GetProcAddress(Handle, 'GetLongPathNameA'); if (@Proc <> nil) and (Proc(PChar(Source), Buffer, SizeOf(Buffer)) <> 0) then Result := Buffer else Result := Source; end else Result := Source; end; function GetMachineName: string; var BufferSize: DWORD; Buffer: array[0..MAX_COMPUTERNAME_LENGTH + 1] of Char ; begin BufferSize := MAX_COMPUTERNAME_LENGTH + 1; GetComputerName(Buffer, BufferSize); Result := Buffer; end; function GetUserName: string; var BufferSize: DWORD; Buffer: array[0..UNLEN + 1] of Char ; begin BufferSize := UNLEN + 1; Windows.GetUserName(Buffer, BufferSize); Result := Buffer; end; function GetVolumeName(const APath: string): string; var PrevErrorMode: UINT; Buffer: array[Byte] of Char; L, Flags: DWORD; begin PrevErrorMode := Windows.SetErrorMode(SEM_FAILCRITICALERRORS); try if GetVolumeInformation(PChar(APath), @Buffer, SizeOf(Buffer), nil, L, Flags, nil, 0) then Result := Buffer else Result := ''; finally Windows.SetErrorMode(PrevErrorMode); end; end; function IsIntelliMousePresent: Boolean; begin Result := Boolean(GetSystemMetrics(SM_MOUSEWHEELPRESENT)); end; function IsNetworkPresent: Boolean; begin Result := GetSystemMetrics(SM_NETWORK) and $01 = $01; end; function IsVolume(const APath: string): Boolean; begin Result := ExtractFileDir(APath) = APath; end; function IsWin32Version(AMajor: Integer; AMinor: Integer = 0): Boolean; begin Result := (Win32MajorVersion > AMajor) or ((Win32MajorVersion = AMajor) and (Win32MinorVersion >= AMinor)); end; function PopulateShellImages(FullInit: Boolean): Boolean; var ShellDLLLoaded: Boolean; ShellDLL: HMODULE; Proc: function(FullInit: BOOL): BOOL; stdcall; begin Result := False; if IsWinNT then begin ShellDLLLoaded := False; ShellDLL := GetModuleHandle(ShellAPI.Shell32); if ShellDLL = 0 then begin ShellDLL := LoadLibrary(ShellAPI.Shell32); if ShellDLL <= Windows.HINSTANCE_ERROR then ShellDLL := 0; ShellDLLLoaded := ShellDLL <> 0; end; if ShellDLL <> 0 then try Proc := GetProcAddress(ShellDll, PChar(660)); Result := (@Proc <> nil) and Proc(FullInit); finally if ShellDLLLoaded then FreeLibrary(ShellDll); end; end; end; function ShellLargeImages: TImageList; var FileInfo: TSHFileInfo; begin if FShellLargeImages = nil then begin FShellLargeImages := TImageList.Create(nil); FShellLargeImages.ShareImages := True; try FillChar(FileInfo, SizeOf(FileInfo), 0); FShellLargeImages.Handle := SHGetFileInfo('', 0, FileInfo, SizeOf(FileInfo), SHGFI_SYSICONINDEX or SHGFI_LARGEICON); finally if FileInfo.hIcon <> 0 then Windows.DestroyIcon(FileInfo.hIcon); end; end; Result := FShellLargeImages; end; function ShellSmallImages: TImageList; var FileInfo: TSHFileInfo; begin if FShellSmallImages = nil then begin FShellSmallImages := TImageList.Create(nil); FShellSmallImages.ShareImages := True; try FillChar(FileInfo, SizeOf(FileInfo), 0); FShellSmallImages.Handle := SHGetFileInfo('', 0, FileInfo, SizeOf(FileInfo), SHGFI_SYSICONINDEX or SHGFI_SMALLICON); finally if FileInfo.hIcon <> 0 then Windows.DestroyIcon(FileInfo.hIcon); end; end; Result := FShellSmallImages; end; function BFFCallBack(Wnd: HWND; uMsg: UINT; lParam, lpData: LPARAM): Integer; stdcall; var Path: PChar absolute lParam; B: Boolean; Buffer: array[0..MAX_PATH] of Char; S: string; begin Result := 0; if uMsg = BFFM_INITIALIZED then begin B := not IsWin9X or (IsVolume(Path) and DirectoryExists(Path)); if B then SendMessage(Wnd, BFFM_SETSELECTION, WPARAM(True), lpData); end; if uMsg = BFFM_SELCHANGED then begin B := SHGetPathFromIDList(PItemIDList(lParam), @Buffer); if B then begin SetString(S, PChar(@Buffer), MAX_PATH); B := DirectoryExists(S); end; SendMessage(Wnd, BFFM_ENABLEOK, 0, Ord(B)); end; if (uMsg = BFFM_VALIDATEFAILEDA) or (uMsg = BFFM_VALIDATEFAILEDW) then begin S := Format(cxGetResourceString(@sdxInvalidRootDirectory), [Path]); Result := Ord(MessageQuestion(S)); if Result = 1 then SendMessage(Wnd, BFFM_ENABLEOK, 0, 0); end; end; function ShowSystemSelectFolderDlg(var ADirPath: string): Boolean; const EditBoxFlags: array[Boolean] of UINT = (0, BIF_EDITBOX); NewDialogStyleFlags: array[Boolean] of UINT = (0, BIF_NEWDIALOGSTYLE); ValidateFlags: array[Boolean] of UINT = (0, BIF_VALIDATE); var ShellMalloc: IMalloc; Buffer: PChar; BrowseInfo: TBrowseInfo; PrevErrorMode: Cardinal; WindowList: Pointer ; IDList: PItemIDList ; begin if (ShGetMalloc(ShellMalloc) = S_OK) and (ShellMalloc <> nil) then begin Buffer := ShellMalloc.Alloc(MAX_PATH); try FillChar(BrowseInfo, SizeOf(TBrowseInfo), 0); BrowseInfo.hwndOwner := Application.Handle; BrowseInfo.pszDisplayName := Buffer; BrowseInfo.lpszTitle := PChar(cxGetResourceString(@sdxSelectNewRoot)); BrowseInfo.ulFlags := BIF_RETURNONLYFSDIRS or EditBoxFlags[IsComCtrlVersion471] or NewDialogStyleFlags[IsComCtrlVersion500] or ValidateFlags[IsComCtrlVersion471]; if IsVolume(ADirPath) then ADirPath := ADirPath + '\'; BrowseInfo.lpfn := BFFCallBack; BrowseInfo.lParam := LPARAM(PChar(ADirPath)); WindowList := DisableTaskWindows(0); try PrevErrorMode := SetErrorMode(SEM_FAILCRITICALERRORS); try IDList := SHBrowseForFolder(BrowseInfo); Result := IDList <> nil; if Result then begin SHGetPathFromIDList(IDList, Buffer); ShellMalloc.Free(IDList); if StrLen(Buffer) > 0 then ADirPath := Buffer; end; finally SetErrorMode(PrevErrorMode); end; finally EnableTaskWindows(WindowList); end; finally ShellMalloc.Free(Buffer); end; end else Result := False; end; function FormatFileSize(const AFileSize: Int64): string; const FormatTemplate = '##0.#'; KiloByte = 1024; MegaByte = KiloByte * KiloByte; GigaByte = KiloByte * MegaByte; begin if AFileSize > GigaByte then Result := FormatFloat(FormatTemplate, AFileSize / GigaByte) + ' ' + cxGetResourceString(@sdxGigaBytes) else if AFileSize > MegaByte then Result := FormatFloat(FormatTemplate, AFileSize / MegaByte) + ' ' + cxGetResourceString(@sdxMegaBytes) else if AFileSize > KiloByte then Result := FormatFloat(FormatTemplate, AFileSize / KiloByte) + ' ' + cxGetResourceString(@sdxKiloBytes) else Result := FormatFloat(FormatTemplate, AFileSize) + ' ' + cxGetResourceString(@sdxBytes); end; function ValidateFileName(const FileName: string): Boolean; function HasChars(const Str, Substr: string): Boolean; var I: Integer; begin Result := False; for I := 1 to Length(Substr) do if Pos(Substr[I], Str) > 0 then begin Result := True; Break; end; end; begin Result := (Trim(FileName) <> '') and not HasChars(FileName, '<>"[]|'); if Result then Result := Pos('\', ExtractFileName(FileName)) = 0; end; procedure Delay(Value: DWORD); //milliseconds var T: DWORD; begin T := GetTickCount; while GetTickCount - T < Value do ; end; { Strings management routines } function ReplaceSubStr(const Source, OldChars, NewChars: string): string; var L, P: Integer; begin Result := Source; P := Pos(OldChars, Result); if P > 0 then begin L := Length(OldChars); while P > 0 do begin Delete(Result, P, L); if NewChars <> #0 then Insert(NewChars, Result, P); P := Pos(OldChars, Result); end; end; end; function ReplicateChar(const S: string; ACount: Integer): string; {$IFNDEF DELPHI6} var I: Integer; {$ENDIF} begin {$IFDEF DELPHI6} Result := DupeString(S, ACount); {$ElSE} Result := ''; for I := 0 to ACount - 1 do Result := Result + S; {$ENDIF} end; procedure SplitString(const ASource, ASeparator: string; AStrings: TStrings); var P, L: Integer; Buffer: string; begin Buffer := ASource; P := Pos(ASeparator, Buffer); if P > 0 then begin L := Length(ASeparator); while P > 0 do begin if P > 1 then AStrings.Add(Copy(Buffer, 1, P + L - 2)); Delete(Buffer, 1, P + L - 1); P := Pos(ASeparator, Buffer); end; end; if Length(Buffer) > 0 then AStrings.Add(Buffer); end; function MakePageIndexes(const Source: string; out AnOutput: TIntegers): Boolean; function ProcessRange(const S: string; out AnArray: TIntegers): Boolean; var V1, V2, P, Code1, Code2, I: Integer; SLeft, SRight: string; begin V1 := 0; V2 := 0; P := Pos(dxPSGlbl.cPageRangeSeparator, S); Result := P <> 0; if Result then begin SLeft := Copy(S, 1, P - 1); SRight := Copy(S, P + 1, Length(S) - P); Val(SLeft, V1, Code1); Val(SRight, V2, Code2); Result := (Code1 = 0) and (Code2 = 0) and (V2 >= V1); end; if Result then begin SetLength(AnArray, V2 - V1 + 1); for I := V1 to V2 do AnArray[I - V1] := I; end else SetLength(AnArray, 0); end; var Buffer: string; Strings: TStrings; S: string; I, V, Code, L, J: Integer; SubRange: TIntegers; begin SetLength(AnOutput, 0); try Buffer := StringReplace(Source, ' ', '', [rfReplaceAll, rfIgnoreCase]); if Length(Buffer) > 0 then begin Strings := TStringList.Create; try SplitString(Buffer, dxPSGlbl.cPageSeparator, Strings); for I := 0 to Strings.Count - 1 do begin S := Strings[I]; Val(S, V, Code); if (Code <> 0) or (V < 0) then if ProcessRange(S, SubRange) then begin L := Length(AnOutput); SetLength(AnOutput, L + Length(SubRange)); for J := L to L + Length(SubRange) - 1 do AnOutput[J] := SubRange[J - L]; end else Abort else begin SetLength(AnOutput, Length(AnOutput) + 1); AnOutput[Length(AnOutput) - 1] := V; end; end; finally Strings.Free; end; end; except SetLength(AnOutput, 0); end; Result := Length(AnOutput) <> 0; end; function Int2Roman(AValue: Integer; AnUpperCase: Boolean): string; const Max = 13; RomanNumbers: array[1..Max] of Integer = (1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000); RomanStrings: array[Boolean, 1..Max] of string = (('i', 'iv', 'v', 'ix', 'x', 'xl', 'l', 'xc', 'c', 'cd', 'd', 'cm', 'm'), ('I', 'IV', 'V', 'IX', 'X', 'XL', 'L', 'XC', 'C', 'CD', 'D', 'CM', 'M')); var Index: Integer; begin Result := ''; Index := Max; while AValue > 0 do begin while AValue < RomanNumbers[Index] do Dec(Index); while AValue >= RomanNumbers[Index] do begin Dec(AValue, RomanNumbers[Index]); Result := Result + RomanStrings[AnUpperCase, Index]; end; end; end; function Roman2Int(AText: string; AnUpperCase: Boolean): Integer; type TdxNumberOrder = (noOnes, noTens, noHundreds); TdxRomanNumber = 1..9; const RomanNumbers: array[TdxNumberOrder, TdxRomanNumber] of Integer = (( 1, 2, 3, 4, 5, 6, 7, 8, 9), ( 10, 20, 30, 40, 50, 60, 70, 80, 90), (100, 200, 300, 400, 500, 600, 700, 800, 900)); RomanThousand: array[Boolean] of string = ('m', 'M'); RomanStrings: array[Boolean, TdxNumberOrder, TdxRomanNumber] of string = ((('i', 'ii', 'iii', 'iv', 'v', 'vi', 'vii', 'viii', 'ix'), ('x', 'xx', 'xxx', 'xl', 'l', 'lx', 'lxx', 'lxxx', 'lc'), ('c', 'cc', 'ccc', 'cd', 'd', 'dc', 'dcc', 'dccc', 'dm')), (('I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX'), ('X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC'), ('C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM'))); var Number: TdxRomanNumber; Order: TdxNumberOrder; begin Result := 0; while (Length(AText) > 0) and (AText[1] = RomanThousand[AnUpperCase]) do begin Delete(AText, 1, 1); Inc(Result, 1000); end; if AText <> '' then for Order := noHundreds downto noOnes do begin Number := High(TdxRomanNumber); while (Number > 0) and (Pos(RomanStrings[AnUpperCase, Order, Number], AText) <> 1) do Dec(Number); if Number > 0 then begin Inc(Result, RomanNumbers[Order, Number]); Delete(AText, 1, Length(RomanStrings[AnUpperCase, Order, Number])); if AText = '' then Exit; end; end; if AText <> '' then Result := -1; end; function Chars2Int(const AText: string; AnUpperCase: Boolean): Integer; begin Result := CharCount * (Length(AText) - 1) + Pos(AText[1], dxShortStringToString(Chars[AnUpperCase])); end; function Int2Chars(AValue: Integer; AnUpperCase: Boolean): string; var I, C: Integer; begin I := AValue mod CharCount; if I = 0 then I := CharCount; C := AValue div CharCount; if I <> 0 then Inc(C); Result := ReplicateChar(dxShortStringToString(Chars[AnUpperCase][I]), C); end; function AddColon(const Source: string): string; begin Result := Source; if Pos(':', Result) <> (Length(Result) - Length(':') + 1) then Result := Result + ':'; end; function AddEndEllipsis(const Source: string): string; begin Result := Source; if Pos('...', Result) <> (Length(Result) - Length('...') + 1) then Result := Result + '...'; end; function DropAmpersand(const Source: string): string; var I: Integer; begin Result := ''; for I := 1 to Length(Source) do if Source[I] <> '&' then Result := Result + Source[I]; end; function DropColon(const Source: string): string; begin Result := Source; if Result[Length(Result)] = ':' then Delete(Result, Length(Result), 1); end; function DropEndEllipsis(const Source: string): string; begin Result := Source; while (Length(Result) > 0) and (Result[Length(Result)] = '.') do Delete(Result, Length(Result), 1); end; procedure MessageError(const AMessage: string); begin MessageBeep(MB_ICONEXCLAMATION); Application.MessageBox(PChar(AMessage), PChar(Application.Title), MB_OK or MB_ICONERROR); end; procedure MessageWarning(const AMessage: string); begin MessageBeep(MB_ICONEXCLAMATION); Application.MessageBox(PChar(AMessage), PChar(Application.Title), MB_OK or MB_ICONEXCLAMATION); end; function MessageQuestion(const AMessage: string): Boolean; begin MessageBeep(MB_ICONQUESTION); Result := (ID_YES = Application.MessageBox(PChar(AMessage), PChar(Application.Title), MB_YESNO or MB_ICONQUESTION or MB_DEFBUTTON1)); end; function DropT(const Source: string): string; begin Result := Source; if Result[1] = 'T' then Delete(Result, 1, 1); end; function HasPropertyEx(AClass: TClass; const AName: string; ATypeKinds: TTypeKinds): Boolean; var PropList: PPropList; PropCount: Integer; I: Integer; begin PropCount := GetPropList(AClass.ClassInfo, ATypeKinds, nil); if PropCount > 0 then begin PropList := AllocMem(PropCount * SizeOf(PPropInfo)); try PropCount := GetPropList(AClass.ClassInfo, ATypeKinds, PropList); I := 0; while (I < PropCount) and (CompareText(dxShortStringToString(PropList^[I].Name), AName) <> 0) do Inc(I); Result := I < PropCount; finally FreeMem(PropList, PropCount * SizeOf(PPropInfo)); end; end else Result := False; end; function HasPropertyEx(AnObject: TObject; const AName: string; ATypeKinds: TTypeKinds): Boolean; begin Result := HasPropertyEx(AnObject.ClassType, AName, ATypeKinds); end; function HasProperty(AClass: TClass; const AName: string): Boolean; begin Result := HasPropertyEx(AClass, AName, tkAny); end; function HasProperty(AnObject: TObject; const AName: string): Boolean; begin Result := HasPropertyEx(AnObject, AName, tkAny); end; function GetProperty(AnObject: TObject; const AName: string): Variant; {$IFNDEF DELPHI5} var PropInfo: PPropInfo; TypeData: PTypeData; {$ENDIF} begin Result := Null; {$IFNDEF DELPHI5} PropInfo := TypInfo.GetPropInfo(AnObject.ClassInfo, AName); if PropInfo <> nil then begin TypeData := TypInfo.GetTypeData(PropInfo^.PropType^); case PropInfo^.PropType^^.Kind of tkInteger, tkChar, tkWChar, tkClass: Result := TypInfo.GetOrdProp(AnObject, PropInfo); tkEnumeration: if TypeData^.BaseType^ = TypeInfo(Boolean) then Result := Boolean(GetOrdProp(AnObject, PropInfo)) else Result := TypInfo.GetOrdProp(AnObject, PropInfo); tkSet: Result := TypInfo.GetOrdProp(AnObject, PropInfo); tkFloat: Result := TypInfo.GetFloatProp(AnObject, PropInfo); tkMethod: Result := PropInfo^.PropType^.Name; tkString, tkLString, tkWString: Result := TypInfo.GetStrProp(AnObject, PropInfo); tkVariant: Result := TypInfo.GetVariantProp(AnObject, PropInfo); tkInt64: Result := TypInfo.GetInt64Prop(AnObject, PropInfo) + 0.0; end; end; {$ELSE} if HasProperty(AnObject, AName) then Result := TypInfo.GetPropValue(AnObject, AName , False); {$ENDIF} end; procedure SetProperty(AnObject: TObject; const AName: string; const AValue: Variant); {$IFNDEF DELPHI5} function RangedValue(const AMin, AMax: Int64): Int64; begin Result := Trunc(AValue); if Result < AMin then Result := AMin; if Result > AMax then Result := AMax; end; procedure SetEnumProp(AnObject: TObject; APropInfo: PPropInfo; const AValue: string); var Data: Longint; begin Data := TypInfo.GetEnumValue(APropInfo^.PropType^, AValue); if Data >= 0 then TypInfo.SetOrdProp(AnObject, APropInfo, Data); end; var PropInfo: PPropInfo; TypeData: PTypeData; {$ENDIF} begin {$IFNDEF DELPHI5} PropInfo := TypInfo.GetPropInfo(AnObject.ClassInfo, AName); if PropInfo <> nil then begin TypeData := TypInfo.GetTypeData(PropInfo^.PropType^); case PropInfo.PropType^^.Kind of tkInteger, tkChar, tkWChar: TypInfo.SetOrdProp(AnObject, PropInfo, RangedValue(TypeData^.MinValue, TypeData^.MaxValue)); tkEnumeration: if VarIsStr(AValue) then SetEnumProp(AnObject, PropInfo, VarToStr(AValue)) else TypInfo.SetOrdProp(AnObject, PropInfo, RangedValue(TypeData^.MinValue, TypeData^.MaxValue)); tkSet: if VarType(AValue) = varInteger then TypInfo.SetOrdProp(AnObject, PropInfo, AValue); tkFloat: TypInfo.SetFloatProp(AnObject, PropInfo, AValue); tkString, tkLString, tkWString: TypInfo.SetStrProp(AnObject, PropInfo, VarToStr(AValue)); tkVariant: TypInfo.SetVariantProp(AnObject, PropInfo, AValue); tkInt64: TypInfo.SetInt64Prop(AnObject, PropInfo, RangedValue(TypeData^.MinInt64Value, TypeData^.MaxInt64Value)); end; end; {$ELSE} if HasProperty(AnObject, AName) then TypInfo.SetPropValue(AnObject, AName, AValue); {$ENDIF} end; procedure dxDrawComboBoxItem(ACanvas: TCanvas; const R: TRect; const AText: string; AnImageList: TCustomImageList; AnImageIndex: Integer; AState: TOwnerDrawState); function IsImageDrawn: Boolean; begin Result := (AnImageList <> nil) and (AnImageIndex > -1) and (AnImageIndex < AnImageList.Count); end; var X, Y: Integer; begin ACanvas.FillRect(R); if IsImageDrawn then begin with R do begin X := Left + 1; Y := Top + (Bottom - Top - AnImageList.Height) div 2; end; AnImageList.Draw(ACanvas, X, Y, AnImageIndex); end; with R do begin X := Left + 1 + Ord(IsImageDrawn) * (AnImageList.Width + 2); Y := Top + (Bottom - Top - ACanvas.TextHeight(AText)) div 2; end; ACanvas.TextOut(X, Y, AText); end; procedure dxLoadStringsFromRegistry(const APath: string; AStrings: TStrings); var Entries: TStringList; I: Integer; begin with TRegistry.Create do try try if OpenKey(APath, False) then begin AStrings.Clear; Entries := TStringList.Create; try GetValueNames(Entries); for I := 0 to Entries.Count - 1 do if ValueExists(Entries[I]) then AStrings.Add(ReadString(Entries[I])); finally Entries.Free; end; end; except on ERegistryException do { ignore } else raise; end; finally Free; end; end; procedure dxSaveStringsToRegistry(const APath: string; AStrings: TStrings); var I: Integer; begin with TRegistry.Create do try try if KeyExists(APath) then DeleteKey(APath); if OpenKey(APath, True) then for I := 0 to AStrings.Count - 1 do WriteString(IntToStr(I), AStrings[I]); except on ERegistryException do { ignore } else raise; end; finally Free; end; end; procedure dxLoadListViewColumnsFromRegistry(AListView: TListView; const APath: string); var I: Integer; S: string; begin with TRegistry.Create do try try if OpenKey(APath + '\' + AListView.Name + ColumnPath, False) then begin AListView.Columns.BeginUpdate; try for I := 0 to AListView.Columns.Count - 1 do begin S := Format(ColumnPattern, [I]); if ValueExists(S) then AListView.Columns[I].Width := ReadInteger(S); end; finally AListView.Columns.EndUpdate; end; end; except on ERegistryException do { ignore } else raise; end; finally Free; end; end; procedure dxSaveListViewColumnsToRegistry(AListView: TListView; const APath: string); var I: Integer; S: string; begin with TRegistry.Create do try try S := APath + '\' + AListView.Name + ColumnPath; if KeyExists(S) then DeleteKey(S); if OpenKey(S, True) then for I := 0 to AListView.Columns.Count - 1 do WriteInteger(Format(ColumnPattern, [I]), AListView.Columns[I].Width); except on ERegistryException do { ignore } else raise; end; finally Free; end; end; procedure dxSaveListViewSelection(AListView: TListView; ASelection: TList); var I: Integer; Item: TListItem; begin for I := 0 to AListView.Items.Count - 1 do begin Item := AListView.Items[I]; if Item.Selected then ASelection.Add(Item.Data); end; end; procedure dxRestoreListViewSelection(AListView: TListView; ASelection: TList); var I: Integer; Item: TListItem; begin for I := 0 to ASelection.Count - 1 do begin Item := AListView.FindData(0, ASelection[I], True, True); if Item <> nil then begin Item.Selected := True; if I = 0 then Item.MakeVisible(True); end; end; end; procedure CopyImages(ASourceHandle: HIMAGELIST; ADest: TCustomImageList); var ImageCount, ImageWidth, ImageHeight, I: Integer; Image, Mask: TBitmap; R: TRect; begin ADest.Clear; ImageCount := ImageList_GetImageCount(ASourceHandle); if ImageCount = 0 then Exit; ImageList_GetIconSize(ASourceHandle, ImageWidth, ImageHeight); ADest.Width := ImageWidth; ADest.Height := ImageHeight; // we need to copy all color depth and alpha channel information ADest.Handle := ImageList_Duplicate(ASourceHandle); ADest.Clear; {???} R := MakeRect(0, 0, ImageWidth, ImageHeight); Image := TBitmap.Create; try Image.Height := ImageHeight; Image.Width := ImageWidth; Mask := TBitmap.Create; try Mask.Monochrome := True; Mask.Height := ImageHeight; Mask.Width := ImageWidth; for I := 0 to ImageCount - 1 do begin with Image.Canvas do begin FillRect(R); ImageList_Draw(ASourceHandle, I, Handle, 0, 0, ILD_NORMAL); end; with Mask.Canvas do begin FillRect(R); ImageList_Draw(ASourceHandle, I, Handle, 0, 0, ILD_MASK); end; ADest.Add(Image, Mask); end; finally Mask.Free; end; finally Image.Free; end; end; procedure PlaceButtons(const AButtons: array of TButton; ABtnOffsetX, ARightOrigin, ATopOrigin: Integer); var DWP: HDWP; procedure PlaceButton(AButton: TButton; AOriginX, AOriginY: Integer); begin DWP := DeferWindowPos(DWP, AButton.Handle, 0, AOriginX, AOriginY, 0, 0, SWP_NOACTIVATE or SWP_NOOWNERZORDER or SWP_NOSIZE or SWP_NOZORDER); Control_UpdateBoundsRect(AButton, AOriginX, AOriginY, AButton.Width, AButton.Height); end; procedure ShiftButtons(Index, Shift: Integer); var OriginX, OriginY, I: Integer; begin OriginY := ATopOrigin; for I := High(AButtons) downto Index + 1 do begin OriginX := AButtons[I - Shift].Left; PlaceButton(AButtons[I], OriginX, OriginY); end; end; procedure OriginalPlaceButtons; var OriginX, OriginY, I: Integer; begin OriginX := ARightOrigin; OriginY := ATopOrigin; for I := Low(AButtons) to High(AButtons) do begin Dec(OriginX, AButtons[I].Width); if I > 0 then Dec(OriginX, ABtnOffsetX); PlaceButton(AButtons[I], OriginX, OriginY); end; end; procedure ReplaceButtons; var Found: Boolean; I, Count, StartIndex: Integer; begin StartIndex := 0; Count := 1; repeat Found := False; for I := StartIndex to High(AButtons) do if not AButtons[I].Visible then begin Found := True; Count := 1; while not AButtons[I + Count].Visible do Inc(Count); end; if Found then begin ShiftButtons(StartIndex, Count); Inc(StartIndex, Count); end; until not Found; end; procedure InvalidateButtons; var I: Integer; begin for I := Low(AButtons) to High(AButtons) do AButtons[I].Invalidate; end; begin DWP := BeginDeferWindowPos(High(AButtons) - Low(AButtons)+ 1); try OriginalPlaceButtons; ReplaceButtons; finally EndDeferWindowPos(DWP); InvalidateButtons; end; end; procedure dxAppendList(ASource, ADest: TList); var PrevCount: Integer; DestMem: PPointerList; begin PrevCount := ADest.Count; ADest.Count := ADest.Count + ASource.Count; ADest.Count := ADest.Count + ASource.Count; if ADest.Count <> 0 then begin DestMem := Pointer(Integer(ADest.List) + SizeOf(Pointer) * PrevCount); Move(ASource.List^, DestMem^, SizeOf(Pointer) * ASource.Count); end; end; procedure dxCopyList(ASource, ADest: TList); begin ADest.Count := ASource.Count; Move(ASource.List^, ADest.List^, SizeOf(Pointer) * ADest.Count); end; procedure dxShiftIntegerListValues(AList: TList; AValue: Integer); var I: Integer; begin with AList do for I := 0 to Count - 1 do List^[I] := Pointer(Integer(List^[I]) + AValue); end; function dxCheckStateImageIndexMap(AState: TCheckBoxState): Integer; const CheckBoxStateMap: array[TCheckBoxState] of Integer = (0, 1, 2); begin Result := 1 + CheckBoxStateMap[AState]; end; procedure dxCreateCheckMarkImages(AnImageList: TCustomImageList); const MaskColor: TColor = clFuchsia; procedure DrawCheckBox(ACanvas: TCanvas; const R: TRect; State: TCheckBoxState); const InteriorColors: array[Boolean] of TColor = (clWindow, clBtnFace); var C: TColor; begin with ACanvas do begin C := Font.Color; //frame Font.Color := clBtnShadow; DrawGlyph(Handle, R, CheckBottomRightArcInnerIndex); DrawGlyph(Handle, R, CheckTopLeftArcInnerIndex); //interior Font.Color := InteriorColors[State = cbGrayed]; DrawGlyph(Handle, R, CheckInteriorIndex); //checkmark if State in [cbChecked, cbGrayed] then begin Font.Color := clWindowText; DrawGlyph(Handle, R, CheckMarkIndex); end; Font.Color := C; end; end; var Bitmap: TBitmap; State: TCheckBoxState; R, CheckRect: TRect; Ch: Char; Size: TSize; begin Bitmap := TBitmap.Create; with Bitmap do try Width := AnImageList.Width; Height := AnImageList.Height; Canvas.Font.Name := 'Marlett'; Canvas.Font.Size := 10; Canvas.Font.Charset := SYMBOL_CHARSET; R := MakeRect(0, 0, Width, Height); Canvas.Brush.Color := MaskColor; Canvas.FillRect(R); AnImageList.AddMasked(Bitmap, clDefault); CheckRect := R; Ch := Chr(CheckBottomRightArcInnerIndex); Size := Canvas.TextExtent(Ch); InflateRect(CheckRect, -(R.Right - R.Left - Size.cX) div 2, -(R.Bottom - R.Top - Size.cY) div 2); for State := Low(TCheckBoxState) to High(TCheckBoxState) do begin Canvas.Brush.Style := bsSolid; Canvas.FillRect(R); Canvas.Brush.Style := bsClear; DrawCheckBox(Canvas, CheckRect, State); AnImageList.AddMasked(Bitmap, clDefault); end; finally Bitmap.Free; end; end; function dxPSDrawModeImages: TCustomImageList; procedure LoadImages; procedure LoadImage(B: TBitmap; const AResName: string); begin Bitmap_LoadFromResourceName(B, AResName); FDrawModeImages.AddMasked(B, clDefault); end; var B: TBitmap; begin B := TBitmap.Create; try LoadImage(B, IDB_DXPSDRAWMODE_STRICT); LoadImage(B, IDB_DXPSDRAWMODE_ODDEVEN); LoadImage(B, IDB_DXPSDRAWMODE_CHESS); LoadImage(B, IDB_DXPSDRAWMODE_BORROW); finally B.Free; end; end; begin if FDrawModeImages = nil then begin FDrawModeImages := TImageList.Create(nil); LoadImages; end; Result := FDrawModeImages; end; {$IFNDEF DELPHI5} procedure FreeAndNil(var Obj); var P: TObject; begin P := TObject(Obj); TObject(Obj) := nil; P.Free; end; {$ENDIF} function dxAllocatehWnd(AMethod: TWndMethod): HWND; begin {$IFDEF DELPHI6} Result := Classes.AllocatehWnd(AMethod); {$ELSE} Result := Forms.AllocatehWnd(AMethod); {$ENDIF} end; procedure dxDeallocatehWnd(AWnd: HWND); begin if IsWindow(AWnd) then {$IFDEF DELPHI6} Classes.DeallocatehWnd(AWnd); {$ELSE} Forms.DeallocatehWnd(AWnd); {$ENDIF} end; procedure dxRecreateWnd(AControl: TWinControl); begin TWinControlAccess(AControl).RecreateWnd; end; function MakeBounds(ALeft, ATop, AWidth, AHeight: Integer): TRect; begin with Result do begin Left := ALeft; Top := ATop; Right := ALeft + AWidth; Bottom := ATop + AHeight; end; end; function MakePoint(X, Y: Integer): TPoint; begin Result.X := X; Result.Y := Y; end; function MakeRect(ALeft, ATop, ARight, ABottom: Integer): TRect; begin with Result do begin Left := ALeft; Top := ATop; Right := ARight; Bottom := ABottom; end; end; function MakeRect(const ATopLeft, ABottomRight: TPoint): TRect; begin with Result do begin TopLeft := ATopLeft; BottomRight := ABottomRight; end; end; function TTagToInt(AValue: Integer ): Integer; begin Result := AValue; end; function TTagToObj(AValue: Integer ): TObject; begin Result := TObject(AValue); end; function TTagToClass(AValue: Integer ): TClass; begin Result := TClass(AValue); end; function MakeTTag(AValue: Integer): Integer ; begin Result := AValue; end; function MakeTTag(AValue: TObject): Integer ; begin Result := Integer(AValue); end; function MakeTTag(AValue: TClass): Integer ; begin Result := Integer(AValue); end; function Control_GetColor(AControl: TControl): TColor; begin Result := TControlAccess(AControl).Color; end; function Control_GetControlStyle(AControl: TControl): TControlStyle; begin Result := TControlAccess(AControl).ControlStyle; end; function Control_GetCtl3D(AControl: TWinControl): Boolean; begin Result := TWinControlAccess(AControl).Ctl3D; end; function Control_GetFont(AControl: TControl): TFont; begin Result := TControlAccess(AControl).Font; end; function Control_GetPopupMenu(AControl: TControl): TPopupMenu; begin Result := TControlAccess(AControl).PopupMenu; end; function Control_GetText(AControl: TControl): string; begin Result := TControlAccess(AControl).Text; end; procedure Control_SetParentBackground(AControl: TWinControl; Value: Boolean); begin {$IFDEF DELPHI7} TWinControlAccess(AControl).ParentBackground := Value; {$ENDIF} end; procedure Control_DoContextPopup(AControl: TControl; const Pt: TPoint; var AHandled: Boolean); begin AHandled := False; {$IFDEF DELPHI5} TControlAccess(AControl).DoContextPopup(Pt, AHandled); {$ENDIF} end; procedure Control_PaintWindow(AControl: TWinControl; DC: HDC); begin TWinControlAccess(AControl).PaintWindow(DC); end; procedure Control_SendCancelMode(AControl, ASender: TControl); begin TControlAccess(AControl).SendCancelMode(ASender); end; procedure Control_UpdateBoundsRect(AControl: TControl; const R: TRect); begin TControlAccess(AControl).UpdateBoundsRect(R); end; procedure Control_UpdateBoundsRect(AControl: TControl; ALeft, ARight, AWidth, AHeight: Integer); begin Control_UpdateBoundsRect(AControl, MakeBounds(ALeft, ARight, AWidth, AHeight)); end; procedure PopupMenu_DoPopup(APopupMenu: TPopupMenu); begin {$IFDEF DELPHI5} TPopupMenuAccess(APopupMenu).DoPopup(APopupMenu); {$ELSE} if Assigned(APopupMenu.OnPopup) then APopupMenu.OnPopup(APopupMenu); {$ENDIF} end; function RichEdit_GetBorderStyle(AControl: TCustomRichEdit): TBorderStyle; begin Result := TCustomRichEditAccess(AControl).BorderStyle; end; function RichEdit_GetLines(AControl: TCustomRichEdit): TStrings; begin Result := TCustomRichEditAccess(AControl).Lines; end; procedure Bitmap_LoadFromResourceName(ABitmap: TBitmap; const AResName: string; ABaseName: string = 'dxPSImgs'); begin ABitmap.LoadFromResourceName(hInstance, AResName); end; procedure Icon_LoadFromResourceName(AIcon: TIcon; const AResName: string; ABaseName: string = 'dxPSImgs'); var Bitmap: TBitmap; ImageList: TImageList; begin Bitmap := TBitmap.Create; try Bitmap_LoadFromResourceName(Bitmap, AResName); ImageList := TImageList.CreateSize(Bitmap.Width, Bitmap.Height); try ImageList.AllocBy := 1; ImageList.AddMasked(Bitmap, clDefault); AIcon.Handle := ImageList_GetIcon(ImageList.Handle, 0, ILD_NORMAL); finally ImageList.Free; end; finally Bitmap.Free; end; end; {$IFNDEF DELPHI6} type PPointer = ^Pointer; {$ENDIF} function IsDelphiObject(AData: DWORD): Boolean; var P: Pointer; SelfPtr: Pointer; begin Result := False; P := Pointer(AData); if IsBadReadPtr(P, SizeOf(Pointer)) then Exit; P := PPointer(P)^; if IsBadReadPtr(P, SizeOf(Pointer)) then Exit; SelfPtr := Pointer(Integer(P) + vmtSelfPtr); if IsBadReadPtr(SelfPtr, SizeOf(Pointer)) then Exit; SelfPtr := PPointer(SelfPtr)^; Result := P = SelfPtr; end; initialization CoInitialize(nil); PopulateShellImages(True); finalization FreeAndNil(FDrawModeImages); if FPatternBrush <> 0 then Windows.DeleteObject(FPatternBrush); FreeAndNil(FTrueTypeFonts); FreeAndNil(FNonTrueTypeFonts); FreeAndNil(FShellLargeImages); FreeAndNil(FShellSmallImages); CoUninitialize; end.