1
0
mirror of https://github.com/narzoul/DDrawCompat synced 2024-12-30 08:55:36 +01:00

Improved logging of pointers and references

This commit is contained in:
narzoul 2021-10-30 23:53:49 +02:00
parent 62e7dc0850
commit 5eaa79d04c
20 changed files with 621 additions and 356 deletions

View File

@ -171,7 +171,8 @@ namespace
break;
}
#ifdef DEBUGLOGS
oss << Compat::hexDump(prevTargetFunc, instructionSize) << " -> " << Compat::funcPtrToStr(targetFunc) << ' ';
Compat::LogStream(oss) << Compat::hexDump(prevTargetFunc, instructionSize) << " -> "
<< Compat::funcPtrToStr(targetFunc) << ' ';
#endif
prevTargetFunc = targetFunc;
}

View File

@ -1,3 +1,5 @@
#include <string>
#include <Common/Log.h>
#include <Common/Path.h>
@ -6,54 +8,21 @@ namespace
Compat::CriticalSection g_logCs;
}
std::ostream& operator<<(std::ostream& os, std::nullptr_t)
{
return os << "null";
}
std::ostream& operator<<(std::ostream& os, const char* str)
{
if (!str)
{
return os << "null";
}
if (!Compat::Log::isPointerDereferencingAllowed() || reinterpret_cast<DWORD>(str) <= 0xFFFF)
{
return os << static_cast<const void*>(str);
}
return os.write(str, strlen(str));
}
std::ostream& operator<<(std::ostream& os, const unsigned char* data)
{
return os << static_cast<const void*>(data);
}
std::ostream& operator<<(std::ostream& os, const WCHAR* wstr)
{
if (!wstr)
{
return os << "null";
}
if (!Compat::Log::isPointerDereferencingAllowed() || reinterpret_cast<DWORD>(wstr) <= 0xFFFF)
{
return os << static_cast<const void*>(wstr);
}
while (*wstr)
{
os.put(static_cast<char>(*wstr));
++wstr;
}
return os;
}
namespace Compat
{
LogStream operator<<(LogStream os, const void* ptr)
{
if (ptr)
{
os.getStream() << '&' << static_cast<const void*>(ptr);
}
else
{
os.getStream() << "null";
}
return os;
}
Log::Log() : m_lock(g_logCs)
{
SYSTEMTIME st = {};
@ -105,8 +74,7 @@ namespace Compat
}
thread_local DWORD Log::s_indent = 0;
thread_local DWORD Log::s_outParamDepth = 0;
thread_local bool Log::s_isLeaveLog = false;
bool Log::s_isLeaveLog = false;
std::ofstream Log::s_logFile;
}

View File

