Thanks Paul.
Here's your confirmation that the FormatMessage syntax you gave me is working.
I will create a FAQ for that tonight.
In the meantime, here is the function I have defined.
FUNCTION GetError
* Returns an error message from WIN32API
* expN1 Error message from WIN32API
PARAMETER tnError
DECLARE INTEGER GetLastError IN WIN32API
DECLARE INTEGER FormatMessage IN WIN32API;
INTEGER, INTEGER, INTEGER, INTEGER, STRING, INTEGER, INTEGER
LOCAL lnError,lcError
* If we pass an error, otherwise get it from GetLastError()
IF TYPE('tnError')='N'
lnError=tnError
ELSE
lnError=GetLastError()
ENDIF
lcError=SPACE(255)
FormatMessage(4096,0,lnError,0,@lcError,255,0)
MESSAGEBOX('Error: '+ALLTRIM(STR(lnError))+CHR(13)+CHR(13)+lcError,16)