unit HandleForm;
 
interface
 
uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 StdCtrls;
 
type
 THandleFrm = class(TForm)
 CreateBtn: TButton;
 CloseOwnerBtn: TButton;
 CloseNonOwnerBtn: TButton;
 RelBtn: TButton;
 procedure CreateBtnClick(Sender: TObject);
 procedure CloseOwnerBtnClick(Sender: TObject);
 procedure CloseNonOwnerBtnClick(Sender: TObject);
 procedure RelBtnClick(Sender: TObject);
 private
 { Private declarations }
 public
 { Public declarations }
 Semaphore: THandle;
 end;
 
var
 HandleFrm: THandleFrm;
 
implementation
 
uses HandleThreads;
 
{$R *.DFM}
 
procedure THandleFrm.CreateBtnClick(Sender: TObject);
 
begin
 Semaphore := CreateSemaphore(nil, 1, 1, nil);
 WaitForSingleObject(Semaphore, INFINITE);
 THandleThread.Create(false);
 THandleThread.Create(false);
 ShowMessage('Hilos creados.');
end;
 
procedure THandleFrm.CloseOwnerBtnClick(Sender: TObject);
begin
 CloseHandle(Semaphore);
end;
 
procedure THandleFrm.CloseNonOwnerBtnClick(Sender: TObject);
begin
 ReleaseSemaphore(Semaphore, 1, nil);
 CloseHandle(Semaphore);
end;
 
procedure THandleFrm.RelBtnClick(Sender: TObject);
begin
 ReleaseSemaphore(Semaphore, 1, nil);
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.Semaphore, 10000);
 case RetVal of
 WAIT_OBJECT_0: ShowMessage('Desbloqueado: WAIT_OBJECT_0');
 WAIT_ABANDONED: ShowMessage('Desbloqueado: WAIT_ABANDONED');
 WAIT_TIMEOUT: ShowMessage('Desbloqueado: WAIT_TIMEOUT');
 else
 ShowMessage('Desbloqueado. Cdigo de respuesta desconocido.');
 end;
end;
 
end.