@ -4,7 +4,7 @@
#include <fstream>
#include <functional>
#include <ostream>
#include <string>
#include <tuple>
#include <type_traits>
#include <utility>
@ -17,10 +17,12 @@
#ifdef DEBUGLOGS
#define LOG_DEBUG Compat::Log()
#define LOG_FUNC(...) Compat::LogFunc logFunc(__VA_ARGS__)
#define LOG_FUNC_CUSTOM(funcPtr, ...) Compat::LogFunc<funcPtr> logFunc(__VA_ARGS__)
#define LOG_RESULT(...) logFunc.setResult(__VA_ARGS__)
#else
#define LOG_DEBUG if constexpr (false) Compat::Log()
#define LOG_FUNC(...)
#define LOG_FUNC_CUSTOM(funcPtr, ...)
#define LOG_RESULT(...) __VA_ARGS__
#endif
@ -36,139 +38,208 @@
#define LOG_CONST_CASE(constant) case constant: return os << #constant;
std::ostream& operator<<(std::ostream& os, std::nullptr_t);
std::ostream& operator<<(std::ostream& os, const char* str);
std::ostream& operator<<(std::ostream& os, const unsigned char* data);
std::ostream& operator<<(std::ostream& os, const WCHAR* wstr);
template <typename T1, typename T2>
std::ostream& operator<<(std::ostream & os, const std::pair<T1, T2> & pair)
{
return Compat::LogStruct(os)
<< pair.first
<< pair.second;
}
namespace Compat
{
using ::operator<<;
namespace detail
template <typename T, typename = void>
struct IsPrintable : std::false_type
{
using ::operator<<;
};
template <typename Elem>
struct Array
template <typename T>
struct IsPrintable<T, decltype(std::declval<std::ostream&>() << std::declval<T>(), void())> : std::true_type
{
};
template<typename T>
struct IsString : std::disjunction<
std::is_same<char*, std::decay_t<T>>,
std::is_same<const char*, std::decay_t<T>>,
std::is_same<wchar_t*, std::decay_t<T>>,
std::is_same<const wchar_t*, std::decay_t<T>>,
std::is_same<std::string, std::decay_t<T>>,
std::is_same<std::wstring, std::decay_t<T>>>
{
};
class LogStream
{
public:
explicit LogStream(std::ostream& os) : m_os(os) {}
std::ostream& getStream() const { return m_os; }
operator std::ostream& () const { return m_os; }
private:
std::ostream& m_os;
};
LogStream operator<<(LogStream os, const void* ptr);
template <typename T>
std::enable_if_t<IsPrintable<const T&>::value || std::is_class_v<T>, LogStream> operator<<(LogStream os, const T& val)
{
if constexpr (IsPrintable<const T&>::value)
{
Array(const Elem* elem, const unsigned long size) : elem(elem), size(size) {}
const Elem* elem;
const unsigned long size;
};
template <typename T>
struct Hex
os.getStream() << val;
}
else
{
explicit Hex(T val) : val(val) {}
T val;
};
os << static_cast<const void*>(&val);
}
return os;
}
struct HexByte
template <typename T>
LogStream operator<<(LogStream os, const T* ptr)
{
if constexpr (std::is_function_v<T>)
{
explicit HexByte(BYTE val) : val(val) {}
BYTE val;
};
template <typename T>
struct Out
os.getStream() << ptr;
}
else if (!ptr)
{
explicit Out(T val) : val(val) {}
T val;
};
class LogParams;
class LogFirstParam
os.getStream() << "null";
}
else if (reinterpret_cast<DWORD>(ptr) <= 0xFFFF)
{
public:
LogFirstParam(std::ostream& os) : m_os(os) {}
template <typename T> LogParams operator<<(const T& val) { m_os << val; return LogParams(m_os); }
protected:
std::ostream& m_os;
};
class LogParams
os << static_cast<const void*>(ptr);
}
else if constexpr (std::is_same_v<T, char> || std::is_same_v<T, wchar_t>)
{
public:
LogParams(std::ostream& os) : m_os(os) {}
template <typename T> LogParams& operator<<(const T& val) { m_os << ',' << val; return *this; }
operator std::ostream&() { return m_os; }
private:
std::ostream& m_os;
};
template <typename Elem>
std::ostream& operator<<(std::ostream& os, Array<Elem> array)
{
os << '[';
if (Log::isPointerDereferencingAllowed())
while (*ptr)
{
if (0 != array.size)
{
os << array.elem[0];
}
for (unsigned long i = 1; i < array.size; ++i)
{
os << ',' << array.elem[i];
}
os.getStream().put(static_cast<char>(*ptr));
++ptr;
}
return os << ']';
}
else if constexpr (std::is_pointer_v<T> || IsPrintable<const T&>::value)
{
os << '*' << *ptr;
}
else
{
os << *ptr;
}
template <typename T>
std::ostream& operator<<(std::ostream& os, Hex<T> hex)
{
return os << "0x" << std::hex << hex.val << std::dec;
}
return os;
}
inline std::ostream& operator<<(std::ostream& os, HexByte hexByte)
{
os.fill('0');
os.width(2);
return os << std::hex << static_cast<DWORD>(hexByte.val) << std::dec;
}
template <typename T>
LogStream operator<<(LogStream os, T* ptr)
{
return os << static_cast<const T*>(ptr);
}
template <typename T>
std::ostream& operator<<(std::ostream& os, Out<T> out)
{
++Log::s_outParamDepth;
os << out.val;
--Log::s_outParamDepth;
return os;
}
template <typename T1, typename T2>
LogStream operator<<(LogStream os, const std::pair<T1, T2>& pair)
{
return Compat::LogStruct(os)
<< pair.first
<< pair.second;
}
template <typename Elem>
detail::Array<Elem> array(const Elem* elem, const unsigned long size)
struct Array
{
return detail::Array<Elem>(elem, size);
Array(const Elem* elem, const unsigned long size) : elem(elem), size(size) {}
const Elem* elem;
const unsigned long size;
};
template <typename T>
struct Hex
{
explicit Hex(T val) : val(val) {}
T val;
};
struct HexByte
{
explicit HexByte(BYTE val) : val(val) {}
BYTE val;
};
template <typename T>
struct Out
{
explicit Out(const T& val) : val(val) {}
const T& val;
};
template <typename Elem>
Array<Elem> array(const Elem* elem, const unsigned long size)
{
return Array<Elem>(elem, size);
}
template <typename T> detail::Hex<T> hex(T val)
template <typename T>
const void* getOutPtr(const T* val)
{
return detail::Hex<T>(val);
return val;
}
inline detail::Array<detail::HexByte> hexDump(const void* buf, const unsigned long size)
template <typename Elem>
const void* getOutPtr(const Array<Elem>& val)
{
return detail::Array<detail::HexByte>(static_cast<const detail::HexByte*>(buf), size);
return val.elem;
}
template <typename T> detail::Out<T> out(const T& val)
template <typename T>
Hex<T> hex(T val)
{
return detail::Out<T>(val);
return Hex<T>(val);
}
inline Array<HexByte> hexDump(const void* buf, const unsigned long size)
{
return Array<HexByte>(static_cast<const HexByte*>(buf), size);
}
template <typename T>
Out<T> out(const T& val)
{
return Out<T>(val);
}
template <typename Elem>
LogStream operator<<(LogStream os, Array<Elem> array)
{
os << '[';
if (0 != array.size)
{
os << array.elem[0];
}
for (unsigned long i = 1; i < array.size; ++i)
{
os << ',' << array.elem[i];
}
return os << ']';
}
template <typename T>
LogStream operator<<(LogStream os, Hex<T> hex)
{
return os << "0x" << std::hex << hex.val << std::dec;
}
inline LogStream operator<<(LogStream os, HexByte hexByte)
{
auto fill = os.getStream().fill('0');
return os << std::setw(2) << std::hex << static_cast<DWORD>(hexByte.val) << std::dec << std::setfill(fill);
}
template <typename T>
LogStream operator<<(LogStream os, Out<T> out)
{
if (Log::isLeaveLog())
{
os << out.val;
}
else
{
os.getStream() << '<' << getOutPtr(out.val) << '>';
}
return os;
}
class Log
@ -180,139 +251,199 @@ namespace Compat
template <typename T>
Log& operator<<(const T& t)
{
s_logFile << t;
LogStream(s_logFile) << t;
return *this;
}
static void initLogging(std::filesystem::path processPath);
static bool isPointerDereferencingAllowed() { return s_isLeaveLog || 0 == s_outParamDepth; }
protected:
template <typename... Params>
Log(const char* prefix, const char* funcName, Params... params) : Log()
{
s_logFile << prefix << ' ' << funcName << '(';
toList(params...);
s_logFile << ')';
}
static bool isLeaveLog() { return s_isLeaveLog; }
private:
friend class LogFunc;
template <typename T> friend std::ostream& detail::operator<<(std::ostream& os, detail::Out<T> out);
void toList()
{
}
template <typename Param>
void toList(Param param)
{
s_logFile << param;
}
template <typename Param, typename... Params>
void toList(Param firstParam, Params... remainingParams)
{
s_logFile << firstParam << ", ";
toList(remainingParams...);
}
friend class LogFuncBase;
ScopedCriticalSection m_lock;
static thread_local DWORD s_indent;
static thread_local DWORD s_outParamDepth;
static thread_local bool s_isLeaveLog;
static bool s_isLeaveLog;
static std::ofstream s_logFile;
};
class LogFunc
template <auto funcPtr, int paramIndex, typename = decltype(funcPtr)>
class LogParam;
template <int paramIndex>
class LogParam<nullptr, paramIndex, nullptr_t>
{
public:
template <typename... Params>
LogFunc(const char* funcName, Params... params)
: m_printCall([=](Log& log) { log << funcName << '('; log.toList(params...); log << ')'; })
static void log(Log& log, Params&... params)
{
auto& param = std::get<paramIndex>(std::tie(params...));
if constexpr (IsString<decltype(param)>::value)
{
if constexpr (!std::is_class_v<decltype(param)>)
{
if (reinterpret_cast<DWORD>(param) <= 0xFFFF)
{
log << param;
return;
}
}
log << '"' << param << '"';
}
else
{
log << param;
}
}
};
template <auto funcPtr, int paramIndex, typename Result, typename... Params>
class LogParam<funcPtr, paramIndex, Result(WINAPI*)(Params...)>
{
public:
static void log(Log& log, Params... params)
{
LogParam<nullptr, paramIndex>::log(log, params...);
}
};
class LogFuncBase
{
public:
template <typename T>
T setResult(T result)
{
m_logResult = [=](Log& log) { log << std::hex << result << std::dec; };
return result;
}
protected:
template <typename... Params>
LogFuncBase(const char* funcName, std::function<void(Log&)> logParams)
: m_funcName(funcName)
, m_logParams(logParams)
{
Log log;
log << "> ";
m_printCall(log);
logCall(log);
Log::s_indent += 2;
}
~LogFunc()
~LogFuncBase()
{
Log::s_isLeaveLog = true;
Log::s_indent -= 2;
Log log;
log << "< ";
m_printCall(log);
logCall(log);
if (m_printResult)
if (m_logResult)
{
log << " = ";
m_printResult(log);
m_logResult(log);
}
Log::s_isLeaveLog = false;
}
template <typename T>
T setResult(T result)
template <typename Param>
auto packParam(Param&& param)
{
m_printResult = [=](Log& log) { log << std::hex << result << std::dec; };
return result;
if constexpr (std::is_lvalue_reference_v<Param>)
{
return std::cref(param);
}
else
{
return param;
}
}
template <typename... Params>
auto packParams(Params&&... params)
{
return std::make_tuple(packParam(std::forward<Params>(params))...);
}
private:
std::function<void(Log&)> m_printCall;
std::function<void(Log&)> m_printResult;
void logCall(Log& log)
{
log << m_funcName << '(';
m_logParams(log);
log << ')';
}
const char* m_funcName;
std::function<void(Log&)> m_logParams;
std::function<void(Log&)> m_logResult;
};
class LogStruct : public detail::LogFirstParam
template <auto funcPtr = nullptr>
class LogFunc : public LogFuncBase
{
public:
LogStruct(std::ostream& os) : detail::LogFirstParam(os) { m_os << '{'; }
template <typename... Params>
LogFunc(const char* funcName, Params&&... params)
: LogFuncBase(funcName, [&, p = packParams(std::forward<Params>(params)...)](Log& log) { logParams(log, p); })
{
}
private:
template <int paramIndex>
void logParams(Log&)
{
}
template <int paramIndex, typename... Params>
void logParams(Log& log, Params&... params)
{
if constexpr (paramIndex > 0)
{
log << ", ";
}
LogParam<funcPtr, paramIndex>::log(log, params...);
if constexpr (paramIndex + 1 < sizeof...(Params))
{
logParams<paramIndex + 1>(log, params...);
}
}
template <typename Pack>
void logParams(Log& log, const Pack& pack)
{
std::apply([&](auto&... params) { logParams<0>(log, params...); }, pack);
}
};
class LogStruct
{
public:
LogStruct(std::ostream& os) : m_os(os), m_isFirst(true) { m_os << '{'; }
~LogStruct() { m_os << '}'; }
template <typename T>
LogStruct& operator<<(const T& val)
{
if (m_isFirst)
{
m_isFirst = false;
}
else
{
m_os << ',';
}
m_os << val;
return *this;
}
operator LogStream() const { return m_os; }
operator std::ostream& () const { return m_os.getStream(); }
private:
LogStream m_os;
bool m_isFirst;
};
}
template <typename T>
typename std::enable_if<std::is_class<T>::value && !std::is_same<T, std::string>::value, std::ostream&>::type
operator<<(std::ostream& os, const T& t)
{
return os << static_cast<const void*>(&t);
}
template <typename T>
typename std::enable_if<std::is_class<T>::value, std::ostream&>::type
operator<<(std::ostream& os, T* t)
{
if (!t)
{
return os << "null";
}
if (!Compat::Log::isPointerDereferencingAllowed() || reinterpret_cast<DWORD>(t) <= 0xFFFF)
{
return os << static_cast<const void*>(t);
}
return os << *t;
}
template <typename T>
std::ostream& operator<<(std::ostream& os, T** t)
{
if (!t)
{
return os << "null";
}
os << static_cast<const void*>(t);
if (!Compat::Log::isPointerDereferencingAllowed() || reinterpret_cast<DWORD>(t) <= 0xFFFF)
{
return os;
}
return os << '=' << *t;
}

