DLL substitution

All CrossVcl APIs concentrated in one shared library, to allows linker correctly link application all Windows APIs should use link to CrossVcl runtime. There is special constant in Windows unit - CrossVclLib.

function GetRandomRgn(DC: HDC; Rgn: HRGN; iNum: Integer): Integer; stdcall;

 external {$IFDEF MSWINDOWS} 'GDI32.DLL' {$ELSE} CrossVclLib {$ENDIF};

Separating Windows and CrossVcl code

In some cases you have to separate Windows-only code and CrossVcl code. We suggest to cover Windows-only code by MSWINDOWS directive.


// Windows-only code


// CrossVcl code


MakeObjectInstance and AllocateHWnd

Delphi’s RTL contains this functions only on Windows, but CrossVcl reimplements they for macOS and Linux. All this function locate in Winapi.Messages unit. To use it, just remove “Classes.” from calls.

Inst := Classes.MakeObjectInstance(Method);

should replaced with:

Inst := MakeObjectInstance(Method);


Delphi Linux compiler doesn’t support AnsiString, but CrossVcl has an alias for AnsiString and PAnsiChar. If you want to use this types, just add Winapi.Windows unit to uses section.

Missing APIs

If you code heavy uses non-UI Windows API, try to replace it with high level cross platform routines from RTL.

Missing UI APIs

If you found unimplemented API’s which related to UI please create issue on our bug-tracker and we will try to resolve it.

Double Buffering

On Windows there is common way to use bitmaps for double buffering, which is useless on macOS and Linux. Both this OS uses own double buffering for every windows. We strongly recommend avoid using bitmap for double buffering, it only can brings issues with HDPI and decrease performance. VCL supports modern double buffering (DWM) by default and CrossVcl covers it. You also can cover windows double buffering code by IFDEFs.


BDC := CreateCompatibleDC(DC);

BMP := CreateCompatibleBitmap(DC, Width, Height);

SelectObject(BDC, BMP);


BDC := DC;


// Common rendering



BitBlt(DC, 0, 0, Width, Height, BDC, 0, 0, SRCCOPY);






Use non-object values in TStrings

In VCL there is common way to store non-object values at TObject in string list, which bring an error on NEXTGEN compiler (ARC-enabled). To keep compatibility CrossVcl has few special functions to convert non-object value to TObject and vise vera. Internally this functions create real object and allows to use it in ARC-enabled environment.

// Store integer value as object

Objects[I] := __TObject(IntValue);

// Read object value as integer

IntValue := __Int(Objects[i]);

DisposeOf instead of Free

All new Delphi compilers (Linux64 and maybe new macOS-64) use Automatic Reference Counting for all objects. See more at Embarcadero Docs. But because VCL isn’t designed to use ARC-model you can get some difference in object live cycle. For example VCL form contains reference in many other object which makes impossible to destroy form, in this case you may use DisposeOf instead of Free.

Form := TForm1.Create(Self);







CrossVcl has easy to use extra function to fill semi-transparency rect. This function declared at Winapi.Windows.pas.

procedure FillRectWithAlpha(hDC: HDC; lprc: TRect; Color: ColorRef; Alpha: byte); cdecl;


CrossVcl has easy to use extra function to fill rect with gradient. This function declared at Winapi.Windows.pas.

procedure FillGradientRect(hDC: HDC; lprc: TRect; Color1, Color2: ColorRef; Horizontal: Boolean); cdecl;

Cursor and Icon Resources

Non Windows Delphi compiler can't corretly handle icon and cursor resources. To be able use of LoadCursor and LoadIcon APIs be sure that you store icon and cursor as RCDATA.