//*******************************************************
//
//    Copyright © 1995-2002 by Lucian Radulescu
//    mailto  :  lucian@ez-delphi.com
//    http    :  http://www.ez-delphi.com
//
//*******************************************************

unit CheckAPI;

{$I ALLLIB.DEF}
{$WARNINGS OFF}
interface

uses
Windows, SysUtils;

type
ESysError = class( Exception );

procedure DisplaySysError; overload;
procedure DisplaySysError( errOk: DWORD ); overload;

function  Check( Value: THandle; errOk: DWORD = ERROR_SUCCESS ): THandle; overload;
function  Check( Value: Bool;    errOk: DWORD = ERROR_SUCCESS ): Bool; overload;
function  Check( Value: Pointer; errOk: DWORD = ERROR_SUCCESS ): Pointer; overload;

function  Check( Value: Bool; const errOk: array of DWORD ): Bool; overload;

function  Check_API( Value: Cardinal ): Cardinal; overload;
function  Check_API( Value: Bool ): Cardinal; overload;
function  Check_API( Value: Pointer ): Pointer; overload;

implementation

procedure DisplaySysError;
var
ErrorCode : Integer;
  Buf       : array [Byte] of Char;
  S         : PChar;
begin
ErrorCode := GetLastError;
try
FillChar( Buf, SizeOf(Buf), #0 );
if ( ErrorCode <> 0 ) and
( FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, nil, ErrorCode,
                        LOCALE_USER_DEFAULT, Buf, sizeof( Buf ), nil ) <> 0 ) then
begin
S := StrEnd( Buf )-1;
while S^ < #32 do begin
S^ := #0;
        Dec( S );
end;
raise ESysError.Create( Buf );
end
else
raise ESysError.Create( 'Out of resources' );
except
on E: Exception do
if not IsConsole then raise
else WriteLn( E.Message );
end;
end;

procedure DisplaySysError( errOk: DWORD );
begin
if GetLastError <> errOk then DisplaySysError;
end;

function Check( Value: THandle; errOk: DWORD = ERROR_SUCCESS ): THandle;
begin
if Value = INVALID_HANDLE_VALUE then DisplaySysError( errOk )
else Result := Value;
end;

function Check( Value: Bool; errOk: DWORD = ERROR_SUCCESS): Bool;
begin
Result := False;
if not Value then DisplaySysError( errOk )
else Result := Value;
end;

function Check( Value: Bool; const errOk: array of DWORD ): Bool;
var
ErrorCode, idx: Integer;
begin
Result := False;
if Value then Result := Value
else
begin
ErrorCode := GetLastError;
for idx := Low(errOk) to High(errOk) do
if errOk[idx] = ErrorCode then Exit;
for idx := Low(errOk) to High(errOk) do
if errOk[idx] <> ErrorCode then
DisplaySysError;
end;
end;

function Check( Value: Pointer; errOk: DWORD = ERROR_SUCCESS ): Pointer;
begin
if Value = nil then DisplaySysError( errOk )
else Result := Value;
end;

function Check_API( Value: Cardinal ): Cardinal;
begin
if Value = 0 then DisplaySysError
else Result := Value;
end;

function Check_API( Value: Bool ): Cardinal;
begin
if not Value then DisplaySysError
else Result := Cardinal ( Value );
end;

function Check_API( Value: Pointer ): Pointer;
begin
if Value = nil then DisplaySysError
else Result := Value;
end;

end.