View File

@ -3,6 +3,8 @@
#include <d3d.h>
#include <d3dumddi.h>
#include <D3dDdi/Log/AdapterCallbacksLog.h>
namespace D3dDdi
{
namespace AdapterCallbacks

View File

@ -0,0 +1,17 @@
#include <Common/Log.h>
#include <D3dDdi/Log/AdapterCallbacksLog.h>
std::ostream& operator<<(std::ostream& os, const D3DDDICB_QUERYADAPTERINFO& data)
{
return Compat::LogStruct(os)
<< data.pPrivateDriverData
<< data.PrivateDriverDataSize;
}
std::ostream& operator<<(std::ostream& os, const D3DDDICB_QUERYADAPTERINFO2& data)
{
return Compat::LogStruct(os)
<< data.QueryType
<< data.pPrivateDriverData
<< data.PrivateDriverDataSize;
}

View File

@ -0,0 +1,11 @@
#pragma once
#include <ostream>
#include <d3d.h>
#include <d3dumddi.h>
#include <D3dDdi/Log/CommonLog.h>
std::ostream& operator<<(std::ostream& os, const D3DDDICB_QUERYADAPTERINFO& data);
std::ostream& operator<<(std::ostream& os, const D3DDDICB_QUERYADAPTERINFO2& data);

View File

@ -1,24 +1,6 @@
#include <Common/Log.h>
#include <D3dDdi/Log/AdapterFuncsLog.h>
std::ostream& operator<<(std::ostream& os, const D3DDDI_ALLOCATIONLIST& data)
{
return Compat::LogStruct(os)
<< Compat::hex(data.hAllocation)
<< Compat::hex(data.Value);
}
std::ostream& operator<<(std::ostream& os, const D3DDDI_PATCHLOCATIONLIST& data)
{
return Compat::LogStruct(os)
<< data.AllocationIndex
<< Compat::hex(data.Value)
<< Compat::hex(data.DriverId)
<< Compat::hex(data.AllocationOffset)
<< Compat::hex(data.PatchOffset)
<< Compat::hex(data.SplitOffset);
}
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_CREATEDEVICE& data)
{
return Compat::LogStruct(os)

View File

@ -7,8 +7,6 @@
#include <D3dDdi/Log/CommonLog.h>
std::ostream& operator<<(std::ostream& os, const D3DDDI_ALLOCATIONLIST& data);
std::ostream& operator<<(std::ostream& os, const D3DDDI_PATCHLOCATIONLIST& data);
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_CREATEDEVICE& data);
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_GETCAPS& data);
std::ostream& operator<<(std::ostream& os, D3DDDICAPS_TYPE data);

