Invoking WinAPI Functions in Delphi using Dot Notation

Windows API functions are declared in structured programming style.

For example consider classical example of using critical sections:

procedure Test;
var 
  CS: TCriticalSection;
begin
  InitializeCriticalSection(CS);
  try
    EnterCriticalSection(CS);
    try
      //somecode
    finally
      LeaveCriticalSection(CS);
    end;
  finally
    DeleteCriticalSection(CS);
  end;
end;

Now consider the example rewritten in "object-oriented" Windows API using dot notation:

procedure Test;
var
  NewCS: TNewCriticalSection;
begin
  NewCS.Initialize;
  try
    NewCS.Enter;
    try
      //somecode
    finally
      NewCS.Leave;
    end;
  finally
    NewCS.Delete;
  end;
end;

Bespoke the code is easier to read, the benefit is CodeInsight works nicely — type "NewCS." and press Control+Space…

Below unit implements new "object-oriented" Windows API w/ dot notation support:

unit NewWindows;

interface

uses Windows;

{$HINTS OFF}
type
  TNewCriticalSection = object
  private
    FOldCriticalSection: TRTLCriticalSection;
  public
    procedure Initialize; stdcall;
    procedure Delete; stdcall;
    procedure Enter; stdcall;
    procedure Leave; stdcall;
  end;
{$HINTS ON}
  
implementation

procedure TNewCriticalSection.Initialize; 
    external kernel32 name 'InitializeCriticalSection';
procedure TNewCriticalSection.Delete; 
    external kernel32 name 'DeleteCriticalSection';
procedure TNewCriticalSection.Enter; 
    external kernel32 name 'EnterCriticalSection';
procedure TNewCriticalSection.Leave; 
    external kernel32 name 'LeaveCriticalSection';

end. 

The trick is that stack layout of TNewCriticalSection methods is identical to what WinAPI critial section functions expect. Thus we can declare implementations of TNewCriticalSection methods as external from kernel32.dll.

Comments

Delphi 2009+ version

Delphi 2009+ version:

unit NewWindows;

interface

uses Windows;

type
  TRTLCriticalSectionHelper = record helper for TRTLCriticalSection
  public
    procedure Initialize; stdcall;
    procedure Delete; stdcall;
    procedure Enter; stdcall;
    procedure Leave; stdcall;
  end;

implementation

procedure TRTLCriticalSectionHelper.Initialize;
    external kernel32 name 'InitializeCriticalSection';
procedure TRTLCriticalSectionHelper.Delete;
    external kernel32 name 'DeleteCriticalSection';
procedure TRTLCriticalSectionHelper.Enter;
    external kernel32 name 'EnterCriticalSection';
procedure TRTLCriticalSectionHelper.Leave;
    external kernel32 name 'LeaveCriticalSection';

end.

Post new comment

The content of this field is kept private and will not be shown publicly.