2009-03-21 4 views
21

Tengo un problema al usar un componente de terceros en Delphi 2006 (también Delphi 7), en el que obtengo un "Error no especificado" al ejecutar una llamada a función a ese componente. ¿Tiene un código de ejemplo que utiliza GetLastError y FormatMessage en Delphi, que me permitiría acceder a más información sobre el error? TIA :)¿Cuál es el uso correcto de GetLastError y FormatMessage en Delphi?

Respuesta

48

Hay una función auxiliar integrada en Delphi: SysErrorMessage. Básicamente es un contenedor para FormatMessage, pero mucho más simple de usar en su caso. Simplemente proporcione el código de error para el que necesita una descripción textual.

Por ejemplo, usted puede usar esto para mostrar el último error:

ShowMessage(SysErrorMessage(GetLastError)) 

Si desea elevar una excepción con este mensaje, es aún más simple:

RaiseLastOSError; 

Importante: Hacer Asegúrese de que no haya una llamada API adicional entre la función anómala y su llamada al GetLastError; de lo contrario, se restablecerá el último error.

+0

Ya viene, ya viene :) –

+3

Nota: El uso de una cadena de recursos dará como resultado una llamada API, ¡por lo que perderá el código de error! – dummzeuch

7

Si bien DR es correcta, hay un problema con este enfoque: no le permite especificar el contexto en el que se produjo el error. Alguna vez has visto el error "Falló una función API". sin ser más sabio de qué función era y dónde sucedió?

Es por eso que escribí las RaiseLastOsErrorEx y Win32CheckEx funciones:

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; 

(Son parte de u_dzMiscUtils unitarios de mi biblioteca dzLib disponible aquí: https://sourceforge.net/p/dzlib/code/HEAD/tree/dzlib/trunk/src/u_dzOsUtils.pas

+0

Muchas gracias por el código adicional y los enlaces :) +1 –

+0

Un marco de excepción general como madExcept sería incluso mejor. –

+0

@DR: Sí, tal vez, pero esa no era la pregunta. – dummzeuch

Cuestiones relacionadas