Как правильно использовать GetLastError и FormatMessage в Delphi? - PullRequest
22 голосов
/ 21 марта 2009

У меня проблема с использованием стороннего компонента в Delphi 2006 (также Delphi 7), в котором я получаю «Неуказанную ошибку» при выполнении вызова функции для этого компонента. У вас есть пример кода, который использует GetLastError и FormatMessage в Delphi, который позволил бы мне получить доступ к дополнительной информации об ошибке? TIA:)

Ответы [ 2 ]

52 голосов
/ 21 марта 2009

В Delphi есть встроенная вспомогательная функция: SysErrorMessage. По сути, это обертка для FormatMessage, но ее гораздо проще использовать в вашем случае. Просто введите код ошибки, для которого необходимо текстовое описание.

Например, вы можете использовать это для отображения последней ошибки:

ShowMessage(SysErrorMessage(GetLastError))

Если вы хотите вызвать исключение с помощью этого сообщения, это даже проще:

RaiseLastOSError;

Важно : убедитесь, что между ошибкой функции и вашим вызовом GetLastError нет дополнительных вызовов API, в противном случае последняя ошибка будет сброшена.

7 голосов
/ 13 июля 2009

Хотя DR правильно, есть проблема с этим подходом: он не позволяет вам указать контекст, в котором произошла ошибка. Когда-либо видел ошибку "Ошибка API-функции". без мудрости, какая это была функция и где это произошло?

Вот почему я написал функции RaiseLastOsErrorEx и Win32CheckEx:

procedure RaiseLastOsErrorEx(const _Format: string);
begin
  RaiseLastOsErrorEx(GetLastError, _Format);
end;

procedure RaiseLastOsErrorEx(_ErrorCode: integer; _Format: string); overload;
var
  Error: EOSError;
begin
  if _ErrorCode <> ERROR_SUCCESS then
    Error := EOSError.CreateFmt(_Format, [_ErrorCode, SysErrorMessage(_ErrorCode)])
  else
    Error := EOsError.CreateFmt(_Format, [_ErrorCode, _('unknown OS error')]);
  Error.ErrorCode := _ErrorCode;
  raise Error;
end;

function GetLastOsError(out _Error: string; const _Format: string = ''): DWORD;
begin
  Result := GetLastOsError(GetLastError, _Error, _Format);
end;

function GetLastOsError(_ErrCode: integer; out _Error: string; const _Format: string = ''): DWORD;
var
  s: string;
begin
  Result := _ErrCode;
  if Result <> ERROR_SUCCESS then
    s := SysErrorMessage(Result)
  else
    s := _('unknown OS error');
  if _Format <> '' then
    try
      _Error := Format(_Format, [Result, s])
    except
      _Error := s;
    end else
    _Error := s;
end;

function Win32CheckEx(_RetVal: BOOL; out _ErrorCode: DWORD; out _Error: string;
  const _Format: string = ''): BOOL;
begin
  Result := _RetVal;
  if not Result then
    _ErrorCode := GetLastOsError(_Error, _Format);
end;

(Они являются частью модуля u_dzMiscUtils моей библиотеки dzLib, доступного здесь: https://sourceforge.net/p/dzlib/code/HEAD/tree/dzlib/trunk/src/u_dzOsUtils.pas

...