Converting a CInternetException to a printable string

I have recently been doing some Internet programming with the MFC classes, such as CInternetSession. One problem I had to deal with was the fact that these classes will sometimes throw exceptions, and I wanted a printable representation of the error. A bit of forensics showed that wininet.dll contains a MESSAGETABLE resource, although to discover this you have to know that a MESSAGETABLE is resource type 11. So I set up a function to convert WinInet error codes, as encoded in the CInternetException, to a CString.

For example, the OpenURL operation can throw an exception. To handle this, I use a TRY/CATCH construct:

CInternetSession session;
CStdioFile * file;
TRY {
 file = session.OpenURL(URL);
 }
 CATCH(CInternetException, e)
 {
 CString s = getInetError(e->m_dwError);
 // here I add the error message to a CListBox
 c_Status.AddString(s);
 return;
 }

The function getInetError uses FormatMessage to convert the message

CString getInetError(DWORD err)
 {
 HANDLE h = ::GetModuleHandle(_T("WinINet.dll"));
 if(h != NULL)
	{ /* got module */
	 LPTSTR p;
	 if(::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
			 FORMAT_MESSAGE_FROM_HMODULE,
			 (LPCVOID)h,
			 err,
			 0, // default language
			 (LPTSTR)&p,
			 0,
			 NULL) != 0)
	 { /* format succeeded */
	 CString s(p);
	 s.Replace(_T("\r\n"), _T(""));
	 return s;
	 } /* format succeeded */
	} /* got module */
 CString s;
 s.Format(_T("%d"), err);
 return s;
 } // getInetError

The explanation of the code is as follows:

The WinInet.dll module is already mapped into the address space (else I would not see the exception being thrown or otherwise have a CInternetException. So I use GetModuleHandle (instead of LoadLibrary, which would increment the reference count) to get the module handle. If this is successful, I call FormatMessage using FORMAT_MESSAGE_FROM_HMODULE and this handle to format the error code. If the error code is a valid WinINet error, FormatMessage will succeed. In this case, I want to remove the gratuitous newline that FormatMessage insists on appending, so I replace "\r\n" with the empty string.

If the module handle cannot be obtained, or the FormatMessage fails, the code drops down to formatting the error code as a decimal integer. A LoadString operation could be used to get a nicer formatting string from the STRINGTABLE, e.g.,

CString fmt;
fmt.LoadString(IDS_NICE_ERROR_MESSAGE); // "WinINet error %d"
CString s;
s.Format(fmt, err);
return s;

[Dividing Line Image]

The views expressed in these essays are those of the author, and in no way represent, nor are they endorsed by, Microsoft.

Send mail to newcomer@flounder.com with questions or comments about this web site.
Copyright ゥ 1999-2003 The Joseph M. Newcomer Co. All Rights Reserved.
Last modified: May 14, 2011

AltStyle によって変換されたページ (->オリジナル) /