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

CrossVcl automatically addeds CROSSVCL define to all projects for non Windows platform. In some cases you have to separate Windows-only code and CrossVcl code. We suggest to cover CrossVCL code by CROSSVCL condition.

{$IFNDEF CROSSVCL}

// Windows-only code

{$ELSE}

// CrossVcl code

{$ENDIF}

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);

PAnsiChar

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.

{$IFDEF MSWINDOWS}

BDC := CreateCompatibleDC(DC);

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

SelectObject(BDC, BMP);

{$ELSE}

BDC := DC;

{$ENDIF}

// Common rendering

Render(BDC);

{$IFDEF MSWINDOWS}

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

{$ENDIF}

{$IFDEF MSWINDOWS}

DeleteObject(BMP);

DeleteDC(BDC);

{$ENDIF}

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);

try

 Form.ShowModal;

finally

 Form.DisposeOf;

end;

ClearRectWithAlpha

CrossVcl has easy to use extra function to clear 32-bit rect using color and alpha (for example to make 32-bitmap fully transparent). This function declared at Winapi.Windows.pas.

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

FillRectWithAlpha

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;

To clear rect with alpha on destination call SetBkMode(BK_CLEAR) before.

FillGradientRect

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.

MYCURSOR RCDATA "Cursor.cur"

MYICON RCDATA "Icon.ico"

Enable Scrolling at TCustomControl

CrossVcl checks for WS_VSCROLL or WS_HSCROLL style when window is creating to enable scrolling support. In some cases control doesn't have this styles, but works like scrolled controls. For this particular purpose CrossVcl has additional extra styles - WS_EX_SCROLLING. How to use:

{$IFNDEF MSWINDOWS}

ExStyle := ExStyle or WS_EX_SCROLLING;

{$ENDIF}