#include "VertexBuffer.h"
void VertexBuffer::Bind( Graphics& gfx ) noexcept
{
const UINT offset = 0u;
GetContext( gfx )->IASetVertexBuffers( 0u,1u,pVertexBuffer.GetAddressOf(),&stride,&offset );
}
#pragma once
#include "Bindable.h"
#include "GraphicsThrowMacros.h"
class VertexBuffer : public Bindable
{
public:
template<class V>
VertexBuffer( Graphics& gfx,const std::vector<V>& vertices )
:
stride( sizeof( V ) )
{
INFOMAN( gfx );
D3D11_BUFFER_DESC bd = {};
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.Usage = D3D11_USAGE_DEFAULT;
bd.CPUAccessFlags = 0u;
bd.MiscFlags = 0u;
bd.ByteWidth = UINT( sizeof( V ) * vertices.size() );
bd.StructureByteStride = sizeof( V );
D3D11_SUBRESOURCE_DATA sd = {};
sd.pSysMem = vertices.data();
GFX_THROW_INFO( GetDevice( gfx )->CreateBuffer( &bd,&sd,&pVertexBuffer ) );
}
void Bind( Graphics& gfx ) noexcept override;
protected:
UINT stride;
Microsoft::WRL::ComPtr<ID3D11Buffer> pVertexBuffer;
};
#include "VertexShader.h"
#include "GraphicsThrowMacros.h"
VertexShader::VertexShader( Graphics& gfx,const std::wstring& path )
{
INFOMAN( gfx );
GFX_THROW_INFO( D3DReadFileToBlob( path.c_str(),&pBytecodeBlob ) );
GFX_THROW_INFO( GetDevice( gfx )->CreateVertexShader(
pBytecodeBlob->GetBufferPointer(),
pBytecodeBlob->GetBufferSize(),
nullptr,
&pVertexShader
) );
}
void VertexShader::Bind( Graphics& gfx ) noexcept
{
GetContext( gfx )->VSSetShader( pVertexShader.Get(),nullptr,0u );
}
ID3DBlob* VertexShader::GetBytecode() const noexcept
{
return pBytecodeBlob.Get();
}
#pragma once
#include "Bindable.h"
class VertexShader : public Bindable
{
public:
VertexShader( Graphics& gfx,const std::wstring& path );
void Bind( Graphics& gfx ) noexcept override;
ID3DBlob* GetBytecode() const noexcept;
protected:
Microsoft::WRL::ComPtr<ID3DBlob> pBytecodeBlob;
Microsoft::WRL::ComPtr<ID3D11VertexShader> pVertexShader;
};
\ No newline at end of file
cbuffer CBuf
{
matrix transform;
};
float4 main( float3 pos : Position ): SV_Position
{
return mul(float4(pos, 1.0f), transform);;
}
\ No newline at end of file
......@@ -18,7 +18,7 @@
* along with The Chili Direct3D Engine. If not, see <http://www.gnu.org/licenses/>. *
******************************************************************************************/
#include "Window.h"
#include "App.h"
int CALLBACK WinMain(
HINSTANCE hInstance,
......@@ -28,25 +28,7 @@ int CALLBACK WinMain(
{
try
{
Window wnd(800, 300, "Donkey Fart Box");
MSG msg;
BOOL gResult;
while ((gResult = GetMessage(&msg, nullptr, 0, 0)) > 0)
{
// TranslateMessage will post auxilliary WM_CHAR messages from key msgs
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// check if GetMessage call itself borked
if (gResult == -1)
{
return -1;
}
// wParam here is the value passed to PostQuitMessage
return msg.wParam;
return App().Go();
}
catch (const ChiliException& e)
{
......
......@@ -19,7 +19,8 @@
******************************************************************************************/
#include "Window.h"
#include <sstream>
#include "resource.h"
#include "WindowsThrowMacros.h"
// Window Class Stuff
Window::WindowClass Window::WindowClass::wndClass;
......@@ -35,12 +36,34 @@ Window::WindowClass::WindowClass() noexcept
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = GetInstance();
wc.hIcon = nullptr;
// wc.hIcon = nullptr;
// 指定图标
wc.hIcon = static_cast<HICON>(
LoadImage(
GetInstance(),
MAKEINTRESOURCE(IDI_ICON1),
IMAGE_ICON,
32,
32,
0));
wc.hCursor = nullptr;
wc.hbrBackground = nullptr;
wc.lpszMenuName = nullptr;
wc.lpszClassName = GetName();
wc.hIconSm = nullptr;
// wc.hIconSm = nullptr;
// 指定小图标
wc.hIconSm = static_cast<HICON>(
LoadImage(
GetInstance(),
MAKEINTRESOURCE(IDI_ICON1),
IMAGE_ICON,
16,
16,
0));
RegisterClassEx( &wc );
}
......@@ -62,6 +85,9 @@ HINSTANCE Window::WindowClass::GetInstance() noexcept
// Window Stuff
Window::Window( int width,int height,const char* name )
:
width(width),
height(height)
{
// calculate window size based on desired client region size
RECT wr;
......@@ -69,10 +95,10 @@ Window::Window( int width,int height,const char* name )
wr.right = width + wr.left;
wr.top = 100;
wr.bottom = height + wr.top;
if (FAILED(AdjustWindowRect(&wr, WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU, FALSE)))
if (AdjustWindowRect(&wr, WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU, FALSE) == 0)
{
throw CHWND_LAST_EXCEPT();
};
}
// create window & get hWnd
hWnd = CreateWindow(
......@@ -86,8 +112,10 @@ Window::Window( int width,int height,const char* name )
{
throw CHWND_LAST_EXCEPT();
}
// show window
// newly created windows start off as hidden
ShowWindow( hWnd,SW_SHOWDEFAULT );
// create graphics object
pGfx = std::make_unique<Graphics>(hWnd);
}
Window::~Window()
......@@ -95,6 +123,42 @@ Window::~Window()
DestroyWindow( hWnd );
}
void Window::SetTitle(const std::string& title)
{
if (SetWindowText(hWnd, title.c_str()) == 0)
{
throw CHWND_LAST_EXCEPT();
}
}
std::optional<int> Window::ProcessMessages() noexcept
{
MSG msg;
// while queue has messages, remove and dispatch them (but do not block on empty queue)
// 检查一下消息队列,如果有的话就循环取出所有消息,如果没有的话直接返回,不阻塞
while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
{
// check for quit because peekmessage does not signal this via return val
if (msg.message == WM_QUIT)
{
// return optional wrapping int (arg to PostQuitMessage is in wparam) signals quit
return (int)msg.wParam;
}
// TranslateMessage will post auxilliary WM_CHAR messages from key msgs
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// return empty optional when not quitting app
return {};
}
Graphics& Window::Gfx()
{
return *pGfx;
}
LRESULT CALLBACK Window::HandleMsgSetup( HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam ) noexcept
{
// use create parameter passed in from CreateWindow() to store window class pointer at WinAPI side
......@@ -132,44 +196,140 @@ LRESULT Window::HandleMsg( HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam ) noex
{
switch( msg )
{
// we don't want the DefProc to handle this message because
// we want our destructor to destroy the window, so return 0 instead of break
case WM_CLOSE:
PostQuitMessage( 0 );
return 0;
}
// we don't want the DefProc to handle this message because
// we want our destructor to destroy the window, so return 0 instead of break
case WM_CLOSE:
PostQuitMessage( 0 );
return 0;
return DefWindowProc( hWnd,msg,wParam,lParam );
}
// 如果窗口失去焦点,立刻清空所有队列中的成员
case WM_KILLFOCUS:
kbd.ClearState();
break;
// Window Exception Stuff
Window::Exception::Exception(int line, const char* file, HRESULT hr) noexcept
:
ChiliException(line, file),
hr(hr)
{}
// 记录Key被按下
case WM_KEYDOWN:
// Bipset的第28,29,30位固定是0,30位代表前一次按键状态,1代表按下。
// 因此28-31的16进制值如果是4的话,表示前一次是按下的状态,这次是持续按键
// 如果Key被持续按下,第一个条件不成立,不执行操作
// 在以上的基础上,提供Autorepeat的选项。如果启用Autorepeat,那么即使持续按键,也执行操作
if (!(lParam & 0x40000000) || kbd.AutorepeatIsEnabled()) // filter autorepeat
{
kbd.OnKeyPressed(static_cast<unsigned char>(wParam));
}
break;
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();
}
// 记录SysKey被按下
case WM_SYSKEYDOWN:
// 同上
if (!(lParam & 0x40000000) || kbd.AutorepeatIsEnabled()) // filter autorepeat
{
kbd.OnKeyPressed(static_cast<unsigned char>(wParam));
}
break;
const char* Window::Exception::GetType() const noexcept
{
return "Chili Window Exception";
// 记录SysKey被释放
case WM_SYSKEYUP:
// 记录Key释放
case WM_KEYUP:
kbd.OnKeyReleased(static_cast<unsigned char>(wParam));
break;
// 记录文字输入
case WM_CHAR:
kbd.OnChar(static_cast<unsigned char>(wParam));
break;
// 鼠标移动
case WM_MOUSEMOVE:
{
const POINTS pt = MAKEPOINTS(lParam);
mouse.OnMouseMove(pt.x, pt.y);
// in client region -> log move, and log enter + capture mouse (if not previously in window)
// 判断是否在窗口内
if (pt.x >= 0 && pt.x <= width && pt.y >= 0 and pt.y <= height) {
// 如果鼠标在窗口内,那么一定会记录鼠标的移动
mouse.OnMouseMove(pt.x, pt.y);
// 判断之前的鼠标状态。如果之前不在窗口内,那么说明现在是从外面移动进入窗口内
if (!mouse.IsInWindow())
{
SetCapture(hWnd);
mouse.OnMouseEnter();
}
}
else
{
// 当鼠标移动到了窗口外,如果之前左键或者右键是按住的状态,那么被识别为拖拽
if (mouse.LeftIsPressed() || mouse.RightIsPressed())
{
// 拖拽过程中,依然会记录鼠标的移动
mouse.OnMouseMove(pt.x, pt.y);
}
else
{
// 否则的话,释放对鼠标的捕获
ReleaseCapture();
mouse.OnMouseLeave();
}
}
break;
}
// 点击左键
case WM_LBUTTONDOWN:
{
const POINTS pt = MAKEPOINTS(lParam);
mouse.OnLeftPressed(pt.x, pt.y);
SetForegroundWindow(hWnd);
break;
}
// 点击右键
case WM_RBUTTONDOWN:
{
const POINTS pt = MAKEPOINTS(lParam);
mouse.OnRightPressed(pt.x, pt.y);
break;
}
// 释放左键
case WM_LBUTTONUP:
{
const POINTS pt = MAKEPOINTS(lParam);
mouse.OnLeftReleased(pt.x, pt.y);
break;
}
// 释放右键
{
case WM_RBUTTONUP:
const POINTS pt = MAKEPOINTS(lParam);
mouse.OnRightReleased(pt.x, pt.y);
break;
}
// 鼠标滚轮
case WM_MOUSEWHEEL:
{
const POINTS pt = MAKEPOINTS(lParam);
const int delta = GET_WHEEL_DELTA_WPARAM(wParam);
mouse.OnWheelDelta(pt.x, pt.y, delta);
break;
}
}
return DefWindowProc( hWnd,msg,wParam,lParam );
}
// Window Exception Stuff
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),
......@@ -187,13 +347,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
......@@ -20,6 +20,11 @@
#pragma once
#include "ChiliWin.h"
#include "ChiliException.h"
#include "Keyboard.h"
#include "Mouse.h"
#include "Graphics.h"
#include <optional>
#include <memory>
class Window
......@@ -27,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
......@@ -58,17 +74,20 @@ public:
~Window();
Window(const Window&) = delete;
Window& operator=(const Window&) = delete;
void SetTitle(const std::string& title);
static std::optional<int> ProcessMessages() noexcept;
Graphics& Gfx();
private:
static LRESULT CALLBACK HandleMsgSetup(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) noexcept;
static LRESULT CALLBACK HandleMsgThunk(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) noexcept;
LRESULT HandleMsg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) noexcept;
public:
Keyboard kbd;
Mouse mouse;
private:
int width;
int height;
HWND hWnd;
};
// 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
// 成员变量gfx在Window的构造函数执行的过程中才会被初始化,因此定义指针变量,用于初始化gfx
std::unique_ptr<Graphics> pGfx;
};
\ No newline at end of file
......@@ -33,7 +33,7 @@
#define REGISTER_MESSAGE(msg){msg,#msg}
WindowsMessageMap::WindowsMessageMap()
WindowsMessageMap::WindowsMessageMap() noexcept
:
map({
REGISTER_MESSAGE(WM_CREATE),
......@@ -168,15 +168,6 @@ WindowsMessageMap::WindowsMessageMap()
REGISTER_MESSAGE(WM_QUERYNEWPALETTE),
REGISTER_MESSAGE(WM_PALETTEISCHANGING),
REGISTER_MESSAGE(WM_PALETTECHANGED),
REGISTER_MESSAGE(WM_DDE_INITIATE),
REGISTER_MESSAGE(WM_DDE_TERMINATE),
REGISTER_MESSAGE(WM_DDE_ADVISE),
REGISTER_MESSAGE(WM_DDE_UNADVISE),
REGISTER_MESSAGE(WM_DDE_ACK),
REGISTER_MESSAGE(WM_DDE_DATA),
REGISTER_MESSAGE(WM_DDE_REQUEST),
REGISTER_MESSAGE(WM_DDE_POKE),
REGISTER_MESSAGE(WM_DDE_EXECUTE),
REGISTER_MESSAGE(WM_DROPFILES),
REGISTER_MESSAGE(WM_POWER),
REGISTER_MESSAGE(WM_WINDOWPOSCHANGED),
......@@ -219,7 +210,7 @@ WindowsMessageMap::WindowsMessageMap()
})
{}
std::string WindowsMessageMap::operator()(DWORD msg, LPARAM lp, WPARAM wp) const
std::string WindowsMessageMap::operator()(DWORD msg, LPARAM lp, WPARAM wp) const noexcept
{
constexpr int firstColWidth = 25;
const auto i = map.find(msg);
......
......@@ -21,12 +21,13 @@
#include <unordered_map>
#include <Windows.h>
#include <string>
#include "ChiliWin.h"
class WindowsMessageMap
{
public:
WindowsMessageMap();
std::string operator()(DWORD msg, LPARAM lp, WPARAM wp) const;
WindowsMessageMap() noexcept;
std::string operator()(DWORD msg, LPARAM lp, WPARAM wp) const noexcept;
private:
std::unordered_map<DWORD, std::string> map;
};
\ No newline at end of file
#pragma once
#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__ )
//--------------------------------------------------------------------------------------
// 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
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by StudyDx.rc
//
#define IDI_ICON1 107
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 108
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif