#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 ); } 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 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