View File

@ -3,6 +3,24 @@
#include <Common/Log.h>
#include <D3dDdi/Log/CommonLog.h>
std::ostream& operator<<(std::ostream& os, const D3DDDI_ALLOCATIONLIST& data)
{
return Compat::LogStruct(os)
<< Compat::hex(data.hAllocation)
<< Compat::hex(data.Value);
}
std::ostream& operator<<(std::ostream& os, const D3DDDI_PATCHLOCATIONLIST& data)
{
return Compat::LogStruct(os)
<< data.AllocationIndex
<< Compat::hex(data.Value)
<< Compat::hex(data.DriverId)
<< Compat::hex(data.AllocationOffset)
<< Compat::hex(data.PatchOffset)
<< Compat::hex(data.SplitOffset);
}
std::ostream& operator<<(std::ostream& os, const D3DDDI_RATIONAL& val)
{
return Compat::LogStruct(os)

View File

@ -5,5 +5,7 @@
#include <d3d.h>
#include <d3dumddi.h>
std::ostream& operator<<(std::ostream& os, const D3DDDI_ALLOCATIONLIST& data);
std::ostream& operator<<(std::ostream& os, const D3DDDI_PATCHLOCATIONLIST& data);
std::ostream& operator<<(std::ostream& os, const D3DDDI_RATIONAL& val);
std::ostream& operator<<(std::ostream& os, D3DDDIFORMAT val);

View File

@ -15,6 +15,14 @@ std::ostream& operator<<(std::ostream& os, D3DDDI_POOL val)
return os << "D3DDDIPOOL_" << static_cast<DWORD>(val);
}
std::ostream& operator<<(std::ostream& os, const D3DDDI_OPENALLOCATIONINFO& val)
{
return Compat::LogStruct(os)
<< Compat::hex(val.hAllocation)
<< val.pPrivateDriverData
<< val.PrivateDriverDataSize;
}
std::ostream& operator<<(std::ostream& os, const D3DDDI_SURFACEINFO& val)
{
return Compat::LogStruct(os)

View File

@ -8,6 +8,7 @@
#include <D3dDdi/Log/CommonLog.h>
std::ostream& operator<<(std::ostream& os, D3DDDI_POOL val);
std::ostream& operator<<(std::ostream& os, const D3DDDI_OPENALLOCATIONINFO& val);
std::ostream& operator<<(std::ostream& os, const D3DDDI_SURFACEINFO& val);
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_BLT& val);
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_CLEAR& val);

View File

