int RunWinMain(HINSTANCE hInstance, LPTSTR lpstrCmdLine, int nCmdShow) { // DLL攻撃対策 SetDllDirectory(_T("")); #if 0 #if defined (_DEBUG) && defined(_CRTDBG_MAP_ALLOC) //メモリリーク検出用 _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT); _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CRTDBG_CHECK_ALWAYS_DF ); //_CrtSetBreakAlloc(874); #endif #endif #if defined (_DEBUG) && defined(_CRTDBG_MAP_ALLOC) _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); #endif #ifdef _DEBUG // ATLTRACEで日本語を使うために必要 _tsetlocale( LC_ALL, _T("japanese") ); #endif Misc::setHeapAllocLowFlagmentationMode(); //+++ // 設定ファイルのフルパスを取得する MtlIniFileNameInit(g_szIniFileName, MAX_PATH); // 複数起動の確認 if (CheckOneInstance(lpstrCmdLine)) return 0; g_pMainWnd = NULL; // HRESULT hRes = ::CoInitialize(NULL); HRESULT hRes = ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); // ATLASSERT( SUCCEEDED(hRes) ); // If you are running on NT 4.0 or higher you can use the following call instead to // make the EXE free threaded. This means that calls come in on a random RPC thread // HRESULT hRes = ::CoInitializeEx(NULL, COINIT_MULTITHREADED); hRes = ::OleInitialize(NULL); ATLASSERT( SUCCEEDED(hRes) ); ATLTRACE(_T("tWinMain\n") _T("CommandLine : %s\n"), lpstrCmdLine); /* コモンコントロールを初期化 */ INITCOMMONCONTROLSEX iccx; iccx.dwSize = sizeof (iccx); iccx.dwICC = ICC_COOL_CLASSES | ICC_BAR_CLASSES | ICC_USEREX_CLASSES; int ret = ::InitCommonControlsEx(&iccx); ATLASSERT(ret); hRes = _Module.Init(ObjectMap, hInstance, &LIBID_ATLLib); //hRes = _Module.Init(NULL, hInstance); ATLASSERT( SUCCEEDED(hRes) ); int nRet = 0; bool bRun = true; bool bAutomation = false; bool bTray = false; bool bRet = _PrivateInit(); if (!bRet) { ErrorLogPrintf(_T("_PrivateInitでエラー\n")); nRet = -1; } // Init CEF CefSettings settings; settings.multi_threaded_message_loop = true; std::wstring strCachePath = CMainOption::s_strCacheFolderPath; if (strCachePath.empty()) { strCachePath = static_cast<LPCWSTR>(Misc::GetExeDirectory() + _T("cache")); } CefString(&settings.cache_path).FromWString(strCachePath); CefString(&settings.locale).FromWString(std::wstring(L"ja")); //settings.auto_detect_proxy_settings_enabled = true; ATLVERIFY(CefInitialize(settings, nullptr)); if (nRet < 0) goto END_APP; // ActiveXコントロールをホストするための準備 //AtlAxWinInit(); // コマンドライン入力によってはCOMサーバー登録及び解除を行う nRet = RegisterCOMServer(nRet, bRun, bAutomation, bTray); if (FAILED(nRet)) { ErrorLogPrintf(_T("RegisterCOMServerでエラー\n")); nRet = -1; goto END_APP; } CDonutSimpleEventManager::RaiseEvent(EVENT_PROCESS_START); if (bRun) { _Module.StartMonitor(); hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE | REGCLS_SUSPENDED); ATLASSERT( SUCCEEDED(hRes) ); hRes = ::CoResumeClassObjects(); ATLASSERT( SUCCEEDED(hRes) ); if (bAutomation) { CMessageLoop theLoop; nRet = theLoop.Run(); } else { //+++ 起動時の環境ファイルチェック. unDonut.iniがなく // 環境ファイルが足りてなかったら起動ページをabout:warningにする. if (lpstrCmdLine == 0 || lpstrCmdLine[0] == 0) { if (HaveEnvFiles() == false) lpstrCmdLine = _T("about:warning"); } //\\nRet = Run(lpstrCmdLine, nCmdShow, bTray); //nRet = MultiThreadManager::Run(lpstrCmdLine, nCmdShow, bTray); //int nRet = 0; { CMessageLoop theLoop; _Module.AddMessageLoop(&theLoop); CMainFrame wndMain; if (wndMain.CreateEx() == NULL) { ATLTRACE( _T("Main window creation failed!\n") ); return 0; } // load windowplacement wndMain.startupMainFrameStayle(nCmdShow, /*bTray*/false); _Module.Lock(); if (CStartUpOption::s_dwParam) CStartUpOption::StartUp(wndMain); if (lpstrCmdLine && lpstrCmdLine[0] != _T('\0')) CommandLineArg(wndMain, lpstrCmdLine); wndMain.SetAutoBackUp(); //自動更新するなら、開始. // 実際のメインループ. nRet = theLoop.Run(); _Module.RemoveMessageLoop(); } } #if 1 //+++ WTLのメイン窓クローズが正常終了時に、終了コードとして1を返す... //+++ OSに返す値なので0のほうがよいはずで、 //+++ donutの他の部分では0にしているようなので //+++ しかたないので、強制的に変換. if (nRet == 1) nRet = 0; #endif _Module.RevokeClassObjects(); ::Sleep(_Module.m_dwPause); } //_PrivateTerm(); ATLTRACE(_T("正常終了しました。\n")); END_APP: _Module.Term(); ::OleUninitialize(); ::CoUninitialize(); // Shut down CEF. DWORD dwTime = ::timeGetTime(); boost::thread terminateWatch([dwTime]() { while (dwTime + (5 * 1000) > ::timeGetTime()) { if (g_bSefShutDown) return ; ::Sleep(0); } if (g_bSefShutDown == false) ExitProcess(-5); }); CefShutdown(); g_bSefShutDown = true; CDonutSimpleEventManager::RaiseEvent(EVENT_PROCESS_END); return nRet; }
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow) { HRESULT hRes = ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); ATLASSERT(SUCCEEDED(hRes)); #if (_WIN32_IE >= 0x0300) INITCOMMONCONTROLSEX iccx; iccx.dwSize = sizeof(iccx); iccx.dwICC = ICC_BAR_CLASSES; // change to support other controls BOOL bRet = ::InitCommonControlsEx(&iccx); bRet; ATLASSERT(bRet); #else ::InitCommonControls(); #endif hRes = _Module.Init(ObjectMap, hInstance); ATLASSERT(SUCCEEDED(hRes)); int nRet = 0; TCHAR szTokens[] = _T("-/"); bool bRun = true; bool bAutomation = false; LPCTSTR lpszToken = _Module.FindOneOf(::GetCommandLine(), szTokens); while(lpszToken != NULL) { if(lstrcmpi(lpszToken, _T("UnregServer")) == 0) { _Module.UpdateRegistryFromResource(IDR_DP, FALSE); nRet = _Module.UnregisterServer(TRUE); bRun = false; break; } else if(lstrcmpi(lpszToken, _T("RegServer")) == 0) { // Already registered... bRun = false; break; } else if((lstrcmpi(lpszToken, _T("Automation")) == 0) || (lstrcmpi(lpszToken, _T("Embedding")) == 0)) { bAutomation = true; break; } lpszToken = _Module.FindOneOf(lpszToken, szTokens); } if(bRun) { if(!bAutomation && CSingleInstance::Instance().IsAlreadyRunning()) { // Only attempt this if manually started, i.e. allow automation // clients to start multiple instances, for what it's worth if(!CSingleInstance::Instance().ActivateRunningInstance()) { MessageBox(NULL, _T("Failed to activate running instance of Developer Playground.\nPlease use Task Manager or similar to terminate rogue DP processes."), _T("DP Error"), MB_OK); } } else { if(!bAutomation) { // Auto-register self at startup, if manually started _Module.UpdateRegistryFromResource(IDR_DP, TRUE); nRet = _Module.RegisterServer(TRUE); } DWORD dwThreadId = 0; SmartHandle hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); SmartHandle hThread = CreateThread(NULL, 0, FactoryThreadProc, hEvent, 0, &dwThreadId); _Module.StartMonitor(); if(bAutomation) { CMessageLoop theLoop; nRet = theLoop.Run(); } else { nRet = Run(lpstrCmdLine, nCmdShow); } SetEvent(hEvent); ::Sleep(_Module.m_dwPause); } } _Module.Term(); ::CoUninitialize(); return nRet; }