Win32/COM Error checking and handling

I wrote following function to help me out debug my code.
basically when there is an error, be it COM or Win32 it shows me a message box indicating where the error occured and what is the error code formated into a string.

Can you please review this code and tell how can I improve error handling and to possibly show more information on the error.

You can just include this header anywhere you need to be informed about error:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#pragma once
#include <comdef.h>
#include <string>
#include <codecvt>
#include <windows.h>

// exclude long file names, show only unit file name
#define __FILENAME__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)

// helper function to convert string to wide string
std::wstring stringToWstring(const std::string& t_str)
{
	//setup converter
	typedef std::codecvt_utf8<wchar_t> convert_type;
	std::wstring_convert<convert_type, wchar_t> converter;

	//use converter (.to_bytes: wstr->str, .from_bytes: str->wstr)
	return converter.from_bytes(t_str);
}

// error info function, show the message box about error and format the message
void ShowError(HWND hWnd, const char* file, int line, HRESULT hr = S_OK)
{
#ifdef UNICODE
	std::wstring error_type = L"Rutime Error";
	std::wstring error_message =
		L"File:\t" + stringToWstring(file) +
		L"\r\nLine:\t" + std::to_wstring(line) + L"\r\nError:\t";
#else
	std::string error_type = "Rutime Error";
	std::string error_message = "File:\t";
	error_message.append(file);
	error_message.append("\r\nLine:\t");
	error_message.append(std::to_string(line));
	error_message.append("\r\nError:\t");
#endif // UNICODE

	// If HRESULT is omited or S_OK
	// format last error code message
	if (hr == S_OK)
	{
		LPVOID lpBuff = nullptr;

		DWORD dwChars = FormatMessage(
			FORMAT_MESSAGE_ALLOCATE_BUFFER |
			FORMAT_MESSAGE_FROM_SYSTEM,
			nullptr,
			GetLastError(),
			0,
			reinterpret_cast<LPTSTR>(&lpBuff),
			0,
			nullptr);
				
		// If the function succeeds, the return value is
		// the number of TCHARs stored in the output buffer
		if (dwChars)
		{
			error_message.append(reinterpret_cast<LPCTSTR>(lpBuff));
		}
		else // If the function fails, the return value is zero
		{
			error_message.append(TEXT("Unknown Error\t"));
#ifdef  UNICODE
			error_message.append(std::to_wstring(GetLastError()));
#else
			error_message.append(std::to_string(GetLastError()));
#endif //  UNICODE

		}
                // free the buffer allocaed by FormatMessage
		LocalFree(lpBuff);
	}
	else // Format com error code into a message
	{
		_com_error err(hr);
		error_message.append(err.ErrorMessage());
	}

	// Play the sound and show error message
	MessageBeep(MB_ICONERROR);
	MessageBox(hWnd,
		error_message.c_str(),
		error_type.c_str(), MB_OK | MB_ICONERROR);
}



Now let's assume following code issues an error of type HRESULT, then show the error in string readable form using messagebox.

1
2
3
4
5
6
7
8
9
10
	HRESULT hr = LoadResourceBitmap(pRenderWindow,
		pWICFactory,
		MAKEINTRESOURCE(IDB_BITMAP1),
		RT_BITMAP,
		&pBitmat);

if(FAILED(hr)
{
          ShowError(m_hwnd, __FILENAME__, __LINE__, hr);
}


Or for example following code for Win32 error type we exclude HRESULT.

1
2
3
4
5
	// Locate the resource.
	auto imageResHandle = FindResource(hInstance, resourceName, resourceType);

	if (!imageResHandle) // show the error
		ShowError(m_hwnd, __FILENAME__, __LINE__);

Last edited on
Registered users can post here. Sign in or register to post.