@ -129,6 +129,16 @@ std::ostream& operator<<(std::ostream& os, const D3DKMT_QUERYADAPTERINFO& data)
<< data.PrivateDriverDataSize;
}
std::ostream& operator<<(std::ostream& os, const D3DKMT_SETGAMMARAMP& data)
{
return Compat::LogStruct(os)
<< Compat::hex(data.hDevice)
<< data.VidPnSourceId
<< data.Type
<< static_cast<const void*>(data.pGammaRampRgb256x3x16)
<< data.Size;
}
std::ostream& operator<<(std::ostream& os, const D3DKMT_SETQUEUEDLIMIT& data)
{
return Compat::LogStruct(os)

View File

@ -19,6 +19,7 @@ std::ostream& operator<<(std::ostream& os, const D3DKMT_DESTROYDEVICE& data);
std::ostream& operator<<(std::ostream& os, const D3DKMT_OPENADAPTERFROMHDC& data);
std::ostream& operator<<(std::ostream& os, const D3DKMT_PRESENT& data);
std::ostream& operator<<(std::ostream& os, const D3DKMT_QUERYADAPTERINFO& data);
std::ostream& operator<<(std::ostream& os, const D3DKMT_SETGAMMARAMP& data);
std::ostream& operator<<(std::ostream& os, const D3DKMT_SETQUEUEDLIMIT& data);
std::ostream& operator<<(std::ostream& os, const D3DKMT_SETVIDPNSOURCEOWNER& data);
std::ostream& operator<<(std::ostream& os, const D3DKMT_SETVIDPNSOURCEOWNER1& data);

View File

@ -105,15 +105,13 @@ namespace
void logSrcColorKeySupportFailure(const char* reason, UINT32 resultCode)
{
std::ostringstream oss;
oss << "Source color key support: no (" << reason;
Compat::Log log;
log << "Source color key support: no (" << reason;
if (resultCode)
{
oss << ": " << Compat::hex(resultCode);
log << ": " << Compat::hex(resultCode);
}
oss << ')';
Compat::Log() << oss.str();
log << ')';
}
template <typename TDirectDraw, typename TSurfaceDesc, typename TSurface>

View File

@ -234,6 +234,7 @@
<ClInclude Include="D3dDdi\FormatInfo.h" />
<ClInclude Include="D3dDdi\Hooks.h" />
<ClInclude Include="D3dDdi\KernelModeThunks.h" />
<ClInclude Include="D3dDdi\Log\AdapterCallbacksLog.h" />
<ClInclude Include="D3dDdi\Log\AdapterFuncsLog.h" />
<ClInclude Include="D3dDdi\Log\CommonLog.h" />
<ClInclude Include="D3dDdi\Log\DeviceCallbacksLog.h" />
@ -349,6 +350,7 @@
<ClCompile Include="D3dDdi\FormatInfo.cpp" />
<ClCompile Include="D3dDdi\Hooks.cpp" />
<ClCompile Include="D3dDdi\KernelModeThunks.cpp" />
<ClCompile Include="D3dDdi\Log\AdapterCallbacksLog.cpp" />
<ClCompile Include="D3dDdi\Log\AdapterFuncsLog.cpp" />
<ClCompile Include="D3dDdi\Log\CommonLog.cpp" />
<ClCompile Include="D3dDdi\Log\DeviceCallbacksLog.cpp" />

View File

@ -492,6 +492,9 @@
<ClInclude Include="Overlay\ComboBoxDropDown.h">
<Filter>Header Files\Overlay</Filter>
</ClInclude>
<ClInclude Include="D3dDdi\Log\AdapterCallbacksLog.h">
<Filter>Header Files\D3dDdi\Log</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Gdi\Gdi.cpp">
@ -779,6 +782,9 @@
<ClCompile Include="Overlay\ComboBoxDropDown.cpp">
<Filter>Source Files\Overlay</Filter>
</ClCompile>
<ClCompile Include="D3dDdi\Log\AdapterCallbacksLog.cpp">
<Filter>Source Files\D3dDdi\Log</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="DDrawCompat.rc">

View File

@ -9,6 +9,109 @@
#include <Gdi/VirtualScreen.h>
#include <Win32/DisplayMode.h>
namespace
{
template <typename Char>
void logString(Compat::Log& log, const Char* str, int length)
{
log << '"';
if (length < 0)
{
log << str;
}
else
{
for (int i = 0; i < length; ++i)
{
log << static_cast<char>(str[i]);
}
}
log << '"';
}
template <typename Char>
void logExtTextOutString(Compat::Log& log, UINT options, const Char* lpString, UINT c)
{
if (options & ETO_GLYPH_INDEX)
{
log << static_cast<const void*>(lpString);
}
else
{
logString(log, lpString, c);
}
}
}
namespace Compat
{
template <>
void LogParam<&DrawEscape, 3>::log(Log& log, HDC, int, int, LPCSTR lpIn)
{
log << static_cast<const void*>(lpIn);
}
template <>
void LogParam<&DrawTextA, 1>::log(Log& log, HDC, LPCSTR lpchText, int cchText, LPRECT, UINT)
{
logString(log, lpchText, cchText);
}
template <>
void LogParam<&DrawTextW, 1>::log(Log& log, HDC, LPCWSTR lpchText, int cchText, LPRECT, UINT)
{
logString(log, lpchText, cchText);
}
template <>
void LogParam<&DrawTextExA, 1>::log(Log& log, HDC, LPSTR lpchText, int cchText, LPRECT, UINT, LPDRAWTEXTPARAMS)
{
logString(log, lpchText, cchText);
}
template <>
void LogParam<&DrawTextExW, 1>::log(Log& log, HDC, LPWSTR lpchText, int cchText, LPRECT, UINT, LPDRAWTEXTPARAMS)
{
logString(log, lpchText, cchText);
}
template <>
void LogParam<&ExtTextOutA, 5>::log(Log& log, HDC, int, int, UINT options, const RECT*, LPCSTR lpString, UINT c, const INT*)
{
logExtTextOutString(log, options, lpString, c);
}
template <>
void LogParam<&ExtTextOutW, 5>::log(Log& log, HDC, int, int, UINT options, const RECT*, LPCWSTR lpString, UINT c, const INT*)
{
logExtTextOutString(log, options, lpString, c);
}
template <>
void LogParam<&TabbedTextOutA, 3>::log(Log& log, HDC, int, int, LPCSTR lpString, int chCount, int, const INT*, int)
{
logString(log, lpString, chCount);
}
template <>
void LogParam<&TabbedTextOutW, 3>::log(Log& log, HDC, int, int, LPCWSTR lpString, int chCount, int, const INT*, int)
{
logString(log, lpString, chCount);
}
template <>
void LogParam<&TextOutA, 3>::log(Log& log, HDC, int, int, LPCSTR lpString, int c)
{
logString(log, lpString, c);
}
template <>
void LogParam<&TextOutW, 3>::log(Log& log, HDC, int, int, LPCWSTR lpString, int c)
{
logString(log, lpString, c);
}
}
namespace
{
template <auto func>
@ -94,7 +197,7 @@ namespace
template <auto origFunc, typename Result, typename... Params>
Result WINAPI compatGdiDcFunc(HDC hdc, Params... params)
{
LOG_FUNC(g_funcName<origFunc>, hdc, params...);
LOG_FUNC_CUSTOM(origFunc, g_funcName<origFunc>, hdc, params...);
if (hasDisplayDcArg(hdc, params...))
{
@ -116,7 +219,7 @@ namespace
BOOL WINAPI compatGdiDcFunc<&ExtTextOutW>(
HDC hdc, int x, int y, UINT options, const RECT* lprect, LPCWSTR lpString, UINT c, const INT* lpDx)
{
LOG_FUNC("ExtTextOutW", hdc, x, y, options, lprect, lpString, c, lpDx);
LOG_FUNC_CUSTOM(&ExtTextOutW, "ExtTextOutW", hdc, x, y, options, lprect, lpString, c, lpDx);
if (hasDisplayDcArg(hdc))
{

View File

@ -6,6 +6,28 @@
namespace
{
template <typename T>
class ParamConverter
{
public:
template <typename Param>
static T& convert(Param& param)
{
return *reinterpret_cast<T*>(&param);
}
};
template <typename T>
class ParamConverter<Compat::Out<T>>
{
public:
template <typename Param>
static Compat::Out<T> convert(Param& param)
{
return Compat::out(ParamConverter<T>::convert(param));
}
};
template <typename CreateStruct>
std::ostream& logCreateStruct(std::ostream& os, const CreateStruct& cs)
{
@ -139,16 +161,13 @@ std::ostream& operator<<(std::ostream& os, const GESTURENOTIFYSTRUCT& gns)
<< gns.dwInstanceID;
}
std::ostream& operator<<(std::ostream& os, HDC dc)
std::ostream& operator<<(std::ostream& os, const HDC__& dc)
{
os << "DC";
if (!dc)
{
return os << "(null)";
}
HDC hdc = const_cast<HDC>(&dc);
return Compat::LogStruct(os)
<< static_cast<void*>(dc)
<< CALL_ORIG_FUNC(WindowFromDC)(dc);
<< static_cast<void*>(hdc)
<< CALL_ORIG_FUNC(WindowFromDC)(hdc);
}
std::ostream& operator<<(std::ostream& os, const HELPINFO& hi)
@ -172,27 +191,21 @@ std::ostream& operator<<(std::ostream& os, const HELPINFO& hi)
<< hi.MousePos;
}
std::ostream& operator<<(std::ostream& os, HFONT font)
std::ostream& operator<<(std::ostream& os, const HFONT__& font)
{
HFONT hfont = const_cast<HFONT>(&font);
LOGFONT lf = {};
if (font)
{
GetObject(font, sizeof(lf), &lf);
}
GetObject(hfont, sizeof(lf), &lf);
return Compat::LogStruct(os)
<< static_cast<void*>(font)
<< (font ? &lf : nullptr);
<< static_cast<void*>(hfont)
<< lf;
}
std::ostream& operator<<(std::ostream& os, HRGN rgn)
std::ostream& operator<<(std::ostream& os, const HRGN__& rgn)
{
os << "RGN";
if (!rgn)
{
return os << "(null)";
}
DWORD size = GetRegionData(rgn, 0, nullptr);
HRGN hrgn = const_cast<HRGN>(&rgn);
DWORD size = GetRegionData(hrgn, 0, nullptr);
if (0 == size)
{
return os << "[]";
@ -200,19 +213,16 @@ std::ostream& operator<<(std::ostream& os, HRGN rgn)
std::vector<unsigned char> rgnDataBuf(size);
auto& rgnData = *reinterpret_cast<RGNDATA*>(rgnDataBuf.data());
GetRegionData(rgn, size, &rgnData);
GetRegionData(hrgn, size, &rgnData);
return os << Compat::array(reinterpret_cast<RECT*>(rgnData.Buffer), rgnData.rdh.nCount);
Compat::LogStream(os) << Compat::array(reinterpret_cast<RECT*>(rgnData.Buffer), rgnData.rdh.nCount);
return os;
}
std::ostream& operator<<(std::ostream& os, HWND hwnd)
std::ostream& operator<<(std::ostream& os, const HWND__& wnd)
{
os << "WND";
if (!hwnd)
{
return os << "(null)";
}
HWND hwnd = const_cast<HWND>(&wnd);
if (!IsWindow(hwnd))
{
return Compat::LogStruct(os)
@ -409,7 +419,7 @@ std::ostream& operator<<(std::ostream& os, const WINDOWPOS& wp)
namespace Compat
{
std::ostream& operator<<(std::ostream& os, WindowMessage msg)
LogStream operator<<(LogStream os, WindowMessage msg)
{
#define LOG_WM_CASE(msg) case msg: return os << #msg;
switch (msg.msg)
@ -659,33 +669,31 @@ namespace Compat
};
#undef LOG_WM_CASE
os.width(4);
os.fill('0');
os << "WM_" << std::hex << msg.msg << std::dec;
return os;
return os << "WM_" << std::hex << msg.msg << std::dec;
}
std::ostream& operator<<(std::ostream& os, WindowMessage16 msg)
LogStream operator<<(LogStream os, WindowMessage16 msg)
{
return os << WindowMessage(msg.msg);
}
std::ostream& operator<<(std::ostream& os, WindowMessageStruct wm)
LogStream operator<<(LogStream os, WindowMessageStruct wm)
{
os << '{' << wm.hwnd << ',' << wm.msg << ',';
Compat::LogStruct log(os);
log << wm.hwnd << wm.msg;
#define LOG_PARAM_CASE_1(param, msg, ...) \
case msg: \
static_assert(sizeof(__VA_ARGS__) == sizeof(param)); \
os << *reinterpret_cast<const __VA_ARGS__*>(&param); \
log << ParamConverter<__VA_ARGS__>::convert(param); \
break
#define LOG_PARAM_CASE_2(param, msg, TypeA, TypeW) \
case msg: \
if (IsWindowUnicode(wm.hwnd)) \
os << *reinterpret_cast<const TypeW*>(&param); \
log << ParamConverter<TypeW>::convert(param); \
else \
os << *reinterpret_cast<const TypeA*>(&param); \
log << ParamConverter<TypeA>::convert(param); \
break;
#define LOG_WPARAM_CASE_1(msg, ...) LOG_PARAM_CASE_1(wm.wParam, msg, __VA_ARGS__)
@ -697,7 +705,7 @@ namespace Compat
LOG_WPARAM_CASE_1(WM_APPCOMMAND, HWND);
LOG_WPARAM_CASE_1(WM_ASKCBFORMATNAME, DWORD);
LOG_WPARAM_CASE_1(WM_CHANGECBCHAIN, HWND);
LOG_WPARAM_CASE_1(WM_CHANGEUISTATE, std::pair<WORD, Compat::detail::Hex<WORD>>);
LOG_WPARAM_CASE_1(WM_CHANGEUISTATE, std::pair<WORD, Hex<WORD>>);
LOG_WPARAM_CASE_1(WM_CHARTOITEM, std::pair<WORD, WORD>);
LOG_WPARAM_CASE_1(WM_CTLCOLORMSGBOX, HDC);
LOG_WPARAM_CASE_1(WM_CTLCOLOREDIT, HDC);
@ -706,7 +714,7 @@ namespace Compat
LOG_WPARAM_CASE_1(WM_CTLCOLORDLG, HDC);
LOG_WPARAM_CASE_1(WM_CTLCOLORSCROLLBAR, HDC);
LOG_WPARAM_CASE_1(WM_CTLCOLORSTATIC, HDC);
LOG_WPARAM_CASE_1(WM_COMMAND, std::pair<Compat::detail::Hex<WORD>, WORD>);
LOG_WPARAM_CASE_1(WM_COMMAND, std::pair<Hex<WORD>, WORD>);
LOG_WPARAM_CASE_1(WM_CONTEXTMENU, HWND);
LOG_WPARAM_CASE_1(WM_COPYDATA, HWND);
LOG_WPARAM_CASE_1(WM_DISPLAYCHANGE, INT);
@ -726,14 +734,14 @@ namespace Compat
LOG_WPARAM_CASE_1(WM_MDIMAXIMIZE, HWND);
LOG_WPARAM_CASE_1(WM_MDINEXT, HWND);
LOG_WPARAM_CASE_1(WM_MDIRESTORE, HWND);
LOG_WPARAM_CASE_1(WM_MENUCHAR, std::pair<Compat::detail::Hex<WORD>, Compat::detail::Hex<WORD>>);
LOG_WPARAM_CASE_1(WM_MENUCHAR, std::pair<Hex<WORD>, Hex<WORD>>);
LOG_WPARAM_CASE_1(WM_MENUCOMMAND, DWORD);
LOG_WPARAM_CASE_1(WM_MENUDRAG, DWORD);
LOG_WPARAM_CASE_1(WM_MENURBUTTONUP, DWORD);
LOG_WPARAM_CASE_1(WM_MENUSELECT, std::pair<WORD, Compat::detail::Hex<WORD>>);
LOG_WPARAM_CASE_1(WM_MENUSELECT, std::pair<WORD, Hex<WORD>>);
LOG_WPARAM_CASE_1(WM_MOUSEACTIVATE, HWND);
LOG_WPARAM_CASE_1(WM_MOUSEHWHEEL, std::pair<Compat::detail::Hex<WORD>, SHORT>);
LOG_WPARAM_CASE_1(WM_MOUSEWHEEL, std::pair<Compat::detail::Hex<WORD>, SHORT>);
LOG_WPARAM_CASE_1(WM_MOUSEHWHEEL, std::pair<Hex<WORD>, SHORT>);
LOG_WPARAM_CASE_1(WM_MOUSEWHEEL, std::pair<Hex<WORD>, SHORT>);
LOG_WPARAM_CASE_1(WM_NCLBUTTONDBLCLK, INT);
LOG_WPARAM_CASE_1(WM_NCLBUTTONDOWN, INT);
LOG_WPARAM_CASE_1(WM_NCLBUTTONUP, INT);
@ -746,51 +754,51 @@ namespace Compat
LOG_WPARAM_CASE_1(WM_NCPOINTERDOWN, std::pair<WORD, SHORT>);
LOG_WPARAM_CASE_1(WM_NCPOINTERUP, std::pair<WORD, SHORT>);
LOG_WPARAM_CASE_1(WM_NCPOINTERUPDATE, std::pair<WORD, SHORT>);
LOG_WPARAM_CASE_1(WM_NCXBUTTONDBLCLK, std::pair<Compat::detail::Hex<WORD>, WORD>);
LOG_WPARAM_CASE_1(WM_NCXBUTTONDOWN, std::pair<Compat::detail::Hex<WORD>, WORD>);
LOG_WPARAM_CASE_1(WM_NCXBUTTONUP, std::pair<Compat::detail::Hex<WORD>, WORD>);
LOG_WPARAM_CASE_1(WM_NCXBUTTONDBLCLK, std::pair<Hex<WORD>, WORD>);
LOG_WPARAM_CASE_1(WM_NCXBUTTONDOWN, std::pair<Hex<WORD>, WORD>);
LOG_WPARAM_CASE_1(WM_NCXBUTTONUP, std::pair<Hex<WORD>, WORD>);
LOG_WPARAM_CASE_1(WM_NOTIFYFORMAT, HWND);
LOG_WPARAM_CASE_1(WM_PALETTECHANGED, HWND);
LOG_WPARAM_CASE_1(WM_PALETTEISCHANGING, HWND);
LOG_WPARAM_CASE_1(WM_PARENTNOTIFY, std::pair<WindowMessage16, Compat::detail::Hex<WORD>>);
LOG_WPARAM_CASE_1(WM_PARENTNOTIFY, std::pair<WindowMessage16, Hex<WORD>>);
LOG_WPARAM_CASE_1(WM_POINTERACTIVATE, std::pair<WORD, SHORT>);
LOG_WPARAM_CASE_1(WM_POINTERDOWN, std::pair<WORD, Compat::detail::Hex<WORD>>);
LOG_WPARAM_CASE_1(WM_POINTERENTER, std::pair<WORD, Compat::detail::Hex<WORD>>);
LOG_WPARAM_CASE_1(WM_POINTERDOWN, std::pair<WORD, Hex<WORD>>);
LOG_WPARAM_CASE_1(WM_POINTERENTER, std::pair<WORD, Hex<WORD>>);
LOG_WPARAM_CASE_1(WM_POINTERHWHEEL, std::pair<WORD, SHORT>);
LOG_WPARAM_CASE_1(WM_POINTERLEAVE, std::pair<WORD, Compat::detail::Hex<WORD>>);
LOG_WPARAM_CASE_1(WM_POINTERUP, std::pair<WORD, Compat::detail::Hex<WORD>>);
LOG_WPARAM_CASE_1(WM_POINTERUPDATE, std::pair<WORD, Compat::detail::Hex<WORD>>);
LOG_WPARAM_CASE_1(WM_POINTERLEAVE, std::pair<WORD, Hex<WORD>>);
LOG_WPARAM_CASE_1(WM_POINTERUP, std::pair<WORD, Hex<WORD>>);
LOG_WPARAM_CASE_1(WM_POINTERUPDATE, std::pair<WORD, Hex<WORD>>);
LOG_WPARAM_CASE_1(WM_POINTERWHEEL, std::pair<WORD, SHORT>);
LOG_WPARAM_CASE_1(WM_PRINT, HDC);
LOG_WPARAM_CASE_1(WM_PRINTCLIENT, HDC);
LOG_WPARAM_CASE_1(WM_SETFOCUS, HWND);
LOG_WPARAM_CASE_1(WM_SETFONT, HFONT);
LOG_WPARAM_CASE_1(WM_SETHOTKEY, std::pair<Compat::detail::Hex<WORD>, Compat::detail::Hex<WORD>>);
LOG_WPARAM_CASE_1(WM_SETHOTKEY, std::pair<Hex<WORD>, Hex<WORD>>);
LOG_WPARAM_CASE_1(WM_SETTEXT, DWORD);
LOG_WPARAM_CASE_1(WM_SIZECLIPBOARD, HWND);
LOG_WPARAM_CASE_1(WM_STYLECHANGED, INT);
LOG_WPARAM_CASE_1(WM_STYLECHANGING, INT);
LOG_WPARAM_CASE_1(WM_UPDATEUISTATE, std::pair<WORD, Compat::detail::Hex<WORD>>);
LOG_WPARAM_CASE_1(WM_VKEYTOITEM, std::pair<Compat::detail::Hex<WORD>, WORD>);
LOG_WPARAM_CASE_1(WM_UPDATEUISTATE, std::pair<WORD, Hex<WORD>>);
LOG_WPARAM_CASE_1(WM_VKEYTOITEM, std::pair<Hex<WORD>, WORD>);
LOG_WPARAM_CASE_1(WM_VSCROLL, std::pair<WORD, WORD>);
LOG_WPARAM_CASE_1(WM_VSCROLLCLIPBOARD, HWND);
LOG_WPARAM_CASE_1(WM_XBUTTONDBLCLK, std::pair<Compat::detail::Hex<WORD>, WORD>);
LOG_WPARAM_CASE_1(WM_XBUTTONDOWN, std::pair<Compat::detail::Hex<WORD>, WORD>);
LOG_WPARAM_CASE_1(WM_XBUTTONUP, std::pair<Compat::detail::Hex<WORD>, WORD>);
LOG_WPARAM_CASE_1(WM_XBUTTONDBLCLK, std::pair<Hex<WORD>, WORD>);
LOG_WPARAM_CASE_1(WM_XBUTTONDOWN, std::pair<Hex<WORD>, WORD>);
LOG_WPARAM_CASE_1(WM_XBUTTONUP, std::pair<Hex<WORD>, WORD>);
case WM_NEXTDLGCTL:
if (wm.lParam)
{
os << reinterpret_cast<HWND>(wm.wParam);
log << reinterpret_cast<HWND>(wm.wParam);
}
else
{
os << wm.wParam;
log << wm.wParam;
}
break;
default:
os << Compat::hex(wm.wParam);
log << hex(wm.wParam);
break;
}
@ -800,12 +808,10 @@ namespace Compat
#define LOG_LPARAM_CASE_1(msg, ...) LOG_PARAM_CASE_1(wm.lParam, msg, __VA_ARGS__)
#define LOG_LPARAM_CASE_2(msg, TypeA, TypeW) LOG_PARAM_CASE_2(wm.lParam, msg, TypeA, TypeW)
os << ',';
switch (wm.msg.msg)
{
LOG_LPARAM_CASE_1(WM_ACTIVATE, HWND);
LOG_LPARAM_CASE_2(WM_ASKCBFORMATNAME, Compat::detail::Out<LPCSTR>, Compat::detail::Out<LPCWSTR>);
LOG_LPARAM_CASE_2(WM_ASKCBFORMATNAME, Out<LPCSTR>, Out<LPCWSTR>);
LOG_LPARAM_CASE_1(WM_CAPTURECHANGED, HWND);
LOG_LPARAM_CASE_1(WM_CHANGECBCHAIN, HWND);
LOG_LPARAM_CASE_1(WM_CHARTOITEM, HWND);
@ -833,9 +839,9 @@ namespace Compat
LOG_LPARAM_CASE_1(WM_GETDPISCALEDSIZE, SIZE*);
LOG_LPARAM_CASE_1(WM_GETICON, DWORD);
LOG_LPARAM_CASE_1(WM_GETMINMAXINFO, MINMAXINFO*);
LOG_LPARAM_CASE_2(WM_GETTEXT, Compat::detail::Out<LPCSTR>, Compat::detail::Out<LPCWSTR>);
LOG_LPARAM_CASE_2(WM_GETTEXT, Out<LPCSTR>, Out<LPCWSTR>);
LOG_LPARAM_CASE_1(WM_HELP, HELPINFO*);
LOG_LPARAM_CASE_1(WM_HOTKEY, std::pair<Compat::detail::Hex<WORD>, Compat::detail::Hex<WORD>>);
LOG_LPARAM_CASE_1(WM_HOTKEY, std::pair<Hex<WORD>, Hex<WORD>>);
LOG_LPARAM_CASE_1(WM_HSCROLL, HWND);
LOG_LPARAM_CASE_1(WM_HSCROLLCLIPBOARD, std::pair<WORD, WORD>);
LOG_LPARAM_CASE_1(WM_INITMENUPOPUP, std::pair<WORD, WORD>);
@ -849,7 +855,7 @@ namespace Compat
LOG_LPARAM_CASE_1(WM_MDIGETACTIVE, BOOL*);
LOG_LPARAM_CASE_1(WM_MEASUREITEM, MEASUREITEMSTRUCT*);
LOG_LPARAM_CASE_1(WM_MENUGETOBJECT, MENUGETOBJECTINFO*);
LOG_LPARAM_CASE_1(WM_MOUSEACTIVATE, std::pair<SHORT, Compat::detail::Hex<WORD>>);
LOG_LPARAM_CASE_1(WM_MOUSEACTIVATE, std::pair<SHORT, Hex<WORD>>);
LOG_LPARAM_CASE_1(WM_MOUSEHOVER, POINTS);
LOG_LPARAM_CASE_1(WM_MOUSEHWHEEL, POINTS);
LOG_LPARAM_CASE_1(WM_MOUSEMOVE, POINTS);
@ -890,7 +896,7 @@ namespace Compat
LOG_LPARAM_CASE_1(WM_RBUTTONDBLCLK, POINTS);
LOG_LPARAM_CASE_1(WM_RBUTTONDOWN, POINTS);
LOG_LPARAM_CASE_1(WM_RBUTTONUP, POINTS);
LOG_LPARAM_CASE_1(WM_SETCURSOR, std::pair<SHORT, Compat::detail::Hex<WORD>>);
LOG_LPARAM_CASE_1(WM_SETCURSOR, std::pair<SHORT, Hex<WORD>>);
LOG_LPARAM_CASE_2(WM_SETTEXT, LPCSTR, LPCWSTR);
LOG_LPARAM_CASE_2(WM_SETTINGCHANGE, LPCSTR, LPCWSTR);
LOG_LPARAM_CASE_1(WM_SIZE, POINTS);
@ -912,27 +918,27 @@ namespace Compat
case WM_NCACTIVATE:
if (-1 == wm.lParam)
{
os << "-1";
log << "-1";
}
else
{
os << reinterpret_cast<HRGN>(wm.lParam);
log << reinterpret_cast<HRGN>(wm.lParam);
}
break;
case WM_NCCALCSIZE:
if (wm.wParam)
{
os << reinterpret_cast<NCCALCSIZE_PARAMS*>(wm.lParam);
log << reinterpret_cast<NCCALCSIZE_PARAMS*>(wm.lParam);
}
else
{
os << reinterpret_cast<RECT*>(wm.lParam);
log << reinterpret_cast<RECT*>(wm.lParam);
}
break;
default:
os << Compat::hex(wm.lParam);
log << hex(wm.lParam);
break;
}
@ -941,7 +947,6 @@ namespace Compat
#undef LOG_PARAM_CASE_1
#undef LOG_PARAM_CASE_2
os << '}';
return os;
}
}

View File

@ -1,7 +1,6 @@
#pragma once
#include <ostream>
#include <string>
#include <Windows.h>
@ -16,11 +15,11 @@ std::ostream& operator<<(std::ostream& os, const DEVMODEA& dm);
std::ostream& operator<<(std::ostream& os, const DEVMODEW& dm);
std::ostream& operator<<(std::ostream& os, const DRAWITEMSTRUCT& dis);
std::ostream& operator<<(std::ostream& os, const GESTURENOTIFYSTRUCT& gns);
std::ostream& operator<<(std::ostream& os, HDC dc);
std::ostream& operator<<(std::ostream& os, const HDC__& dc);
std::ostream& operator<<(std::ostream& os, const HELPINFO& hi);
std::ostream& operator<<(std::ostream& os, HFONT font);
std::ostream& operator<<(std::ostream& os, HRGN rgn);
std::ostream& operator<<(std::ostream& os, HWND hwnd);
std::ostream& operator<<(std::ostream& os, const HFONT__& font);
std::ostream& operator<<(std::ostream& os, const HRGN__& rgn);
std::ostream& operator<<(std::ostream& os, const HWND__& wnd);
std::ostream& operator<<(std::ostream& os, const LOGFONT& lf);
std::ostream& operator<<(std::ostream& os, const MDICREATESTRUCTA& mcs);
std::ostream& operator<<(std::ostream& os, const MDICREATESTRUCTW& mcs);
@ -43,6 +42,8 @@ std::ostream& operator<<(std::ostream& os, const WINDOWPOS& wp);
namespace Compat
{
class LogStream;
struct WindowMessage
{
UINT msg;
@ -70,7 +71,7 @@ namespace Compat
}
};
std::ostream& operator<<(std::ostream& os, WindowMessage msg);
std::ostream& operator<<(std::ostream& os, WindowMessage16 msg);
std::ostream& operator<<(std::ostream& os, WindowMessageStruct wm);
LogStream operator<<(LogStream os, WindowMessage msg);
LogStream operator<<(LogStream os, WindowMessage16 msg);
LogStream operator<<(LogStream os, WindowMessageStruct wm);
}