2009-03-21 28 views
21

Ho un problema nell'usare un componente di terze parti in Delphi 2006 (anche Delphi 7), in cui viene visualizzato un "Errore non specificato" quando si esegue una chiamata di funzione a quel componente. Hai un codice di esempio che utilizza GetLastError e FormatMessage in Delphi, che mi consentirebbe di accedere a più informazioni sull'errore? TIA :)Qual è l'uso corretto di GetLastError e FormatMessage in Delphi?

risposta

48

C'è una funzione di supporto integrata in Delphi: SysErrorMessage. È essenzialmente un wrapper per FormatMessage, ma molto più semplice da utilizzare nel tuo caso. Basta fornire il codice di errore per il quale è necessaria una descrizione testuale.

Per esempio si può usare questo per visualizzare l'ultimo errore:

ShowMessage(SysErrorMessage(GetLastError)) 

Se si vuole sollevare un'eccezione con questo messaggio, è ancora più semplice:

RaiseLastOSError; 

Importante: Fare sicuro che non ci sia una chiamata API aggiuntiva tra la funzione malfunzionante e la vostra chiamata di GetLastError, altrimenti l'ultimo errore verrà ripristinato.

+0

Sta arrivando, sta arrivando :) –

+3

Nota: L'utilizzo di una stringa di risorse comporterà una chiamata API, quindi perderai il codice di errore! – dummzeuch

7

Mentre DR è corretto, c'è un problema con questo approccio: non consente di specificare il contesto in cui si è verificato l'errore. Mai visto l'errore "Una funzione API fallita." senza essere più saggio quale funzione fosse e dove si è verificato?

Ecco perché ho scritto le RaiseLastOsErrorEx e Win32CheckEx funzioni:

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; 

(Fanno parte di u_dzMiscUtils unità della mia biblioteca dzLib disponibile qui: https://sourceforge.net/p/dzlib/code/HEAD/tree/dzlib/trunk/src/u_dzOsUtils.pas

+0

Grazie mille per il codice aggiuntivo e i collegamenti :) +1 –

+0

Un framework di eccezioni generali come madExcept sarebbe ancora meglio. –

+0

@DR: Sì, forse, ma non era questa la domanda. – dummzeuch

Problemi correlati