#ifndef main_H #define main_H #ifdef _DEBUG # include # include # include # ifndef _LTMDB # define _CRTDBG_MAP_ALLOC # include # include # define DEBUG_CLIENTBLOCK new (_CLIENT_BLOCK, __FILE__, __LINE__) # define new DEBUG_CLIENTBLOCK # define _LTMDB # endif #endif #define WIN32_LEAN_AND_MEAN #include #pragma warning(push) #pragma warning(disable : 4091) #include #pragma warning(pop) #define KSGStart __stdcall #include "Globals.h" namespace Framework { //! Speichert die dem Programm vom Betriebssystem beim Start übergebenen //! Parameter struct Startparam { HINSTANCE hinst, hpinst; LPSTR cmd; int show; }; //! Überschreibe diese Funktion. Sie wird vom Framework automatisch beim //! Start des Programmes aufgerufen \param p Die Parameter, die dem Programm //! beim Start vom Betriebssystem übergeben wurden int KSGStart Start(Startparam p); } // namespace Framework typedef BOOL(__stdcall* MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD dwPid, HANDLE hFile, MINIDUMP_TYPE DumpType, CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam); void createMinidump(struct _EXCEPTION_POINTERS* apExceptionInfo) { HMODULE mhLib = ::LoadLibrary("dbghelp.dll"); MINIDUMPWRITEDUMP pDump = mhLib ? (MINIDUMPWRITEDUMP)::GetProcAddress( mhLib, "MiniDumpWriteDump") : 0; HANDLE hFile = ::CreateFile("error_core_memory_dump.dmp", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); _MINIDUMP_EXCEPTION_INFORMATION ExInfo; ExInfo.ThreadId = ::GetCurrentThreadId(); ExInfo.ExceptionPointers = apExceptionInfo; ExInfo.ClientPointers = FALSE; if (pDump) pDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, NULL, NULL); ::CloseHandle(hFile); } LONG WINAPI unhandledHandler(struct _EXCEPTION_POINTERS* apExceptionInfo) { createMinidump(apExceptionInfo); return EXCEPTION_CONTINUE_SEARCH; } #ifdef _DEBUG template class OutputDebugStringBuf : public std::basic_stringbuf { public: explicit OutputDebugStringBuf() : _buffer(1) { __super::setg(nullptr, nullptr, nullptr); __super::setp( _buffer.data(), _buffer.data(), _buffer.data() + _buffer.size()); } ~OutputDebugStringBuf() {} static_assert( std::is_same::value || std::is_same::value, "OutputDebugStringBuf only supports char and wchar_t types"); int sync() try { MessageOutputer()(__super::pbase(), __super::pptr()); __super::setp( _buffer.data(), _buffer.data(), _buffer.data() + _buffer.size()); return 0; } catch (...) { return -1; } int overflow(int c = TTraits::eof()) { auto syncRet = sync(); if (c != TTraits::eof()) { _buffer[0] = c; __super::setp(_buffer.data(), _buffer.data() + 1, _buffer.data() + _buffer.size()); } return syncRet == -1 ? TTraits::eof() : 0; } private: std::vector _buffer; template struct MessageOutputer; template<> struct MessageOutputer> { template void operator()(TIterator begin, TIterator end) const { std::string s(begin, end); OutputDebugStringA(s.c_str()); } }; template<> struct MessageOutputer> { template void operator()(TIterator begin, TIterator end) const { std::wstring s(begin, end); OutputDebugStringW(s.c_str()); } }; }; #endif #ifndef NO_MAIN int WINAPI WinMain(_In_ HINSTANCE hinst, _In_opt_ HINSTANCE hpinst, _In_ LPSTR cmd, int _In_ show) { # ifdef _DEBUG _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); OutputDebugStringBuf> charDebugOutput; std::streambuf* buf = std::cout.rdbuf(); std::cout.rdbuf(&charDebugOutput); # endif SetUnhandledExceptionFilter(unhandledHandler); Framework::initFramework(hinst); Framework::Startparam stp; stp.hinst = hinst; stp.hpinst = hpinst; stp.cmd = cmd; stp.show = show; int ret = Framework::Start(stp); Framework::releaseFramework(); # ifdef _DEBUG std::cout.rdbuf(buf); # endif return ret; } #endif #endif