unit HandleForm;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  THandleFrm = class(TForm)
    CreateBtn: TButton;
    CloseOwnerBtn: TButton;
    CloseNonOwnerBtn: TButton;
    procedure CreateBtnClick(Sender: TObject);
    procedure CloseOwnerBtnClick(Sender: TObject);
    procedure CloseNonOwnerBtnClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    Mutex: THandle;
  end;

var
  HandleFrm: THandleFrm;

implementation

uses HandleThreads;

{$R *.DFM}

procedure THandleFrm.CreateBtnClick(Sender: TObject);

var
  NewThread: THandleThread;

begin
  Mutex := CreateMutex(nil, false, nil);
  WaitForSingleObject(Mutex, INFINITE);
  NewThread := THandleThread.Create(false);
  NewThread := THandleThread.Create(false);
  ShowMessage('Threads Created.');
end;

procedure THandleFrm.CloseOwnerBtnClick(Sender: TObject);
begin
  CloseHandle(Mutex);
end;

procedure THandleFrm.CloseNonOwnerBtnClick(Sender: TObject);
begin
  ReleaseMutex(Mutex);
  CloseHandle(Mutex);
end;

end.

unit HandleThreads;

interface

uses
  Classes, Windows, SysUtils, Dialogs;

type
  THandleThread = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;
  end;

implementation

uses HandleForm;

procedure THandleThread.Execute;

var
  RetVal: integer;

begin
  RetVal := WaitForSingleObject(HandleFrm.Mutex, INFINITE);
  case RetVal of
    WAIT_OBJECT_0: ShowMessage('Unblocked: WAIT_OBJECT_0');
    WAIT_ABANDONED: ShowMessage('Unblocked: WAIT_ABANDONED');
    WAIT_TIMEOUT: ShowMessage('Unblocked: WAIT_TIMEOUT');
  else
    ShowMessage('Unblocked. Unknown return code.');
  end;
end;

end.