Commit f4450a4d authored by Administrator's avatar Administrator
Browse files

add graphic exception handling

parent bd929e85
This diff is collapsed.
This diff is collapsed.
DX_CHAR strBufferLine[128];
DX_CHAR strBufferError[256];
DX_CHAR strBuffer[BUFFER_SIZE];
DX_SPRINTF_S( strBufferLine, 128, DX_STR_WRAP("%lu"), dwLine );
if( strFile )
{
DX_SPRINTF_S( strBuffer, BUFFER_SIZE, DX_STR_WRAP(STR_FMT_SPEC "(" STR_FMT_SPEC "): "), strFile, strBufferLine );
DX_OUTPUTDEBUGSTRING( strBuffer );
}
size_t nMsgLen = (strMsg) ? DX_STRNLEN_S( strMsg, 1024 ) : 0;
if( nMsgLen > 0 )
{
DX_OUTPUTDEBUGSTRING( strMsg );
DX_OUTPUTDEBUGSTRING( DX_STR_WRAP(" ") );
}
DX_SPRINTF_S( strBufferError, 256, DX_STR_WRAP(STR_FMT_SPEC " (0x%0.8x)"), DX_GETERRORSTRING(hr), hr );
DX_SPRINTF_S( strBuffer, BUFFER_SIZE, DX_STR_WRAP("hr=" STR_FMT_SPEC), strBufferError );
DX_OUTPUTDEBUGSTRING( strBuffer );
DX_OUTPUTDEBUGSTRING( DX_STR_WRAP("\n") );
#if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP)
if( bPopMsgBox )
{
DX_CHAR strBufferFile[MAX_PATH];
DX_STRCPY_S( strBufferFile, MAX_PATH, DX_STR_WRAP("") );
if( strFile )
DX_STRCPY_S( strBufferFile, MAX_PATH, strFile );
DX_CHAR strBufferMsg[1024];
DX_STRCPY_S( strBufferMsg, 1024, DX_STR_WRAP("") );
if( nMsgLen > 0 )
DX_SPRINTF_S( strBufferMsg, 1024, DX_STR_WRAP("Calling: " STR_FMT_SPEC "\n"), strMsg );
DX_SPRINTF_S( strBuffer, BUFFER_SIZE, DX_STR_WRAP("File: " STR_FMT_SPEC "\nLine: " STR_FMT_SPEC "\nError Code: " STR_FMT_SPEC "\n" STR_FMT_SPEC "Do you want to debug the application?"),
strBufferFile, strBufferLine, strBufferError, strBufferMsg );
int nResult = DX_MESSAGEBOX( GetForegroundWindow(), strBuffer, DX_STR_WRAP("Unexpected error encountered"), MB_YESNO | MB_ICONERROR );
if( nResult == IDYES )
DebugBreak();
}
#else
UNREFERENCED_PARAMETER(bPopMsgBox);
#endif
return hr;
#include "DxgiInfoManager.h"
#include "Window.h"
#include "Graphics.h"
#include <dxgidebug.h>
#include <memory>
#pragma comment(lib, "dxguid.lib")
#define GFX_THROW_NOINFO(hrcall) if( FAILED( hr = (hrcall) ) ) throw Graphics::HrException( __LINE__,__FILE__,hr )
DxgiInfoManager::DxgiInfoManager()
{
// define function signature of DXGIGetDebugInterface
typedef HRESULT (WINAPI* DXGIGetDebugInterface)(REFIID,void **);
// load the dll that contains the function DXGIGetDebugInterface
const auto hModDxgiDebug = LoadLibraryEx( "dxgidebug.dll",nullptr,LOAD_LIBRARY_SEARCH_SYSTEM32 );
if( hModDxgiDebug == nullptr )
{
throw CHWND_LAST_EXCEPT();
}
// get address of DXGIGetDebugInterface in dll
const auto DxgiGetDebugInterface = reinterpret_cast<DXGIGetDebugInterface>(
reinterpret_cast<void*>(GetProcAddress( hModDxgiDebug,"DXGIGetDebugInterface" ))
);
if( DxgiGetDebugInterface == nullptr )
{
throw CHWND_LAST_EXCEPT();
}
HRESULT hr;
GFX_THROW_NOINFO( DxgiGetDebugInterface( __uuidof(IDXGIInfoQueue),reinterpret_cast<void**>(&pDxgiInfoQueue) ) );
}
DxgiInfoManager::~DxgiInfoManager()
{
if( pDxgiInfoQueue != nullptr )
{
pDxgiInfoQueue->Release();
}
}
void DxgiInfoManager::Set() noexcept
{
// set the index (next) so that the next all to GetMessages()
// will only get errors generated after this call
next = pDxgiInfoQueue->GetNumStoredMessages( DXGI_DEBUG_ALL );
}
std::vector<std::string> DxgiInfoManager::GetMessages() const
{
std::vector<std::string> messages;
const auto end = pDxgiInfoQueue->GetNumStoredMessages( DXGI_DEBUG_ALL );
for( auto i = next; i < end; i++ )
{
HRESULT hr;
SIZE_T messageLength;
// get the size of message i in bytes
GFX_THROW_NOINFO( pDxgiInfoQueue->GetMessage( DXGI_DEBUG_ALL,i,nullptr,&messageLength ) );
// allocate memory for message
auto bytes = std::make_unique<byte[]>( messageLength );
auto pMessage = reinterpret_cast<DXGI_INFO_QUEUE_MESSAGE*>(bytes.get());
// get the message and push its description into the vector
GFX_THROW_NOINFO( pDxgiInfoQueue->GetMessage( DXGI_DEBUG_ALL,i,pMessage,&messageLength ) );
messages.emplace_back( pMessage->pDescription );
}
return messages;
}
#pragma once
#include "ChiliWin.h"
#include <vector>
#include <string>
class DxgiInfoManager
{
public:
DxgiInfoManager();
~DxgiInfoManager();
DxgiInfoManager( const DxgiInfoManager& ) = delete;
DxgiInfoManager& operator=( const DxgiInfoManager& ) = delete;
void Set() noexcept;
std::vector<std::string> GetMessages() const;
private:
unsigned long long next = 0u;
struct IDXGIInfoQueue* pDxgiInfoQueue = nullptr;
};
\ No newline at end of file
#include "Graphics.h"
#include "dxerr.h"
#include <sstream>
#pragma comment(lib,"d3d11.lib")
// graphics exception checking/throwing macros (some with dxgi infos)
#define GFX_EXCEPT_NOINFO(hr) Graphics::HrException( __LINE__,__FILE__,(hr) )
#define GFX_THROW_NOINFO(hrcall) if( FAILED( hr = (hrcall) ) ) throw Graphics::HrException( __LINE__,__FILE__,hr )
#ifndef NDEBUG
#define GFX_EXCEPT(hr) Graphics::HrException( __LINE__,__FILE__,(hr),infoManager.GetMessages() )
#define GFX_THROW_INFO(hrcall) infoManager.Set(); if( FAILED( hr = (hrcall) ) ) throw GFX_EXCEPT(hr)
#define GFX_DEVICE_REMOVED_EXCEPT(hr) Graphics::DeviceRemovedException( __LINE__,__FILE__,(hr),infoManager.GetMessages() )
#else
#define GFX_EXCEPT(hr) Graphics::HrException( __LINE__,__FILE__,(hr) )
#define GFX_THROW_INFO(hrcall) GFX_THROW_NOINFO(hrcall)
#define GFX_DEVICE_REMOVED_EXCEPT(hr) Graphics::DeviceRemovedException( __LINE__,__FILE__,(hr) )
#endif
Graphics::Graphics( HWND hWnd )
{
// 交换链的参数定义
......@@ -16,19 +32,27 @@ Graphics::Graphics( HWND hWnd )
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.BufferCount = 1;
sd.BufferCount = 2;
sd.OutputWindow = hWnd;
sd.Windowed = TRUE;
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
sd.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
sd.Flags = 0;
UINT swapCreateFlags = 0u;
#ifndef NDEBUG
swapCreateFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
// for checking results of d3d functions
HRESULT hr;
// create device and front/back buffers, and swap chain and rendering context
// 创建Device,SwapChain和Context
D3D11CreateDeviceAndSwapChain(
GFX_THROW_INFO(D3D11CreateDeviceAndSwapChain(
nullptr,
D3D_DRIVER_TYPE_HARDWARE,
nullptr,
0,
swapCreateFlags,
nullptr,
0,
D3D11_SDK_VERSION,
......@@ -37,18 +61,19 @@ Graphics::Graphics( HWND hWnd )
&pDevice,
nullptr,
&pContext
);
));
// gain access to texture subresource in swap chain (back buffer)
// 定义指向backBuffer的指针
ID3D11Resource* pBackBuffer = nullptr;
// 通过SwapChian,取得backBuffer
pSwap->GetBuffer(0, __uuidof(ID3D11Resource), reinterpret_cast<void**>(&pBackBuffer));
GFX_THROW_INFO(pSwap->GetBuffer(0, __uuidof(ID3D11Resource), reinterpret_cast<void**>(&pBackBuffer)));
// 取得指向属于backBuffer的View的指针
pDevice->CreateRenderTargetView(
pBackBuffer,
nullptr,
&pTarget
);
GFX_THROW_INFO(pDevice->CreateRenderTargetView(pBackBuffer, nullptr, &pTarget));
pBackBuffer->Release();
}
......@@ -76,11 +101,93 @@ Graphics::~Graphics()
void Graphics::EndFrame()
{
// flipping,使用SwapChain将back buffer的内容展现到屏幕
pSwap->Present( 1u,0u ); // 同步频率1,代表屏幕每刷新一次,就进行图形刷新。
HRESULT hr;
#ifndef NDEBUG
infoManager.Set();
#endif
if (FAILED(hr = pSwap->Present(1u, 0u))) // 同步频率1,代表屏幕每刷新一次,就进行图形刷新。
{
if (hr == DXGI_ERROR_DEVICE_REMOVED)
{
throw GFX_DEVICE_REMOVED_EXCEPT(pDevice->GetDeviceRemovedReason());
}
else
{
throw GFX_EXCEPT(hr);
}
}
}
void Graphics::ClearBuffer(float red, float green, float blue) noexcept
{
const float color[] = { red,green,blue,1.0f };
pContext->ClearRenderTargetView(pTarget, color);
}
// Graphics exception stuff
Graphics::HrException::HrException(int line, const char* file, HRESULT hr, std::vector<std::string> infoMsgs) noexcept
:
Exception(line, file),
hr(hr)
{
// join all info messages with newlines into single string
for (const auto& m : infoMsgs)
{
info += m;
info.push_back('\n');
}
// remove final newline if exists
if (!info.empty())
{
info.pop_back();
}
}
const char* Graphics::HrException::what() const noexcept
{
std::ostringstream oss;
oss << GetType() << std::endl
<< "[Error Code] 0x" << std::hex << std::uppercase << GetErrorCode()
<< std::dec << " (" << (unsigned long)GetErrorCode() << ")" << std::endl
<< "[Error String] " << GetErrorString() << std::endl
<< "[Description] " << GetErrorDescription() << std::endl;
if (!info.empty())
{
oss << "\n[Error Info]\n" << GetErrorInfo() << std::endl << std::endl;
}
oss << GetOriginString();
whatBuffer = oss.str();
return whatBuffer.c_str();
}
const char* Graphics::HrException::GetType() const noexcept
{
return "Chili Graphics Exception";
}
HRESULT Graphics::HrException::GetErrorCode() const noexcept
{
return hr;
}
std::string Graphics::HrException::GetErrorString() const noexcept
{
return DXGetErrorString(hr);
}
std::string Graphics::HrException::GetErrorDescription() const noexcept
{
char buf[512];
DXGetErrorDescription(hr, buf, sizeof(buf));
return buf;
}
std::string Graphics::HrException::GetErrorInfo() const noexcept
{
return info;
}
const char* Graphics::DeviceRemovedException::GetType() const noexcept
{
return "Chili Graphics Exception [Device Removed] (DXGI_ERROR_DEVICE_REMOVED)";
}
\ No newline at end of file
#pragma once
#include "ChiliWin.h"
#include "ChiliException.h"
#include <d3d11.h>
#include <vector>
#include "DxgiInfoManager.h"
class Graphics
{
public:
class Exception : public ChiliException
{
using ChiliException::ChiliException;
};
class HrException : public Exception
{
public:
HrException(int line, const char* file, HRESULT hr, std::vector<std::string> infoMsgs = {}) noexcept;
const char* what() const noexcept override;
const char* GetType() const noexcept override;
HRESULT GetErrorCode() const noexcept;
std::string GetErrorString() const noexcept;
std::string GetErrorDescription() const noexcept;
std::string GetErrorInfo() const noexcept;
private:
HRESULT hr;
std::string info;
};
class DeviceRemovedException : public HrException
{
using HrException::HrException;
public:
const char* GetType() const noexcept override;
private:
std::string reason;
};
public:
Graphics( HWND hWnd );
Graphics( const Graphics& ) = delete;
......@@ -13,6 +43,9 @@ public:
// 刷新RGB
void ClearBuffer(float red, float green, float blue) noexcept;
private:
#ifndef NDEBUG
DxgiInfoManager infoManager;
#endif
// 指向Device的指针
ID3D11Device* pDevice = nullptr;
// 指向交换链的指针
......
......@@ -140,6 +140,8 @@
<ClCompile Include="App.cpp" />
<ClCompile Include="ChiliException.cpp" />
<ClCompile Include="ChiliTimer.cpp" />
<ClCompile Include="dxerr.cpp" />
<ClCompile Include="DxgiInfoManager.cpp" />
<ClCompile Include="Graphics.cpp" />
<ClCompile Include="Keyboard.cpp" />
<ClCompile Include="Mouse.cpp" />
......@@ -152,6 +154,8 @@
<ClInclude Include="ChiliException.h" />
<ClInclude Include="ChiliTimer.h" />
<ClInclude Include="ChiliWin.h" />
<ClInclude Include="dxerr.h" />
<ClInclude Include="DxgiInfoManager.h" />
<ClInclude Include="Graphics.h" />
<ClInclude Include="Keyboard.h" />
<ClInclude Include="Mouse.h" />
......@@ -165,6 +169,11 @@
<ItemGroup>
<Image Include="oasis.ico" />
</ItemGroup>
<ItemGroup>
<None Include="DXGetErrorDescription.inl" />
<None Include="DXGetErrorString.inl" />
<None Include="DXTrace.inl" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
......
......@@ -13,6 +13,9 @@
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Inline FIles">
<UniqueIdentifier>{4ea6ad36-f6fa-4bd0-a3a7-f0e7c18bdeac}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="WinMain.cpp">
......@@ -42,6 +45,12 @@
<ClCompile Include="Graphics.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="dxerr.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="DxgiInfoManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="ChiliException.h">
......@@ -74,6 +83,12 @@
<ClInclude Include="Graphics.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="dxerr.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="DxgiInfoManager.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="StudyDx.rc">
......@@ -85,4 +100,15 @@
<Filter>Resource Files</Filter>
</Image>
</ItemGroup>
<ItemGroup>
<None Include="DXGetErrorDescription.inl">
<Filter>Inline FIles</Filter>
</None>
<None Include="DXGetErrorString.inl">
<Filter>Inline FIles</Filter>
</None>
<None Include="DXTrace.inl">
<Filter>Inline FIles</Filter>
</None>
</ItemGroup>
</Project>
\ No newline at end of file
......@@ -131,7 +131,7 @@ void Window::SetTitle(const std::string& title)
}
}
std::optional<int> Window::ProcessMessages()
std::optional<int> Window::ProcessMessages() noexcept
{
MSG msg;
// while queue has messages, remove and dispatch them (but do not block on empty queue)
......@@ -324,33 +324,11 @@ LRESULT Window::HandleMsg( HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam ) noex
}
// Window Exception Stuff
Window::Exception::Exception(int line, const char* file, HRESULT hr) noexcept
:
ChiliException(line, file),
hr(hr)
{}
const char* Window::Exception::what() const noexcept
{
std::ostringstream oss;
oss << GetType() << std::endl
<< "[Error Code] " << GetErrorCode() << std::endl
<< "[Description] " << GetErrorString() << std::endl
<< GetOriginString();
whatBuffer = oss.str();
return whatBuffer.c_str();
}
const char* Window::Exception::GetType() const noexcept
{
return "Chili Window Exception";
}
std::string Window::Exception::TranslateErrorCode(HRESULT hr) noexcept
{
char* pMsgBuf = nullptr;
// windows will allocate memory for err string and make our pointer point to it
DWORD nMsgLen = FormatMessage(
const DWORD nMsgLen = FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
......@@ -368,13 +346,41 @@ std::string Window::Exception::TranslateErrorCode(HRESULT hr) noexcept
return errorString;
}
HRESULT Window::Exception::GetErrorCode() const noexcept
Window::HrException::HrException(int line, const char* file, HRESULT hr) noexcept
:
Exception(line, file),
hr(hr)
{}
const char* Window::HrException::what() const noexcept
{
std::ostringstream oss;
oss << GetType() << std::endl
<< "[Error Code] 0x" << std::hex << std::uppercase << GetErrorCode()
<< std::dec << " (" << (unsigned long)GetErrorCode() << ")" << std::endl
<< "[Description] " << GetErrorDescription() << std::endl
<< GetOriginString();
whatBuffer = oss.str();
return whatBuffer.c_str();
}
const char* Window::HrException::GetType() const noexcept
{
return "Chili Window Exception";
}
HRESULT Window::HrException::GetErrorCode() const noexcept
{
return hr;
}
std::string Window::Exception::GetErrorString() const noexcept
std::string Window::HrException::GetErrorDescription() const noexcept
{
return TranslateErrorCode(hr);
return Exception::TranslateErrorCode(hr);
}
const char* Window::NoGfxException::GetType() const noexcept
{
return "Chili Window Exception [No Graphics]";
}
\ No newline at end of file
......@@ -32,16 +32,27 @@ class Window
public:
class Exception : public ChiliException
{
using ChiliException::ChiliException;
public:
Exception(int line, const char* file, HRESULT hr) noexcept;
const char* what() const noexcept override;
virtual const char* GetType() const noexcept;
static std::string TranslateErrorCode(HRESULT hr) noexcept;
};
class HrException : public Exception
{
public:
HrException(int line, const char* file, HRESULT hr) noexcept;
const char* what() const noexcept override;
const char* GetType() const noexcept override;
HRESULT GetErrorCode() const noexcept;
std::string GetErrorString() const noexcept;
std::string GetErrorDescription() const noexcept;
private:
HRESULT hr;
};
class NoGfxException : public Exception
{
public:
using Exception::Exception;
const char* GetType() const noexcept override;
};
private:
// singleton manages registration/cleanup of window class
class WindowClass
......@@ -64,7 +75,7 @@ public:
Window(const Window&) = delete;
Window& operator=(const Window&) = delete;
void SetTitle(const std::string& title);
static std::optional<int> ProcessMessages();
static std::optional<int> ProcessMessages() noexcept;
Graphics& Gfx();
private:
static LRESULT CALLBACK HandleMsgSetup(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) noexcept;
......@@ -83,5 +94,6 @@ private:
// error exception helper macro
#define CHWND_EXCEPT( hr ) Window::Exception( __LINE__,__FILE__,hr )
#define CHWND_LAST_EXCEPT() Window::Exception( __LINE__,__FILE__,GetLastError() )
\ No newline at end of file
#define CHWND_EXCEPT( hr ) Window::HrException( __LINE__,__FILE__,(hr) )
#define CHWND_LAST_EXCEPT() Window::HrException( __LINE__,__FILE__,GetLastError() )
#define CHWND_NOGFX_EXCEPT() Window::NoGfxException( __LINE__,__FILE__ )
\ No newline at end of file
//--------------------------------------------------------------------------------------
// File: DXErr.cpp
//
// DirectX Error Library
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
#include "dxerr.h"
#include <stdio.h>
#include <algorithm>
#if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP)
#include <ddraw.h>
#include <d3d9.h>
#define DIRECTINPUT_VERSION 0x800
#include <dinput.h>
#include <dinputd.h>
#endif
#include <d3d10_1.h>
#include <d3d11_1.h>
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
#include <wincodec.h>
#include <d2derr.h>
#include <dwrite.h>
#endif
#define XAUDIO2_E_INVALID_CALL 0x88960001
#define XAUDIO2_E_XMA_DECODER_ERROR 0x88960002
#define XAUDIO2_E_XAPO_CREATION_FAILED 0x88960003
#define XAUDIO2_E_DEVICE_INVALIDATED 0x88960004
#define XAPO_E_FORMAT_UNSUPPORTED MAKE_HRESULT(SEVERITY_ERROR, 0x897, 0x01)
#define DXUTERR_NODIRECT3D MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0901)
#define DXUTERR_NOCOMPATIBLEDEVICES MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0902)
#define DXUTERR_MEDIANOTFOUND MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0903)
#define DXUTERR_NONZEROREFCOUNT MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0904)
#define DXUTERR_CREATINGDEVICE MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0905)
#define DXUTERR_RESETTINGDEVICE MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0906)
#define DXUTERR_CREATINGDEVICEOBJECTS MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0907)
#define DXUTERR_RESETTINGDEVICEOBJECTS MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0908)
#define DXUTERR_INCORRECTVERSION MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0909)
#define DXUTERR_DEVICEREMOVED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x090A)
//-----------------------------------------------------------------------------
#define BUFFER_SIZE 3000
#pragma warning( disable : 6001 6221 )
//--------------------------------------------------------------------------------------
#define CHK_ERR_W(hrchk, strOut) \
case hrchk: \
return L##strOut;
#define CHK_ERRA_W(hrchk) \
case hrchk: \
return L#hrchk;
#define CHK_ERR_A(hrchk, strOut) \
case hrchk: \
return strOut;
#define CHK_ERRA_A(hrchk) \
case hrchk: \
return #hrchk;
#define HRESULT_FROM_WIN32b(x) ((HRESULT)(x) <= 0 ? ((HRESULT)(x)) : ((HRESULT) (((x) & 0x0000FFFF) | (FACILITY_WIN32 << 16) | 0x80000000)))
#define CHK_ERR_WIN32A_W(hrchk) \
case HRESULT_FROM_WIN32b(hrchk): \
case hrchk: \
return L#hrchk;
#define CHK_ERR_WIN32_ONLY_W(hrchk, strOut) \
case HRESULT_FROM_WIN32b(hrchk): \
return L##strOut;
#define CHK_ERR_WIN32A_A(hrchk) \
case HRESULT_FROM_WIN32b(hrchk): \
case hrchk: \
return #hrchk;
#define CHK_ERR_WIN32_ONLY_A(hrchk, strOut) \
case HRESULT_FROM_WIN32b(hrchk): \
return strOut;
//-----------------------------------------------------
const WCHAR* WINAPI DXGetErrorStringW( _In_ HRESULT hr )
{
#define CHK_ERRA CHK_ERRA_W
#define CHK_ERR CHK_ERR_W
#define CHK_ERR_WIN32A CHK_ERR_WIN32A_W
#define CHK_ERR_WIN32_ONLY CHK_ERR_WIN32_ONLY_W
#define DX_STR_WRAP(...) L##__VA_ARGS__
#include "DXGetErrorString.inl"
#undef DX_STR_WRAP
#undef CHK_ERR_WIN32A
#undef CHK_ERR_WIN32_ONLY
#undef CHK_ERRA
#undef CHK_ERR
}
const CHAR* WINAPI DXGetErrorStringA( _In_ HRESULT hr )
{
#define CHK_ERRA CHK_ERRA_A
#define CHK_ERR CHK_ERR_A
#define CHK_ERR_WIN32A CHK_ERR_WIN32A_A
#define CHK_ERR_WIN32_ONLY CHK_ERR_WIN32_ONLY_A
#define DX_STR_WRAP(s) s
#include "DXGetErrorString.inl"
#undef DX_STR_WRAP
#undef CHK_ERR_WIN32A
#undef CHK_ERR_WIN32_ONLY
#undef CHK_ERRA
#undef CHK_ERR
}
//--------------------------------------------------------------------------------------
#undef CHK_ERR
#undef CHK_ERRA
#undef HRESULT_FROM_WIN32b
#undef CHK_ERR_WIN32A
#undef CHK_ERR_WIN32_ONLY
#undef CHK_ERRA_W
#undef CHK_ERR_W
#undef CHK_ERRA_A
#undef CHK_ERR_A
#define CHK_ERRA_W(hrchk) \
case hrchk: \
wcscpy_s( desc, count, L#hrchk ); \
break;
#define CHK_ERR_W(hrchk, strOut) \
case hrchk: \
wcscpy_s( desc, count, L##strOut ); \
break;
#define CHK_ERRA_A(hrchk) \
case hrchk: \
strcpy_s( desc, count, #hrchk ); \
break;
#define CHK_ERR_A(hrchk, strOut) \
case hrchk: \
strcpy_s( desc, count, strOut ); \
break;
//--------------------------------------------------------------------------------------
void WINAPI DXGetErrorDescriptionW( _In_ HRESULT hr, _Out_cap_(count) WCHAR* desc, _In_ size_t count )
{
#define CHK_ERRA CHK_ERRA_W
#define CHK_ERR CHK_ERR_W
#define DX_FORMATMESSAGE FormatMessageW
#include "DXGetErrorDescription.inl"
#undef DX_FORMATMESSAGE
#undef CHK_ERRA
#undef CHK_ERR
}
void WINAPI DXGetErrorDescriptionA( _In_ HRESULT hr, _Out_cap_(count) CHAR* desc, _In_ size_t count )
{
#define CHK_ERRA CHK_ERRA_A
#define CHK_ERR CHK_ERR_A
#define DX_FORMATMESSAGE FormatMessageA
#include "DXGetErrorDescription.inl"
#undef DX_FORMATMESSAGE
#undef CHK_ERRA
#undef CHK_ERR
}
//-----------------------------------------------------------------------------
HRESULT WINAPI DXTraceW( _In_z_ const WCHAR* strFile, _In_ DWORD dwLine, _In_ HRESULT hr,
_In_opt_ const WCHAR* strMsg, _In_ bool bPopMsgBox )
{
#define DX_STR_WRAP(...) L##__VA_ARGS__
#define DX_CHAR WCHAR
#define DX_SPRINTF_S swprintf_s
#define DX_STRCPY_S wcscpy_s
#define DX_STRNLEN_S wcsnlen_s
#define STR_FMT_SPEC "%ls"
#define DX_MESSAGEBOX MessageBoxW
#define DX_OUTPUTDEBUGSTRING OutputDebugStringW
#define DX_GETERRORSTRING DXGetErrorStringW
#include "DXTrace.inl"
#undef DX_STR_WRAP
#undef DX_CHAR
#undef DX_SPRINTF_S
#undef DX_STRCPY_S
#undef DX_STRNLEN_S
#undef STR_FMT_SPEC
#undef DX_MESSAGEBOX
#undef DX_OUTPUTDEBUGSTRING
#undef DX_GETERRORSTRING
}
HRESULT WINAPI DXTraceA( _In_z_ const CHAR* strFile, _In_ DWORD dwLine, _In_ HRESULT hr,
_In_opt_ const CHAR* strMsg, _In_ bool bPopMsgBox )
{
#define DX_STR_WRAP(s) s
#define DX_CHAR CHAR
#define DX_SPRINTF_S sprintf_s
#define DX_STRCPY_S strcpy_s
#define DX_STRNLEN_S strnlen_s
#define STR_FMT_SPEC "%s"
#define DX_MESSAGEBOX MessageBoxA
#define DX_OUTPUTDEBUGSTRING OutputDebugStringA
#define DX_GETERRORSTRING DXGetErrorStringA
#include "DXTrace.inl"
#undef DX_STR_WRAP
#undef DX_CHAR
#undef DX_SPRINTF_S
#undef DX_STRCPY_S
#undef DX_STRNLEN_S
#undef STR_FMT_SPEC
#undef DX_MESSAGEBOX
#undef DX_OUTPUTDEBUGSTRING
#undef DX_GETERRORSTRING
}
//--------------------------------------------------------------------------------------
// File: DXErr.h
//
// DirectX Error Library
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
#pragma once
#include "ChiliWin.h"
#include <sal.h>
#ifdef __cplusplus
extern "C" {
#endif
//--------------------------------------------------------------------------------------
// DXGetErrorString
//--------------------------------------------------------------------------------------
const WCHAR* WINAPI DXGetErrorStringW( _In_ HRESULT hr );
const CHAR* WINAPI DXGetErrorStringA( _In_ HRESULT hr );
#ifdef UNICODE
#define DXGetErrorString DXGetErrorStringW
#else
#define DXGetErrorString DXGetErrorStringA
#endif
//--------------------------------------------------------------------------------------
// DXGetErrorDescription has to be modified to return a copy in a buffer rather than
// the original static string.
//--------------------------------------------------------------------------------------
void WINAPI DXGetErrorDescriptionW( _In_ HRESULT hr, _Out_cap_(count) WCHAR* desc, _In_ size_t count );
void WINAPI DXGetErrorDescriptionA( _In_ HRESULT hr, _Out_cap_(count) CHAR* desc, _In_ size_t count );
#ifdef UNICODE
#define DXGetErrorDescription DXGetErrorDescriptionW
#else
#define DXGetErrorDescription DXGetErrorDescriptionA
#endif
//--------------------------------------------------------------------------------------
// DXTrace
//
// Desc: Outputs a formatted error message to the debug stream
//
// Args: WCHAR* strFile The current file, typically passed in using the
// __FILEW__ macro.
// DWORD dwLine The current line number, typically passed in using the
// __LINE__ macro.
// HRESULT hr An HRESULT that will be traced to the debug stream.
// CHAR* strMsg A string that will be traced to the debug stream (may be NULL)
// BOOL bPopMsgBox If TRUE, then a message box will popup also containing the passed info.
//
// Return: The hr that was passed in.
//--------------------------------------------------------------------------------------
HRESULT WINAPI DXTraceW( _In_z_ const WCHAR* strFile, _In_ DWORD dwLine, _In_ HRESULT hr, _In_opt_ const WCHAR* strMsg, _In_ bool bPopMsgBox );
//--------------------------------------------------------------------------------------
// DXTrace
//
// Desc: Outputs a formatted error message to the debug stream
//
// Args: CHAR* strFile The current file, typically passed in using the
// __FILE__ macro.
// DWORD dwLine The current line number, typically passed in using the
// __LINE__ macro.
// HRESULT hr An HRESULT that will be traced to the debug stream.
// CHAR* strMsg A string that will be traced to the debug stream (may be NULL)
// BOOL bPopMsgBox If TRUE, then a message box will popup also containing the passed info.
//
// Return: The hr that was passed in.
//--------------------------------------------------------------------------------------
HRESULT WINAPI DXTraceA( _In_z_ const CHAR* strFile, _In_ DWORD dwLine, _In_ HRESULT hr, _In_opt_ const CHAR* strMsg, _In_ bool bPopMsgBox );
#ifdef UNICODE
#define DXTrace DXTraceW
#else
#define DXTrace DXTraceA
#endif
//--------------------------------------------------------------------------------------
//
// Helper macros
//
//--------------------------------------------------------------------------------------
#if defined(DEBUG) || defined(_DEBUG)
#ifdef UNICODE
#define DXTRACE_MSG(str) DXTrace( __FILEW__, (DWORD)__LINE__, 0, str, false )
#define DXTRACE_ERR(str,hr) DXTrace( __FILEW__, (DWORD)__LINE__, hr, str, false )
#define DXTRACE_ERR_MSGBOX(str,hr) DXTrace( __FILEW__, (DWORD)__LINE__, hr, str, true )
#else
#define DXTRACE_MSG(str) DXTrace( __FILE__, (DWORD)__LINE__, 0, str, false )
#define DXTRACE_ERR(str,hr) DXTrace( __FILE__, (DWORD)__LINE__, hr, str, false )
#define DXTRACE_ERR_MSGBOX(str,hr) DXTrace( __FILE__, (DWORD)__LINE__, hr, str, true )
#endif
#else
#define DXTRACE_MSG(str) (0L)
#define DXTRACE_ERR(str,hr) (hr)
#define DXTRACE_ERR_MSGBOX(str,hr) (hr)
#endif
#ifdef __cplusplus
}
#endif //__cplusplus
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment