# FormatMessage not working for HRESULTs returned by Direct3D 11

I am using Windows 7 x64 and Visual Studio 17 (v15.9.7).

Say I try to create a swap chain using IDXGIFactory2::CreateSwapChainForHwnd and pass in DXGI_SCALING_NONE. I will get the following message in debug output (if I have enabled Direct3D debugging):

DXGI ERROR: IDXGIFactory::CreateSwapChain: DXGI_SCALING_NONE is only supported on Win8 and beyond. DXGI_SWAP_CHAIN_DESC{ SwapChainType = ..._HWND, BufferDesc = DXGI_MODE_DESC1{Width = 816, Height = 488, RefreshRate = DXGI_RATIONAL{ Numerator = 0, Denominator = 1 }, Format = B8G8R8A8_UNORM, ScanlineOrdering = ..._UNSPECIFIED, Scaling = ..._UNSPECIFIED, Stereo = FALSE }, SampleDesc = DXGI_SAMPLE_DESC{ Count = 1, Quality = 0 }, BufferUsage = 0x20, BufferCount = 2, OutputWindow = 0x0000000000290738, Scaling = ..._NONE, Windowed = TRUE, SwapEffect = ..._FLIP_SEQUENTIAL, AlphaMode = ..._UNSPECIFIED, Flags = 0x0 } [ MISCELLANEOUS ERROR #175: ]


The function returns 0x887a0001 in form of a HRESULT. If I put @err,hr in the watch window, I get a nice error message there:

ERROR_MOD_NOT_FOUND : The specified module could not be found.


However, if I pass this HRESULT to FormatMessage, it just puts NULL in the output and returns 0. @err,hr helpfully informs me that the new error is ERROR_MR_MID_NOT_FOUND : The system cannot find message text for message number 0x%1 in the message file for %2.

My questions are:

1. Why is FormatMessage not giving me right error string (the one starting with ERROR_MOD_NOT_FOUND...)?
2. Where is Visual Studio getting these pretty error strings from?
3. Can I get them too? Who do I pay?

PS. I am using the Windows 10 SDK version of DX11, not the older DirectX SDK version. Thus, I can't really link to dxerr.lib either.

This is the code that is used to print the error message:

LPTSTR error_text = NULL;
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
hr,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&error_text, 0,
NULL);

• docs.microsoft.com/en-gb/windows/desktop/direct3ddxgi/… - 0x887A0001 is DXGI_ERROR_INVALID_CALL, not ERROR_MOD_NOT_FOUND; your watch window is not returning the correct error either. – Maximus Minimus Feb 19 '19 at 16:23
• @MaximusMinimus Why is that? Microsoft seems to be very vehement that I should be using FormatMessage instead of legacy DXGetErrorMessage, etc. Are they wrong? Or has the right way to do things changed again? – strNOcat Feb 20 '19 at 1:58

## 1 Answer

TL;DR: The short answer is that you should be using FormatMessage, but you should also be using Windows 8 or later. With Windows 7, the OS was never updated to include the DirectX error messages in FormatMessage.

In my blog post on replacing the legacy DXERR library, I try using FormatMessage and if that fails fallback to the local list for cases like Windows 7.

You are using the DirectX 11.1 Runtime which is partially supported for Windows 7 Service Pack 1 per Microsoft Docs. That page explicitly states:

IDXGIFactory2::CreateSwapChainForHwnd takes a DXGI_SWAP_CHAIN_DESC1 structure, which has a field for Scaling. DXGI_SCALING_NONE is not supported on Windows 7 with the platform update and causes CreateSwapChainForHwnd to return DXGI_ERROR_INVALID_CALL when called.