diff --git a/GME/Gme/GME.rc b/GME/Gme/GME.rc index ab653327..7e6fcf79 100644 --- a/GME/Gme/GME.rc +++ b/GME/Gme/GME.rc @@ -1,21 +1,17 @@ // Microsoft Visual C++ generated resource script. // -#include "resource.h" - +#include "resource.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #include "afxres.h" -#include "GMEVersion.h" - +#include "GMEVersion.h" ///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - +#undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// -// English (United States) resources - +// English (United States) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) @@ -255,6 +251,8 @@ BEGIN END POPUP "&Help" BEGIN + MENUITEM "&Paradigm Help", ID_HELP_PARADIGMHELP + MENUITEM "C&omponent Help", ID_HELP_COMPONENTHELP MENUITEM "&Contents", ID_HELP_CONTENTS MENUITEM "&About GME...", ID_APP_ABOUT END @@ -396,6 +394,8 @@ BEGIN END POPUP "&Help" BEGIN + MENUITEM "&Paradigm Help", ID_HELP_PARADIGMHELP + MENUITEM "C&omponent Help", ID_HELP_COMPONENTHELP MENUITEM "&Contents", ID_HELP_CONTENTS MENUITEM "&Help", ID_HELP_HELP MENUITEM "&About GME...", ID_APP_ABOUT @@ -1788,5 +1788,4 @@ LANGUAGE 9, 1 #endif 1 TYPELIB "GmeLib.tlb" ///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - +#endif // not APSTUDIO_INVOKED \ No newline at end of file diff --git a/GME/Gme/GMEApp.cpp b/GME/Gme/GMEApp.cpp index 1a9acb3a..5be09ab7 100644 --- a/GME/Gme/GMEApp.cpp +++ b/GME/Gme/GMEApp.cpp @@ -1,3364 +1,3526 @@ -// GMEApp.cpp : Defines the class behaviors for the application. -// - -#include "stdafx.h" -#include // for CWaitCursor -#include "GMEApp.h" -#include "GMEVersion.h" - - -#include "Parser.h" - -#include "GMEstd.h" -#include "GuiMeta.h" -#include "MainFrm.h" -#include "ChildFrm.h" -#include "GMEDoc.h" -#include "GMEView.h" -#include "GMEChildFrame.h" -#include "GMEBrowser.h" -#include "GMEObjectInspector.h" -#include -#include "MgaOpenDlg.h" -#include "GmeDocTemplate.h" -#include "ProjectPropertiesDlg.h" -#include "GmeLib.h" -#include "GMEOLEApp.h" -#include "GMEEventLogger.h" -#include "GMEPrintDialog.h" - -#include "CrashRpt.h" -#ifdef _DEBUG -#pragma comment(lib, "CrashRpt1403.lib") -// https://msdn.microsoft.com/en-us/library/bb531344.aspx#BK_CRT -#pragma comment(lib, "legacy_stdio_definitions.lib") -#else -#pragma comment(lib, "CrashRpt1403.lib") -#endif - -#import "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorlib.tlb" no_implementation -namespace CSGUI { -using namespace mscorlib; -} -#import "CSGUI.tlb" no_implementation - -#ifndef _DEBUG -#pragma comment(linker, "\"/manifestdependency:type='win32' name='Core' version='1.0.0.0' language='*'\"") -#pragma comment(linker, "\"/manifestdependency:type='win32' name='Meta' version='1.0.0.0' language='*'\"") -#pragma comment(linker, "\"/manifestdependency:type='win32' name='Mga' version='1.0.0.0' language='*'\"") -#endif - -#include "CrashTest.h" -#include -#include "GraphicsUtil.h" -#include - - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -// ATL /////////////////////////////////////////////////////////////////////////// -#include -#include "mga_i.c" -#include "meta_i.c" -#include "Splash.h" - -CComModule _Module; - - -///////////////////////////////////////////////////////////////////////////// - -///////////////////////////////////////////////////////////////////////////// -// CGMEApp - -BEGIN_MESSAGE_MAP(CGMEApp, CWinAppEx) - //{{AFX_MSG_MAP(CGMEApp) - ON_COMMAND(ID_APP_ABOUT, OnAppAbout) - ON_COMMAND(ID_FILE_OPEN, OnFileOpen) - ON_COMMAND(ID_FILE_NEW, OnFileNew) - ON_UPDATE_COMMAND_UI(ID_FILE_CLOSEPROJECT, OnUpdateFileCloseproject) - ON_COMMAND(ID_FILE_CLOSEPROJECT, OnFileCloseproject) - ON_UPDATE_COMMAND_UI(ID_FILE_NEW, OnUpdateFileNew) - ON_UPDATE_COMMAND_UI(ID_FILE_OPEN, OnUpdateFileOpen) - ON_COMMAND(ID_EDIT_UNDO, OnEditUndo) - ON_COMMAND(ID_EDIT_REDO, OnEditRedo) - ON_UPDATE_COMMAND_UI(ID_EDIT_REDO, OnUpdateEditRedo) - ON_UPDATE_COMMAND_UI(ID_FILE_EXPORTXML, OnUpdateFileExportxml) - ON_COMMAND(ID_FILE_EXPORTXML, OnFileExportxml) - ON_COMMAND(ID_FILE_IMPORTXML, OnFileImportxml) - ON_UPDATE_COMMAND_UI(ID_EDIT_PROJECTPROPERTIES, OnUpdateEditProjectproperties) - ON_COMMAND(ID_EDIT_PROJECTPROPERTIES, OnEditProjectproperties) - ON_COMMAND(ID_FILE_SETTINGS, OnFileSettings) - ON_COMMAND(ID_FILE_CLEARLOCKS, OnFileClearLocks) - ON_COMMAND(ID_EDIT_CLEARUNDO, OnEditClearUndo) - ON_UPDATE_COMMAND_UI(ID_EDIT_CLEARUNDO, OnUpdateEditClearUndo) - ON_COMMAND(ID_HELP_CONTENTS, OnHelpContents) - ON_COMMAND(ID_FILE_CHECKALL, OnFileCheckall) - ON_UPDATE_COMMAND_UI(ID_FILE_CHECKALL, OnUpdateFileCheckall) - ON_UPDATE_COMMAND_UI(ID_FILE_SAVEPROJECT, OnUpdateFileSave) - ON_UPDATE_COMMAND_UI(ID_FILE_SAVEPROJECTAS, OnUpdateFileSaveAs) - ON_COMMAND(ID_FILE_SAVEPROJECTAS, OnFileSaveAs) - ON_COMMAND(ID_FILE_SAVEPROJECT, OnFileSave) - ON_COMMAND(ID_FILE_ABORTPROJECT, OnFileAbortProject) - ON_UPDATE_COMMAND_UI(ID_FILE_ABORTPROJECT, OnUpdateFileAbortProject) - ON_COMMAND(ID_FILE_REGCOMPONENTS, OnFileRegcomponents) - ON_COMMAND(ID_FILE_REGPARADIGMS, OnFileRegparadigms) - ON_UPDATE_COMMAND_UI(ID_FILE_REGCOMPONENTS, OnUpdateFileRegcomponents) - ON_UPDATE_COMMAND_UI(ID_FILE_UPDATETHROUGHXML, OnUpdateFileXMLUpdate) - ON_COMMAND(ID_FILE_UPDATETHROUGHXML, OnFileXMLUpdate) - ON_COMMAND(ID_FILE_DISPLAY_CONSTRAINTS, OnFileDisplayConstraints) - ON_UPDATE_COMMAND_UI(ID_FILE_DISPLAY_CONSTRAINTS, OnUpdateFileDisplayConstraints) - ON_COMMAND(ID_APP_EXIT, OnAppExit) - ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO, OnUpdateEditUndo) - //}}AFX_MSG_MAP - // Standard file based document commands -// ON_COMMAND(ID_FILE_NEW, CWinAppEx::OnFileNew) -// ON_COMMAND(ID_FILE_OPEN, CWinAppEx::OnFileOpen) - // Standard print setup command - ON_COMMAND(ID_FILE_PRINT_SETUP, OnUniquePrintSetup) // CWinAppEx::OnFilePrintSetup) - // MRU - most recently used project menu - ON_UPDATE_COMMAND_UI(ID_FILE_MRU_PRJ1, OnUpdateRecentProjectMenu) - ON_COMMAND_EX_RANGE(ID_FILE_MRU_PRJ1, ID_FILE_MRU_PRJ16, OnOpenRecentProject) - ON_COMMAND_RANGE(ID_FILE_RUNPLUGIN1, ID_FILE_RUNPLUGIN_LAST, OnRunPlugin) - ON_COMMAND_RANGE(ID_FILE_INTERPRET1, ID_FILE_INTERPRET_LAST, OnRunInterpreter) - ON_UPDATE_COMMAND_UI_RANGE( ID_FILE_RUNPLUGIN1, ID_FILE_RUNPLUGIN_LAST, OnUpdateFilePluginX) - ON_UPDATE_COMMAND_UI_RANGE( ID_FILE_INTERPRET1, ID_FILE_INTERPRET_LAST, OnUpdateFileInterpretX) - ON_COMMAND(ID_FOCUS_BROWSER, OnFocusBrowser) - ON_COMMAND(ID_FOCUS_INSPECTOR, OnFocusInspector) -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// The one and only CGMEApp object - -CGMEApp theApp; - -// This identifier was generated to be statistically unique for your app. -// You may change it if you prefer to choose a specific identifier. - - -/*static*/ const TCHAR * CGMEApp::m_no_model_open_string = _T("_NO_MODEL_IS_OPEN_"); - -static CComBSTR StringFromGUID2(const CComVariant& guid) -{ - ASSERT(guid.vt == (VT_UI1 | VT_ARRAY)); - GUID guid2; - CopyTo(guid, guid2); - CComBSTR strGuid; - CopyTo(guid2, &strGuid.m_str); - return strGuid; -} - -///////////////////////////////////////////////////////////////////////////// -// CGMEApp construction - -CGMEApp::CGMEApp() : - m_RecentProjectList(0, _T("Recent Project List"), _T("Project%d"), 8) - , m_compFilterOn( false) -{ - multipleView = false; - useAutoRouting = true; - labelAvoidance = false; - defZoomLev = _T("100"); - mouseOverNotify = false; - maintainHistory = false; - realFmtStr = _T("%.12g"); - // TODO: add construction code here, - - // Place all significant initialization in InitInstance - SIZE size; - size.cx = 16; - size.cy = 16; - m_userImages.SetImageSize(size); -} - -CGMEApp::~CGMEApp() -{ -} - -class CGMECommandLineInfo : public CCommandLineInfo { -public: - bool bNoProtect, bOpenLast; - CString run; - CGMECommandLineInfo() : bNoProtect(false), bOpenLast(false) { ; } - - virtual void ParseParam(const TCHAR* pszParam, BOOL bFlag, BOOL bLast) { - - if(bFlag && !_wcsicmp(pszParam, L"d")) bNoProtect = true; - else if(bFlag && !_wcsicmp(pszParam, L"l")) bOpenLast = true; - else if(bFlag && _wcsnicmp(pszParam, L"run:", 4) == 0) - { - run = pszParam + 4; - } - else CCommandLineInfo::ParseParam(pszParam, bFlag, bLast); - } - -}; - - -bool CheckInterfaceVersions() { - bool err = false; - LPCOLESTR components[] = { - L"Mga.MgaProject", - L"Mga.MgaMetaProject", - L"Mga.CoreProject", - L"Mga.MgaRegistrar", - L"Mga.MgaParser", - L"Mga.AddOn.ConstraintManager", - NULL }; - CString errstring; - HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); - TCHAR hrbuf[20]; - if(hr != S_OK) AfxMessageBox(CString(_T("Coinitialize failure. Err: #")) + _ltot(hr,hrbuf,16)); - for(LPCOLESTR *p = components; *p; p++) { - GMEInterfaceVersion verid = GMEInterfaceVersion_None; - CComPtr unk; - CString ee; - if(S_OK != (hr = unk.CoCreateInstance(*p))) { - { - _com_error error(hr); - errstring.Format(_T("Cannot create object %%s (Err: #%X, %s)"), hr, error.ErrorMessage()); - } -gerr: - CString a; - a.Format(errstring, *p, verid/0x1000, verid%0x1000, GMEInterfaceVersion_Current/0x1000,GMEInterfaceVersion_Current%0x1000); - AfxMessageBox(a); - err = true; - continue; - } - CComQIPtr vinf = unk; - if(!vinf) { - errstring = _T("Incompatible version of object %s (does not support version information)"); - goto gerr; - } - if(S_OK != vinf->get_version(&verid)) { - errstring = _T("Get_Version failed for object %s"); - goto gerr; - } - if(verid != GMEInterfaceVersion_Current) { - errstring = _T("Interface version for class %s (%d.%d) differs from GME interface version (%d.%d)"); - goto gerr; - } - } - return err; -} - - -CString getUserRegistryStringValue(const TCHAR* name) { - CString ret; - HKEY hKey; - if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Software\\GME\\"), - 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) - { - TCHAR szData[256]; - DWORD dwKeyDataType; - DWORD dwDataBufSize = sizeof(szData) / sizeof(TCHAR); - - if (RegQueryValueEx(hKey, name, NULL, &dwKeyDataType, - (LPBYTE)&szData, &dwDataBufSize) == ERROR_SUCCESS) - { - ret = CString(szData, dwDataBufSize); - } - - RegCloseKey(hKey); - } - return ret; -} - -///////////////////////////////////////////////////////////////////////////// -// CGMEApp initialization - -BOOL CGMEApp::InitInstance() -{ - // InitCommonControlsEx() is required on Windows XP if an application - // manifest specifies use of ComCtl32.dll version 6 or later to enable - // visual styles. Otherwise, any window creation will fail. - INITCOMMONCONTROLSEX InitCtrls; - InitCtrls.dwSize = sizeof(InitCtrls); - // Set this to include all the common control classes you want to use - // in your application. - InitCtrls.dwICC = ICC_WIN95_CLASSES; - InitCommonControlsEx(&InitCtrls); - -#if _MSC_VER < 1700 - // See MSDN example code for CWinApp::InitInstance: http://msdn.microsoft.com/en-us/library/ae6yx0z0.aspx - // MFC module state handling code is changed with VC80. - // We follow the Microsoft's suggested way, but in case of any trouble the set the - // HKCU\Software\GME\AfxSetAmbientActCtxMod key to 0 - UINT uAfxSetAmbientActCtxMod = 1; - HKEY hKey; - if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Software\\GME\\"), - 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) - { - TCHAR szData[128]; - DWORD dwKeyDataType; - DWORD dwDataBufSize = sizeof(szData)/sizeof(TCHAR); - - if (RegQueryValueEx(hKey, _T("AfxSetAmbientActCtxMod"), NULL, &dwKeyDataType, - (LPBYTE) &szData, &dwDataBufSize) == ERROR_SUCCESS) - { - uAfxSetAmbientActCtxMod = _tcstoul(szData, NULL, 10); - } - - RegCloseKey(hKey); - } - if (uAfxSetAmbientActCtxMod != 0) - { - AfxSetAmbientActCtx(FALSE); - } -#endif - - CWinAppEx::InitInstance(); - - // CG: The following block was added by the Splash Screen component. - CGMECommandLineInfo cmdInfo; - ParseCommandLine(cmdInfo); - - if( cmdInfo.m_nShellCommand == CCommandLineInfo::FileOpen || cmdInfo.m_nShellCommand == CCommandLineInfo::AppRegister) - ; - cmdInfo.m_bShowSplash = false; - - CSplashWnd::EnableSplashScreen(cmdInfo.m_bShowSplash); - // CG: The following block was inserted by 'Status Bar' component. - { - //Set up date and time defaults so they're the same as system defaults - setlocale(LC_ALL, ""); - } - - //if(CheckInterfaceVersions()) return FALSE; - - - // Initialize OLE libraries - if (!AfxOleInit()) - { - AfxMessageBox(IDP_OLE_INIT_FAILED); - return FALSE; - } - - AfxEnableControlContainer(); - - EnableTaskbarInteraction(); - - // Standard initialization - // If you are not using these features and wish to reduce the size - // of your final executable, you should remove from the following - // the specific initialization routines you do not need. - -#ifdef _AFXDLL - //Enable3dControls(); // deprecated -#else - Enable3dControlsStatic(); // Call this when linking to MFC statically -#endif - - - // Enable assigning shortcut keys to the menus - InitKeyboardManager(); - - // Enabling user tools - EnableUserTools(ID_TOOLS_EXTERNAL_TOOLS, ID_USER_TOOL1, ID_USER_TOOL10, RUNTIME_CLASS(CUserTool)/*, IDR_MENU_ARGS, IDR_MENU_DIRS*/); - - InitContextMenuManager(); - - // Change the registry key under which our settings are stored. - // TODO: You should modify this string to be something appropriate - // such as the name of your company or organization. - SetRegistryKey(_T("GME\\GUI")); - - LoadStdProfileSettings(); // Load standard INI file options (including MRU) - m_RecentProjectList.ReadList(); - - - // Load Accelerator Table for CGMEView - - m_GMEView_hAccel = LoadAccelerators(m_hInstance, MAKEINTRESOURCE(IDR_GMEVIEW)); - ASSERT( m_GMEView_hAccel ); - - // Register the application's document templates. Document templates - // serve as the connection between documents, frame windows and views. - - pDocTemplate = new CGmeDocTemplate( - IDR_GMETYPE, - RUNTIME_CLASS(CGMEDoc), - RUNTIME_CLASS(CChildFrame), // custom MDI child frame -#if !defined(ACTIVEXGMEVIEW) - RUNTIME_CLASS(CGMEView)); -#else - RUNTIME_CLASS(CGMEChildFrame)); -#endif - pDocTemplate->SetContainerInfo(IDR_GMETYPE_CNTR_IP); - AddDocTemplate(pDocTemplate); - - - - // create main MDI Frame window - CMainFrame* pMainFrame = new CMainFrame; - if (!pMainFrame->LoadFrame(IDR_MAINFRAME)) - { - // n.b. if LoadFrame fails, CFrameWnd::PostNcDestroy is called which does `delete this` - // delete pMainFrame; - return FALSE; - } - m_pMainWnd = pMainFrame; - pMainFrame->CheckForOffscreenPanes(); - -#if !defined(ADDCRASHTESTMENU) && defined(_DEBUG) - bNoProtect = true; -#else - bNoProtect = cmdInfo.bNoProtect; -#endif - - //initialize the logfile - first check registry to see if the user wants logging - MSGTRY - { - CComPtr registrar; - COMTHROW(registrar.CoCreateInstance(CComBSTR(L"Mga.MgaRegistrar"))); - VARIANT_BOOL enablelogging; - COMTHROW( registrar->get_EventLoggingEnabled(REGACCESS_USER, &enablelogging) ); - if(enablelogging != VARIANT_FALSE) - { - CGMEEventLogger::initialize(); - CGMEEventLogger::LogGMEEvent("GME started\r\n"); - } - } - MSGCATCH(_T("Error while trying to get logfile settings"),;); - - ASSERT((CMainFrame*)m_pMainWnd); - CGMEOLEApp *t_pGmeOleApp = new CGMEOLEApp(); - ((CMainFrame*)m_pMainWnd)->setGmeOleApp( t_pGmeOleApp ); - - // Register all OLE server factories as running. This enables the - // OLE libraries to create objects from other applications. - COleObjectFactory::RegisterAll(); - // Note: MDI applications register all server objects without regard - // to the /Embedding or /Automation on the command line. - // Note: we switched the default REGCLS_MULTIPLEUSE behavior to REGCLS_SINGLEUSE, - // see GMEOLEApp.cpp's MY_IMPLEMENT_OLECREATE macro, and - // "How to use single or multiple instances of an OLE object in MFC by using Visual C++" KB article: - // http://support.microsoft.com/kb/141154 - - // Check to see if launched as OLE server - if (cmdInfo.m_bRunEmbedded || cmdInfo.m_bRunAutomated) - { - // Application was run with /Embedding or /Automation. Don't show the - // main window in this case. - - // - // load settings in this case as well - GetSettings(); - - return TRUE; - } - - // Updates system registry with all creatable classes (_OLECREATE) - // PETER: It works only with administrator priviledges - COleObjectFactory::UpdateRegistryAll(); - - // Make sure the type library is registered or dual interface won't work. - AfxOleRegisterTypeLib(AfxGetInstanceHandle(), __uuidof(__GmeLib)); - - // Dispatch commands specified on the command line - if ((cmdInfo.m_nShellCommand == CCommandLineInfo::AppRegister || cmdInfo.m_nShellCommand == CCommandLineInfo::AppUnregister) && !ProcessShellCommand(cmdInfo)) - return FALSE; - - // The main window has been initialized, so show and update it. - pMainFrame->ShowWindow(m_nCmdShow); - pMainFrame->UpdateWindow(); - - - dynmenus_need_refresh = true; - - GetSettings(); - m_pMainWnd->DragAcceptFiles(TRUE); - - return TRUE; -} - -BOOL CGMEApp::PreTranslateMessage(MSG* pMsg) -{ - // CG: The following lines were added by the Splash Screen component. - if (CSplashWnd::PreTranslateAppMessage(pMsg)) - return TRUE; - // KMS: m_pMainWnd->PreTranslateMessage here for Alt-F,C. Otherwise, CGMEView::PreTranslateMessage TranslateAccelerator will return TRUE - if (m_pMainWnd && m_pMainWnd->PreTranslateMessage(pMsg)) - return TRUE; - - return CWinAppEx::PreTranslateMessage(pMsg); -} - - - -///////////////////////////////////////////////////////////////////////////// -// CGMEApp emergency - -void CGMEApp::EmergencySave(void) -{ - CGMEEventLogger::LogGMEEvent("EMERGENCY EVENT\r\n"); - if (mgaProject && (proj_type_is_mga || proj_type_is_xmlbackend)) { - CString embackupname = currentConnection; - int p = embackupname.ReverseFind('.'); - if ((p == -1) || embackupname.Find('\\', p) != -1) - p = embackupname.GetLength(); - CString emcode; - static int emnum; - emcode.Format(_T("-emergency%ld"), ++emnum); - embackupname.Insert(p, emcode); - long status = 0; - mgaProject->get_ProjectStatus(&status); // ignore failure - if (status == 3 || status == 4) // i.e. in tx - mgaProject->AbortTransaction(); // ignore failure - HRESULT hr = mgaProject->Save(PutInBstr(embackupname), VARIANT_TRUE); - if (proj_type_is_xmlbackend) { - AfxMessageBox(_T("Your current work can be found in the local checkout directory.")); - } else { - CString emergencySaveMsg; - emergencySaveMsg.FormatMessage(_T("Your current work %1 been saved to %2.\n") - _T("The original project file has not been modified. ") - _T("We apologize for the inconvenience."), - (hr == S_OK)? _T("has") : _T("might have"), - embackupname); - AfxMessageBox(emergencySaveMsg); - m_RecentProjectList.AddAndWriteList(embackupname); - } - } -} - -BOOL CGMEApp::OpenCommandLineProject() -{ - CGMECommandLineInfo cmdInfo; - ParseCommandLine(cmdInfo); - // We don't want a new document at startup - if(cmdInfo.m_nShellCommand == CCommandLineInfo::FileNew) - cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing; - if (cmdInfo.m_nShellCommand == CCommandLineInfo::AppRegister) - cmdInfo.bOpenLast = true; - if(cmdInfo.m_nShellCommand == CCommandLineInfo::FileOpen) - { - CString conn = cmdInfo.m_strFileName; - if(conn.Find(_T("=")) < 0) { - if (conn.Right(4).CompareNoCase(_T(".xme")) == 0) - conn.Insert(0, _T("XML=")); - else - conn.Insert(0,_T("MGA=")); - } - OpenProject(conn); - - cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing; - return TRUE; - } - else if(cmdInfo.bOpenLast && !m_RecentProjectList[0].IsEmpty()) - { - OpenProject(m_RecentProjectList[0]); - cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing; - return TRUE; - } else if(cmdInfo.run != "") - { - if (CMainFrame::theInstance) - CMainFrame::theInstance->m_console.m_Console.RunCode(CComBSTR(cmdInfo.run)); - return TRUE; - } - - // Dispatch commands specified on the command line - //if (!ProcessShellCommand(cmdInfo)) - // return FALSE; - if (!(cmdInfo.m_bRunEmbedded || cmdInfo.m_bRunAutomated)) - { - ShowWelcomeWindow(); - } - return FALSE; -} - -BOOL CGMEApp::ShowWelcomeWindow() -{ - CSGUI::_WelcomeScreenExpPtr ws; - ws.CreateInstance(L"CSGUI.WelcomeScreenExp"); - if (ws) - try { - ATL::CComSafeArray recents; - for (int i = 0; i < m_RecentProjectList.GetSize(); i++) - { - recents.Add(CComBSTR(m_RecentProjectList[i])); - } - VARIANT vrecents; - vrecents.parray = (SAFEARRAY*)recents; - vrecents.vt = VT_ARRAY | VT_BSTR; - ws->SetRecentProjects(_variant_t(vrecents)); - _bstr_t SelectedProject = ws->ShowWelcomeWindow((unsigned long)m_pMainWnd->GetSafeHwnd()); - - if (SelectedProject != _bstr_t()) { - if (SelectedProject == ws->CREATE_SENTINEL) { - OnFileNew(); - } else { - CString conn = static_cast(SelectedProject); - if(conn.Find(_T("=")) < 0) { - if (conn.Right(4).CompareNoCase(_T(".xme")) == 0) - conn.Insert(0, _T("XML=")); - else if (conn.Right(4).CompareNoCase(_T(".mgx")) == 0) - { - CString filename, dirname; - GetFullPathName(conn, filename, dirname); - conn = CString(L"MGX=\"") + dirname + L"\""; - } - else - conn.Insert(0,_T("MGA=")); - } - OpenProject(conn); - } - } - } catch (_com_error& e) { - //AfxMessageBox(e.ErrorMessage()); - } - return TRUE; -} - -// CInvalidArgException _simpleInvalidArgException(FALSE); -static void (__stdcall *InvalidArg)() = nullptr; -void __stdcall InvalidArgReplacement() { - CR_EXCEPTION_INFO ei; - memset(&ei, 0, sizeof(CR_EXCEPTION_INFO)); - ei.cb = sizeof(CR_EXCEPTION_INFO); - ei.exctype = CR_SEH_EXCEPTION; - ei.code = 1234; - ei.pexcptrs = NULL; - - int result = crGenerateErrorReport(&ei); - - if (result != 0) - { - TCHAR szErrorMsg[256]; - crGetLastErrorMsg(szErrorMsg, 256); - AfxMessageBox(szErrorMsg); - } - // FIXME: this shows "Internal application error" instead of invalid argument - throw new CInvalidArgException(); -} - -static void HookInvalidArg() { -#if defined(_M_IX86) - // reg add HKCU\Software\GME /v HookInvalidArg /d 1 /t REG_SZ /f - if (getUserRegistryStringValue(L"HookInvalidArg") == L"1") { - InvalidArg = &AfxThrowInvalidArgException; - int** invalidArg = (int**)(2 + ((char*)(void*)InvalidArg)); - DWORD oldProtect; - if (VirtualProtect((LPVOID)**invalidArg, 5, PAGE_EXECUTE_READWRITE, &oldProtect)) { - int invalidArgHook = (int)(void*)&InvalidArgReplacement; - ptrdiff_t diff = invalidArgHook - **invalidArg; - diff -= 5; - *((char*)**invalidArg) = 0xe9; - *((int*)(1 + (char*)**invalidArg)) = diff; - // AfxThrowInvalidArgException(); - } - } -#endif -} - -int CGMEApp::Run() -{ - CoFreeUnusedLibraries(); // JIRA 221: GME 9.12.15 Crashing - // Unload ConstraintManager.dll, GME crashes if the system unloads it by itself - - Gdiplus::GdiplusStartupInput gdiplusStartupInput; - Gdiplus::GdiplusStartupOutput gdiplusStartupOutput; - ULONG_PTR gdiplusToken; - ULONG_PTR gdiplusHookToken; - - // Tihamer: Initializing GDI+ - // See "Special CWinApp Services" MSDN topic http://msdn.microsoft.com/en-us/library/001tckck.aspx - gdiplusStartupInput.SuppressBackgroundThread = TRUE; - VERIFY(Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, &gdiplusStartupOutput) == Gdiplus::Ok); - gdiplusStartupOutput.NotificationHook(&gdiplusHookToken); - graphics.Initialize(); - - - // KMS: set up CrashRpt info - CR_INSTALL_INFO info; - memset(&info, 0, sizeof(CR_INSTALL_INFO)); - info.cb = sizeof(CR_INSTALL_INFO); - info.pszAppName = _T("GME"); - info.pszAppVersion = _T(GME_VERSION_ID); - info.pszEmailSubject = _T("GME CrashRpt"); - info.uPriorities[CR_SMTP] = CR_NEGATIVE_PRIORITY; - info.uPriorities[CR_SMAPI] = CR_NEGATIVE_PRIORITY; - info.pszUrl = _T("https://gme-crashrpt.metamorphsoftware.com/crashrpt"); - info.dwFlags = CR_INST_SEH_EXCEPTION_HANDLER | CR_INST_PURE_CALL_HANDLER | CR_INST_SECURITY_ERROR_HANDLER - | CR_INST_INVALID_PARAMETER_HANDLER | CR_INST_SIGABRT_HANDLER | CR_INST_SIGINT_HANDLER | CR_INST_SIGTERM_HANDLER; - // missing: CR_INST_NEW_OPERATOR_ERROR_HANDLER: the default std::bad_alloc is fine (sometimes we handle it) -#ifdef _DEBUG - bNoProtect = true; -#endif - auto disableCrashRpt = []() -> bool { - // reg add HKCU\Software\GME /v InstallCrashRpt /d 0 /t REG_SZ /f - if (getUserRegistryStringValue(L"InstallCrashRpt") == L"0") { - return true; - } - return false; - }; - bNoProtect = bNoProtect || disableCrashRpt(); - bNoProtect = bNoProtect || static_cast(IsDebuggerPresent()); - if (!bNoProtect) { - if (crInstall(&info) != 0) - { - TCHAR buff[1024]; - crGetLastErrorMsg(buff, 1024); - AfxMessageBox(buff); - return FALSE; - } - HookInvalidArg(); - } - - OpenCommandLineProject(); - - int retVal = 0; - if (bNoProtect) { - retVal = CWinAppEx::Run(); - } else { - __try { - retVal = CWinAppEx::Run(); - } - __except(crExceptionFilter(GetExceptionCode(), GetExceptionInformation())) { - EmergencySave(); - - // KMS: As our state may be corrupted, TerminateProcess so we don't run any atexits and crash again - TerminateProcess(GetCurrentProcess(), GetExceptionCode()); - } - } - // KMS: need to unload decorators before closing GDI+: e.g. ~Facilities() does GDI+ ops - CoFreeUnusedLibraries(); - // Closing GDI+ - graphics.Uninitialize(); - gdiplusStartupOutput.NotificationUnhook(gdiplusHookToken); - Gdiplus::GdiplusShutdown(gdiplusToken); - - return retVal; -} - -///////////////////////////////////////////////////////////////////////////// -// CGMEApp Autosave -void CGMEApp::Autosave() -{ - - if(mgaProject == NULL || (0&&!proj_type_is_mga) || (!autosaveEnabled)) { - // The KillTimer function does not remove WM_TIMER messages - // already posted to the message queue ... - CGMEEventLogger::LogGMEEvent(_T("WARNING: CGMEApp::Autosave was called with no active project or autosave disabled.\r\n")); - return; - } - - // Figure out the filename - CString conn; - if (autosaveUseDir) { - int p = currentConnection.ReverseFind('\\'); - CString fname = currentConnection.Mid(p + 1); - - conn = CString(_T("MGA=")) + autosaveDir + CString(_T("\\")) + fname + GME_AUTOSAVE_EXTENSION; - } - else { - conn = currentConnection + GME_AUTOSAVE_EXTENSION; - } - - // autosave in case of xmlbackend means saving into the sourcecontrol - if( proj_type_is_xmlbackend) - conn = currentConnection; - - // Check if in transaction - bool inTrans; - try { - long status; - COMTHROW(mgaProject->get_ProjectStatus(&status)); - inTrans = (status & 0x08L) != 0; - } - catch(hresult_exception &) { - // Safe presumption - inTrans = true; - } - - if (inTrans) { - CGMEEventLogger::LogGMEEvent(_T("WARNING: CGMEApp::Autosave failed ") + - conn + _T(". We are in transaction.\r\n")); - return; - } - - // Save the project - try { - COMTHROW(mgaProject->Save(CComBSTR(conn), VARIANT_TRUE)); - CGMEEventLogger::LogGMEEvent(_T("CGMEApp::Autosave succeeded ") + - conn + _T("\r\n")); - } - catch(hresult_exception &e) { - CGMEEventLogger::LogGMEEvent(_T("WARNING: CGMEApp::Autosave failed ") + - conn + _T(" ") + e.what() + _T("\r\n")); - } -} - - -///////////////////////////////////////////////////////////////////////////// -// CGMEApp MGA project management - - -void CGMEApp::CloseProject(bool updateStatusBar, bool force_abort) -{ - - CWaitCursor wait; - - if(CGMEDataSource::myData) // it is true when object copied to the clipboard from the view - OleFlushClipboard(); - - if( CMainFrame::theInstance != NULL ) { - CMainFrame::theInstance->StopAutosaveTimer(); - CMainFrame::theInstance->SetPartBrowserMetaModel(NULL); - CMainFrame::theInstance->SetPartBrowserBg(::GetSysColor(COLOR_APPWORKSPACE)); - } - - if( CGMEBrowser::theInstance != NULL ) - CGMEBrowser::theInstance->CloseProject(); - - if(CGMEObjectInspector::theInstance!=NULL) - CGMEObjectInspector::theInstance->CloseProject(); - - if(CGMESearch::theInstance!=NULL) - CGMESearch::theInstance->CloseProject(); - - if (CGMEPartBrowser::theInstance) - CGMEPartBrowser::theInstance->SetProject(CComPtr(0)); - - - - if( guiMetaProject != NULL ) - { - delete guiMetaProject; - guiMetaProject = NULL; - } - - mgaMetaProject = NULL; - UpdateComponentLists(); - - if( mgaProject != NULL ) { - mgaClient = NULL; - if(mgaProject->Close((abort_on_close || force_abort) ? VARIANT_TRUE : VARIANT_FALSE) != S_OK) { - AfxMessageBox(CString(_T("Error occurred ")) + ((abort_on_close || force_abort) ? _T("aborting") : _T("closing")) + _T(" the project")); - } - mgaProject.Release(); - } - - - if(updateStatusBar) { - CMainFrame::theInstance->WriteStatusParadigm(_T("-")); - CMainFrame::theInstance->WriteStatusMode(_T("EDIT")); - CMainFrame::theInstance->WriteStatusZoom(100); - } - projectName.Empty(); - ChangedProjectConnStrings(); - - if(CGMEDoc::theInstance) - CGMEDoc::theInstance->SetTitle(_T("")); - if(CMainFrame::theInstance) { - CMainFrame::theInstance->SetTitle(m_pszAppName); - CMainFrame::theInstance->UpdateTitle(0);//WAS: "" .By passing 0 instead of "" we won't get title such as "GME-" after a project was closed - } -} - - -void CGMEApp::ChangedProjectConnStrings() { - if(!mgaProject) { // project closed - paradigmDir.Empty(); - projectDir.Empty(); - proj_type_is_mga = false; - proj_type_is_xmlbackend = false; - return; - } - CString conn, metaconn; - CComBstrObj cc; - conn = cc; - COMTHROW(mgaProject->get_ProjectConnStr(PutOut(cc))); - conn = cc; - cc.Empty(); - COMTHROW(mgaProject->get_ParadigmConnStr(PutOut(cc))); - metaconn = cc; - if(!conn.IsEmpty()) { - TCHAR cd[200]; - GetCurrentDirectory(200, cd); - projectDir = cd; - if (conn.Find(_T("MGA=")) == 0) { - proj_type_is_mga = true; - int epos = conn.ReverseFind('\\'); - if(epos >= 4) { - projectDir = conn.Mid(4, epos-4); - if(projectDir.IsEmpty()) projectDir= '\\'; - SetCurrentDirectory(projectDir); - } - } - else proj_type_is_mga = false; - - if( conn.Find(_T("MGX=")) == 0 ) - proj_type_is_xmlbackend = true; - else - proj_type_is_xmlbackend = false; - } - if(!metaconn.IsEmpty()) { - if (metaconn.Find(_T("MGA=")) == 0) { - int epos = metaconn.ReverseFind('\\'); - if(epos >= 4) { - paradigmDir = metaconn.Mid(4, epos-4); - if(paradigmDir.IsEmpty()) paradigmDir= '\\'; - } - } - } -} - - -// throws exceptions!! -void CGMEApp::UpdateProjectName(bool retrievePath) { - if( mgaProject == NULL ) { - projectName.Empty(); - } - else { - - - CComObjPtr terry; - COMTHROW(mgaProject->CreateTerritory(NULL, PutOut(terry), NULL) ); - CComBSTR nm; - - MSGTRY - { - COMTHROW(mgaProject->BeginTransaction(terry,TRANSACTION_READ_ONLY)); - COMTHROW(mgaProject->get_Name(&nm)); - COMTHROW(mgaProject->CommitTransaction()); - } - MSGCATCH(_T("Error getting project name"), mgaProject->AbortTransaction()) - - CopyTo(nm,projectName); - } - - if(CGMEDoc::theInstance) - CGMEDoc::theInstance->SetTitle(projectName); - UpdateMainFrameTitle(projectName, retrievePath); -} - -void CGMEApp::UpdateMainFrameTitle(const CString& projName, bool retrievePath) -{ - CString projectName = projName; - - if (retrievePath) { - CDocument* pDocument = CGMEDoc::theInstance; - if (pDocument) { - POSITION pos = pDocument->GetFirstViewPosition(); - while (pos != NULL) { -#if !defined(ACTIVEXGMEVIEW) - CGMEView* pView = (CGMEView*) pDocument->GetNextView(pos); - ASSERT(pView); - pView->RetrievePath(); - pView->SetTitles(); - } -#endif - } - } - CMDIChildWnd* pChild = CMainFrame::theInstance->MDIGetActive(); - if (pChild && pChild->IsKindOf(RUNTIME_CLASS(CChildFrame))) { -#if !defined (ACTIVEXGMEVIEW) - if (retrievePath) { - CGMEView* view = (CGMEView*)pChild->GetActiveView(); - if (view) { - view->RetrievePath(); - view->SetTitles(); - } - } -#endif - CChildFrame* childFrame = STATIC_DOWNCAST(CChildFrame, pChild); - projectName = childFrame->GetTitle() + _T(" - ") + childFrame->GetAppTitle(); - } - if (mgaProject && isMgaProj()) { - CString filename, dirname; - getMgaPaths(filename, dirname); - projectName = projectName + L" (" + filename + L")"; - } - CMainFrame::theInstance->UpdateTitle(projectName); -} - -void CGMEApp::FindConstraintManager() -{ - CComPtr comps; - COMTHROW( mgaProject->get_AddOnComponents(&comps)); - MGACOLL_ITERATE(IMgaComponent, comps) { - CComBSTR name; - COMTHROW(MGACOLL_ITER->get_ComponentName(&name)); - if(name == _T("ConstraintManager")) { - mgaConstMgr = CComQIPtr(MGACOLL_ITER); - COMTHROW(mgaConstMgr->put_InteractiveMode(VARIANT_TRUE)); - break; - } - } MGACOLL_ITERATE_END; -} - - -void CGMEApp::UpdateComponentToolbar() -{ - if (!CMainFrame::theInstance) - return; - CComponentBar &componentBar = CMainFrame::theInstance->m_wndComponentBar; - componentBar.ShowWindow(SW_HIDE); - CMainFrame::theInstance->ShowPane(&componentBar, FALSE, FALSE, FALSE); - - // Removing the add-in and plug-in buttons - const CObList &componentButtons = componentBar.GetAllButtons(); - for(POSITION pos = componentButtons.GetHeadPosition(); pos!= NULL; ) - { - const CMFCToolBarButton* pCurrent = (const CMFCToolBarButton*) componentButtons.GetNext(pos); - if(pCurrent->m_bUserButton == TRUE) - { - // FIXME: this doesn't work, so we leak all the icons. Maybe we could m_userImages.UpdateImage instead? - // VERIFY(m_userImages.DeleteImage(pCurrent->GetImage())); - int buttonIndex = componentBar.ButtonToIndex(pCurrent); - componentBar.RemoveButton(buttonIndex); - } - } - - componentBar.AdjustLayout(); // CMFCToolBar::AdjustLayout - componentBar.AdjustSizeImmediate(TRUE); - componentBar.RecalcLayout(); // CPane::RecalcLayout - - if (!mgaMetaProject) - { - return; - } - - // Updating the Component toolbar - CComPtr registrar; - if(registrar.CoCreateInstance(L"Mga.MgaRegistrar") != S_OK) return; - - - // Traversing the plugins and interpreters - int plugins_size = min((int)plugins.GetSize(), ID_FILE_RUNPLUGIN_LAST - ID_FILE_RUNPLUGIN1); - int interpreters_size = min((int)interpreters.GetSize(), ID_FILE_INTERPRET_LAST - ID_FILE_INTERPRET1); - for(int i = 0; i < plugins_size + interpreters_size; ++i) - { - // Querying component name - CComBSTR componentName; - if(i < plugins_size) // if it is a plugin - { - componentName = plugins[i]; - } - else // if it is an interpreter - { - componentName = interpreters[i-plugins_size]; - } - - // Obtaining ToolTip - HRESULT errCode; - CString toolTip; - errCode = registrar->get_ComponentExtraInfo(REGACCESS_PRIORITY, componentName, CComBSTR(L"Tooltip"), PutOut(toolTip)); - if(errCode != S_OK || toolTip.IsEmpty()) - { - toolTip = componentName; - } - if(i < plugins_size) - { - pluginTooltips.Add(toolTip); - } - else - { - interpreterTooltips.Add(toolTip); - } - - // Querying icon information - CString iconInfo; - errCode = registrar->get_ComponentExtraInfo(REGACCESS_PRIORITY, componentName, CComBSTR(L"Icon"), PutOut(iconInfo)); - if(errCode != S_OK || iconInfo.IsEmpty()) - { - continue; - } - - // Loading icon - HICON hIcon = NULL; //, hictofree = NULL; - int commaPos; - HMODULE hModule = NULL; - if((commaPos = iconInfo.Find(',')) >= 0) //Format: , - { - if(commaPos) // module name present; - { - // XP doesn't support LOAD_LIBRARY_AS_IMAGE_RESOURCE - hModule = LoadLibraryEx(iconInfo.Left(commaPos), NULL, LOAD_LIBRARY_AS_DATAFILE); - } - else // No module name provided, - { - _bstr_t modulePath; - registrar->get_LocalDllPath(componentName, modulePath.GetAddress()); - if(modulePath.length() != 0) - { - // XP doesn't support LOAD_LIBRARY_AS_IMAGE_RESOURCE - hModule = LoadLibraryEx(modulePath, NULL, LOAD_LIBRARY_AS_DATAFILE); - } - } - } - - int cx = m_userImages.GetImageSize().cx; - int cy = m_userImages.GetImageSize().cy; - - if( hModule != NULL ) - { - hIcon = (HICON)::LoadImage(hModule, iconInfo.Mid(commaPos+1), IMAGE_ICON, cx, cy, LR_DEFAULTCOLOR); - } - else - { - // simple .ico file with path - hIcon =(HICON)LoadImage(NULL, iconInfo, IMAGE_ICON, cx, cy, LR_LOADFROMFILE); - } - - // If icon is not found either in the DLL or a standalone file - if(!hIcon) - { - // Displaying component not found icon: red X - hIcon = (HICON)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_COMPNOTFOUND), IMAGE_ICON, 16,16, LR_DEFAULTCOLOR); - } - - //Adding button icon - int nIndex = m_userImages.AddIcon(hIcon); - ASSERT(nIndex >= 0); - BOOL succ = CMFCToolBar::SetUserImages(&m_userImages); - ASSERT(succ == TRUE); - - // Adding button - UINT commandID = (i < plugins_size) ? ID_FILE_RUNPLUGIN1 + i : ID_FILE_INTERPRET1 + i - plugins_size; - CMFCToolBarButton toolBarButton(commandID, nIndex, componentName + '\n' + toolTip, TRUE); - - VERIFY(componentBar.InsertButton(toolBarButton) != -1); - if (hModule) - FreeLibrary(hModule); - } - if (plugins_size + interpreters_size != 0) { - componentBar.AdjustLayout(); // CMFCToolBar::AdjustLayout - componentBar.AdjustSizeImmediate(TRUE); - componentBar.RecalcLayout(); // CPane::RecalcLayout - CMainFrame::theInstance->ShowPane(&componentBar, TRUE, FALSE, FALSE); - componentBar.ShowWindow(SW_SHOW); - } -} - - -void CGMEApp::UpdateComponentLists(bool restart_addons) -{ - ClearDisabledComps(); - plugins .RemoveAll(); - pluginTooltips.RemoveAll(); - interpreters.RemoveAll(); - interpreterTooltips.RemoveAll(); - CStringArray tempaddons; tempaddons.Copy(addons); - addons.RemoveAll(); - mgaConstMgr = NULL; - if(mgaMetaProject) { - CComBSTR b; - COMTHROW(mgaMetaProject->get_Name(&b)); - CComPtr reg; - COMTHROW(reg.CoCreateInstance(CComBSTR(L"Mga.MgaRegistrar"))); - { - CComVariant v; - COMTHROW(reg->get_AssociatedComponents(b, COMPONENTTYPE_PLUGIN, REGACCESS_BOTH, &v)); - CopyTo(v, plugins); - } - { - CComVariant v; - COMTHROW(reg->get_AssociatedComponents(b, COMPONENTTYPE_INTERPRETER, REGACCESS_BOTH, &v)); - CopyTo(v, interpreters); - } - { - CComVariant v; - COMTHROW(reg->get_AssociatedComponents(b, COMPONENTTYPE_ADDON, REGACCESS_BOTH, &v)); - - CopyTo(v, addons); - if(restart_addons) { - bool redo = false; - if(tempaddons.GetSize() != addons.GetSize()) redo = true; - else { - for(int j = 0 ; j < tempaddons.GetSize(); j++) { - if(addons[j].Compare(tempaddons[j])) { - redo = true; - break; - } - } - } - if(redo && AfxMessageBox(_T("AddOn configuration has changed.\nRestart addons?"), MB_YESNO) == IDYES) { - COMTHROW(mgaProject->EnableAutoAddOns(VARIANT_FALSE)); - COMTHROW(mgaProject->EnableAutoAddOns(VARIANT_TRUE)); - } - } - } - // access constraint mgr - FindConstraintManager(); - - } - dynmenus_need_refresh = true; - UpdateComponentToolbar(); -} - -void CGMEApp::UpdateDynMenus(CMenu *toolmenu) -{ - CString runPluginLabel = _T("R&un Plug-In"); - CString runInterpreterLabel = _T("Run In&terpreter"); - CString label; - // [ Begin workaround - // If you just go left to the Window menu next to the Tools menu, and back to the Tools menu (so not even abandoming the menubar) - // the original menu (without added intepreters and plugins) is switched back. - // To workaround this we check always if the original plugin and interpreter placeholder menus are present, - // because if they are present we have to populate the interpreters plugins again. - // Step 1: Get tools menu if we got NULL menu - if (toolmenu == NULL) { - CMenu* mainMenu = CMainFrame::theInstance->GetMenu(); - if (mainMenu == NULL || mainMenu->m_hMenu == NULL) { - HMENU mainHMenu = CMainFrame::theInstance->GetMenuBar()->GetHMenu(); - mainMenu = CMenu::FromHandle(mainHMenu); - } - ASSERT(mainMenu); - for(UINT idxa = 0; idxa < mainMenu->GetMenuItemCount(); idxa++) { - CString labela; - mainMenu->GetMenuString(idxa, labela, MF_BYPOSITION); - if (!labela.CompareNoCase(_T("&Tools"))) { - toolmenu = mainMenu->GetSubMenu(idxa); - break; - } - } - } - // Step 2: Check if placeholder menus are present -> we switch trigger in that case - if (toolmenu != NULL) { - for(UINT idx = 0; idx < toolmenu->GetMenuItemCount(); idx++) { - toolmenu->GetMenuString(idx, label, MF_BYPOSITION); - UINT menuID = toolmenu->GetMenuItemID(idx); - if (menuID == ID_TOOLS_RUNPLUG || menuID == ID_FILE_RUNINTERPRETER) { - dynmenus_need_refresh = true; - break; - } - } - } - // End workaround ] - if (!dynmenus_need_refresh) - return; - ASSERT(toolmenu); - bool found = false; - for(UINT idx = 0; idx < toolmenu->GetMenuItemCount(); idx++) { - toolmenu->GetMenuString(idx, label, MF_BYPOSITION); - UINT menuID = toolmenu->GetMenuItemID(idx); - if (!label.CompareNoCase(runPluginLabel) || - menuID == ID_TOOLS_RUNPLUG || menuID == ID_FILE_RUNPLUGIN1) - { - if (dynmenus_need_refresh) { - toolmenu->DeleteMenu(idx, MF_BYPOSITION); - if (plugins.GetSize() == 1) { - toolmenu->InsertMenu(idx, MF_BYPOSITION | MF_ENABLED, - ID_FILE_RUNPLUGIN1, pluginTooltips[0]); - } else { - CMenu pluginmenu; - pluginmenu.CreatePopupMenu(); - for(int i = 0; i < min(plugins.GetSize(), ID_FILE_RUNPLUGIN_LAST - ID_FILE_RUNPLUGIN1); ++i) { - pluginmenu.AppendMenu(MF_ENABLED, ID_FILE_RUNPLUGIN1 + i, pluginTooltips[i]); - } - toolmenu->InsertMenu(idx, - plugins.GetSize() ? MF_BYPOSITION | MF_POPUP | MF_ENABLED : MF_BYPOSITION | MF_POPUP | MF_GRAYED, - (UINT_PTR)pluginmenu.Detach(), runPluginLabel); - } - found = true; - } - } else if (!label.CompareNoCase(runInterpreterLabel) || - menuID == ID_FILE_RUNINTERPRETER || menuID == ID_FILE_INTERPRET1) - { - if (dynmenus_need_refresh) { - toolmenu->DeleteMenu(idx, MF_BYPOSITION); - if (interpreters.GetSize() == 1) { - toolmenu->InsertMenu(idx, MF_BYPOSITION | MF_ENABLED, - ID_FILE_INTERPRET1, interpreterTooltips[0]); - } else { - CMenu pluginmenu; - pluginmenu.CreatePopupMenu(); - - struct TooltipSorter { - CString tooltip; - int id; - bool operator<(const TooltipSorter& that) { - return this->tooltip < that.tooltip; - } - }; - std::vector interpreters_sorted; - - for (int i = 0; i < min(interpreters.GetSize(), ID_FILE_INTERPRET_LAST - ID_FILE_INTERPRET1); ++i) { - TooltipSorter tt = { interpreterTooltips[i], ID_FILE_INTERPRET1 + i }; - interpreters_sorted.push_back(std::move(tt)); - } - std::sort(begin(interpreters_sorted), end(interpreters_sorted)); - std::for_each(begin(interpreters_sorted), end(interpreters_sorted), [&](const TooltipSorter& tt) - { - pluginmenu.AppendMenu(MF_ENABLED, tt.id, tt.tooltip); - }); - toolmenu->InsertMenu(idx, - interpreters.GetSize() ? MF_BYPOSITION | MF_POPUP | MF_ENABLED : MF_BYPOSITION | MF_POPUP | MF_GRAYED, - (UINT_PTR)pluginmenu.Detach(), runInterpreterLabel); - } - found = true; - } - } - } - if (found) - dynmenus_need_refresh = false; -} - - -// throws exceptions!! -void CGMEApp::AfterOpenOrCreateProject(const CString &conn) -{ - UpdateProjectName(); - if( mgaProject != NULL ) { - abort_on_close = false; -// get meta - COMTHROW( mgaProject->get_RootMeta(&mgaMetaProject) ); - UpdateComponentLists(); - -// create guimetaproject - ASSERT( guiMetaProject == NULL ); - guiMetaProject = new CGuiMetaProject(mgaMetaProject); - CMainFrame::theInstance->WriteStatusParadigm(guiMetaProject->displayedName); - CMainFrame::theInstance->SetTitle(guiMetaProject->displayedName); - UpdateProjectName(); - -// Register OLE Server / MGA Client - CGMEOLEApp *oleApp = ((CMainFrame*)m_pMainWnd)->mGmeOleApp; - CComBSTR clientName(OLESTR("GME.Application")); - COMTHROW(mgaProject->RegisterClient(clientName, oleApp->GetIDispatch(FALSE), &mgaClient)); // mgaClient increments the refcount of oleApp->idispatch by 1 - - ((CMainFrame*)m_pMainWnd)->setMgaProj(); - -// notify object inspector - ASSERT(CGMEObjectInspector::theInstance!=NULL); - CGMEObjectInspector::theInstance->SetProject(mgaProject); - -// notify Part Browser - ASSERT(CGMEPartBrowser::theInstance!=NULL); - CGMEPartBrowser::theInstance->SetProject(mgaProject); - -// by swapping the order of SetProject (first ObjectInspector, then Browser), -// the user will see the properties of the initally selected project at once -// notify browser - ASSERT( CGMEBrowser::theInstance != NULL ); - CGMEBrowser::theInstance->SetProject(mgaProject); - -// notify search control - ASSERT(CGMESearch::theInstance!=NULL); - CGMESearch::theInstance->SetProject(mgaProject); - - -// change dir - ChangedProjectConnStrings(); -// record connection name - currentConnection = conn; - m_RecentProjectList.AddAndWriteList(conn); - if (!CGMEDoc::theInstance) { - CWinAppEx::OnFileNew(); - } -// start autosave - if (autosaveEnabled) { - CMainFrame::theInstance->StartAutosaveTimer(autosaveFreq); - } - } -} - - -static int guidcmp(VARIANT &qGUID, VARIANT &pGUID) { - GUID g1, g2; - CopyTo(qGUID, g1); - CopyTo(pGUID, g2); - return memcmp(&g1, &g2, sizeof(g1)); -} - -static int versioncmp(CComBSTR &qVer, CComBSTR &pVer) { - CString q(qVer); - CString p(pVer); - - if ((!p.IsEmpty()) && (!q.IsEmpty())) { - return p.Compare(q); - } - return 1; -} - - -bool DiagnoseParadigm(CString metaname, bool syscheck = false) { - CComPtr reg; - try { - HRESULT hr = reg.CoCreateInstance(CComBSTR(L"Mga.MgaRegistrar")); - if(hr != S_OK) { - throw CString(_T("Cannot create the registrar component\n") - _T("We recommend you to reinstall GME")); - } - CComBSTR conn; - CComVariant guid; - hr = reg->QueryParadigm(CComBSTR(metaname), &conn, &guid, - syscheck ? REGACCESS_SYSTEM : REGACCESS_PRIORITY); - if(hr != S_OK) { - throw CString(_T("Cannot access registry info for paradigm ") + metaname + - _T("\nWe recommend you remove and re-register the paradigm")); - } - CComObjPtr paradigm; - hr = paradigm.CoCreateInstance(OLESTR("MGA.MgaMetaProject")); - if(hr != S_OK) { - throw CString(_T("Cannot create the meta component\n") - _T("We recommend you reinstall GME")); - } - - hr = paradigm->Open(conn); - - if(hr != S_OK) { - throw CString(_T("Cannot open the paradigm ") + metaname + _T("\n") - _T("Probable cause is file non-existence,\n") - _T("insufficient access, or format error\n") - _T("Connection string: ") + CString(conn)); - } - - - CComBSTR parname; - CComVariant gguid; - hr = paradigm->get_Name(&parname); - if(hr == S_OK) paradigm->get_GUID(&gguid); - hr |= paradigm->Close(); - - if(hr != S_OK) { - throw CString(_T("Cannot read the paradigm ") + metaname + _T("\n") - _T("Probable cause is file format error\n") - _T("Connection string: ") + CString(conn)); - } - if(!( parname == CComBSTR( (LPCTSTR) metaname))) { - throw CString(_T("The paradigm opened '") + CString(parname) + _T("'\n") - _T("differs from the requested paradigm '")+ metaname + _T("'\n") - _T("We recommend you unregister '") + metaname + _T("'\n") - _T("Connection string: ") + CString(conn)); - - } - - CComBstrObj parg1, parg2; - GUID g; - CopyTo(gguid, g); - CopyTo(g, parg1); - CopyTo(guid, g); - CopyTo(g, parg2); - if(parg1 != parg2) { - throw CString(_T("The GUID in paradigm '") + CString(parname) + _T("'\n") - _T("{") + CString(parg1) + _T("}\n") - _T("differs from the requested GUID for '")+ metaname + _T("'\n") - _T("{") + CString(parg2) + _T("}\n") - _T("We recommend you unregister '") + metaname + _T("'\n") - _T("Connection string: ") + CString(conn)); - } - } catch( CString &c) { - if(!syscheck) { - AfxMessageBox(c); - CComBSTR cc; CComVariant gg; - if(reg && E_NOTFOUND != reg->QueryParadigm(CComBSTR(metaname), &cc, &gg, REGACCESS_SYSTEM)) { - if(DiagnoseParadigm(metaname, true)) { - AfxMessageBox(_T("SYSTEM registry for '") + metaname + _T("' is correct\n") - _T("We recommend you remove the USER registration for ") + metaname); - } - else { - AfxMessageBox(_T("SYSTEM registry for '") + metaname + _T("' is also incorrect\n") - _T("We recommend you reinstall the paradigm.")); - } - } - } - return false; - } - catch(...) { - return false; - } - return true; -} - - - -void CGMEApp::OpenProject(const CString &conn) { - - MSGTRY - { - if (conn.Left(4) == _T("XML=")) { - CString fullPath = conn.Right(conn.GetLength() - 4); - TCHAR buffer[MAX_PATH]; - TCHAR* filepart = NULL; - GetFullPathName(fullPath, MAX_PATH, buffer, &filepart); - if (filepart == NULL) { - COMTHROW(E_FILEOPEN); - } - CString filename = filepart; - CString title = filename.Left(filename.ReverseFind('.')); - Importxml(fullPath, filepart, title); - return; - } - - CWaitCursor wait; - - ASSERT( mgaProject == 0 ); - COMTHROW( mgaProject.CoCreateInstance(OLESTR("Mga.MgaProject")) ); - - VARIANT_BOOL enableAutoAddOns = VARIANT_TRUE; - VARIANT_BOOL readable_only; - - COMTHROW( mgaProject->EnableAutoAddOns(VARIANT_TRUE)); - HRESULT hr = mgaProject->Open(PutInBstr(conn), &readable_only); - if(hr != S_OK) { - _bstr_t mgaProjectOpenError; - GetErrorInfo(mgaProjectOpenError.GetAddress()); - CComBSTR parn; - CComBSTR parv; - long version; - CComVariant parg; - VARIANT_BOOL ro_mode; - if( conn.Left(5) == _T("MGX=\"")) - { - if( E_FILEOPEN == hr) { - consoleMessage( _T("Could not open project!"), MSG_ERROR); - } - else if( E_MGA_PARADIGM_INVALID == hr) { - consoleMessage( _T("Project could not access its original version of paradigm!"), MSG_ERROR); - } - else if( E_MGA_PARADIGM_NOTREG == hr) { - consoleMessage( _T("Project could not access its paradigm!"), MSG_ERROR); - } - else if( E_MGA_META_INCOMPATIBILITY == hr) { - consoleMessage( _T("Versioned project is not compatible with the registered paradigm!"), MSG_ERROR); - } - else if( E_UNKNOWN_STORAGE == hr) { - // no additional comment in this case - } - else { - consoleMessage( _T("Could not open project (unknown error)!"), MSG_ERROR); - } - CloseProject(); - return; // ensures no more exception handlers or explanatory messages (or QueryProjectInfo calls) - } - - COMTHROW(mgaProject->QueryProjectInfo(PutInBstr(conn), &version, &parn, &parv, &parg, &ro_mode)); - while (true) { - CString msg; - CComVariant guidpar; - CString newparname; - bool tryit = false; - - if(hr == E_MGA_MODULE_INCOMPATIBILITY) { - msg = _T("WARNING: The project data is not in the current MGA format\n") - _T("Do you want to upgrade it?"); - if (AfxMessageBox(msg ,MB_OKCANCEL) == IDOK) { - tryit = true; - } - } - if(hr == E_MGA_PARADIGM_INVALID) { - msg = _T("WARNING: Project could not access its original version of\n") - _T("paradigm '") + CString(parn) + _T("'\n"); - if (mgaProjectOpenError.length()) - msg += static_cast(mgaProjectOpenError); - msg += _T("Do you want to try with the current version of the paradigm?"); - if (AfxMessageBox(msg ,MB_OKCANCEL) == IDOK) { - guidpar = true; - tryit = true; - newparname = parn; - } - } - if(hr == E_MGA_PARADIGM_NOTREG) { - CString msg = _T("Could not find paradigm '") + CString(parn) + "'"; - if (parv != "") { - msg += CString(" version ") + static_cast(parv); - } else if (parg.vt == (VT_UI1 | VT_ARRAY)) { - msg += CString(" with GUID ") + StringFromGUID2(parg); - } - IMgaRegistrarPtr registrar; - COMTHROW(registrar.CreateInstance(L"Mga.MgaRegistrar")); - _variant_t current_guid; - _bstr_t current_version; - registrar->QueryParadigm(static_cast(parn), _bstr_t().GetAddress(), current_guid.GetAddress(), REGACCESS_BOTH); - registrar->VersionFromGUID(static_cast(parn), current_guid, current_version.GetAddress(), REGACCESS_BOTH); - if (current_guid.vt != VT_EMPTY || current_version.length()) - { - CString msg_current = msg; - msg_current += L"\nDo you want to open with the current version ("; - if (current_version.length()) - { - msg_current += static_cast(current_version); - } - else if (current_guid.vt == (VT_UI1 | VT_ARRAY)) - { - msg_current += StringFromGUID2(current_guid); - } - msg_current += L")?"; - int mbRes = AfxMessageBox(msg_current, MB_YESNOCANCEL); - if (mbRes == IDCANCEL) - { - break; - } - if (mbRes == IDYES) - { - guidpar = true; - tryit = true; - newparname = parn; - } - } - - if (!tryit) - { - if (CString(parn) == _T("MetaGME2000")) - msg += _T("\n (In GME3 the MetaGME2000 paradigm was renamed to MetaGME)"); - msg += _T("\nDo you want to import with another registered paradigm ?"); - if (AfxMessageBox(msg ,MB_OKCANCEL) == IDOK) { - - CComObjPtr launcher; - COMTHROW( launcher.CoCreateInstance(CComBSTR(L"Mga.MgaLauncher")) ); - if (SUCCEEDED(launcher->MetaDlg(METADLG_NONE))) { - guidpar = true; - newparname.Empty(); - COMTHROW( launcher->get_ParadigmName(PutOut(newparname)) ); - tryit = !newparname.IsEmpty(); - } - } - } - } - if(hr == E_MGA_META_INCOMPATIBILITY && (parv.Length() > 0)) { - msg = _T("WARNING: Versioned project is not compatible with the paradigm '") + CString(parn) + _T("'\n") - _T(" (Eg.: Same version string was assigned to incompatible paradigms)\n") - _T("Do you want to open it based on the paradigm GUID?"); - if (AfxMessageBox(msg ,MB_OKCANCEL) == IDOK) { - guidpar = parg; - tryit = true; - newparname = parn; - } - } - if(hr == E_MGA_COMPONENT_ERROR) { - _bstr_t err(_T("ERROR: automatic addon components could not start up:\n")); - err += mgaProjectOpenError; - err += "\nDo you want to open the project without addons?"; - if (AfxMessageBox(err, MB_YESNO) == IDYES) { - enableAutoAddOns = VARIANT_FALSE; - mgaProject->EnableAutoAddOns(enableAutoAddOns); - tryit = true; - } - } - if(tryit) { - hr = mgaProject->OpenEx(PutInBstr(conn), CComBSTR(newparname), guidpar); - if(hr == E_MGA_PARADIGM_NOTREG || hr == E_MGA_PARADIGM_INVALID) { - DiagnoseParadigm(CString(parn)); - } - } - else break; - } - COMTHROW(hr); - } - - if(readable_only != VARIANT_FALSE) { - AfxMessageBox(_T("WARNING: Project file is read-only\nChange file access or use Save As to save your work")); - } - else { - CComVariant g, g2; - CComBSTR pname; - CComBSTR pver, pver2; - { - CComPtr t; - COMTHROW(mgaProject->CreateTerritory(NULL, &t, NULL)); - COMTHROW(mgaProject->BeginTransaction(t, TRANSACTION_READ_ONLY)); - COMTHROW(mgaProject->get_MetaName(&pname)); - COMTHROW(mgaProject->get_MetaGUID(&g)); - COMTHROW(mgaProject->get_MetaVersion(&pver)); - // COMTHROW(mgaProject->AbortTransaction()); PETER: Why abort ? - COMTHROW(mgaProject->CommitTransaction()); - CComPtr mgareg; - COMTHROW(mgareg.CoCreateInstance(OLESTR("MGA.MgaRegistrar"))); - CComBSTR connstr; - COMTHROW(mgareg->QueryParadigm(pname, &connstr, &g2, REGACCESS_PRIORITY)); - mgareg->VersionFromGUID(pname, g2, &pver2, REGACCESS_PRIORITY); - } - if(guidcmp(g, g2) && versioncmp(pver, pver2)) { - CString project_version = pver; - if (project_version == _T("")) - project_version = StringFromGUID2(g); - CString registered_paradigm_version = pver2; - if (pver2 == _T("")) - registered_paradigm_version = StringFromGUID2(g2); - CString prompt; - prompt.Format(_T("The '%s' paradigm version used to save this file, '%s', is not the currently-registered version, '%s'.\n\n") - _T("Do you want to upgrade to the current paradigm?"), - static_cast(pname), project_version, registered_paradigm_version); - int answer = AfxMessageBox(prompt, MB_YESNO); - if(answer == IDYES) { - COMTHROW(mgaProject->Close(VARIANT_FALSE)); - - // PETER: Create new MgaProject COM object (workaround MGA addon bug) - mgaProject.Release(); - COMTHROW( mgaProject.CoCreateInstance(OLESTR("Mga.MgaProject")) ); - COMTHROW( mgaProject->EnableAutoAddOns(enableAutoAddOns)); - - HRESULT hr = mgaProject->OpenEx(PutInBstr(conn), pname, g2); - if(hr == E_MGA_PARADIGM_NOTREG || hr == E_MGA_PARADIGM_INVALID) { - AfxMessageBox(_T("Paradigm error")); - DiagnoseParadigm(CString(pname)); - } - else if(hr != S_OK) { - AfxMessageBox(_T("Upgrade failed, probably due to incompatibility.\n") - _T("You can probably reopen the file without upgrade,\n") - _T("and use the 'Upgrade through XML' function later.")); - throw_last_com_error(hr); - } - else readable_only = false; - COMTHROW(hr); - } - } - } - AfterOpenOrCreateProject(conn); - hr = mgaProject->Notify(GLOBALEVENT_OPEN_PROJECT_FINISHED); - ASSERT(SUCCEEDED(hr)); - } - MSGCATCH(_T("Could not open project"), CloseProject(true, true)) - - UpdateProjectName(); - -} - - - -void CGMEApp::CreateProject(const CString &metaname, const CString &conn) -{ - CString msg; - try - { - CWaitCursor wait; - - // create the project - msg = _T("Fatal error while initializing project"); - ASSERT( mgaProject == 0 ); - COMTHROW( mgaProject.CoCreateInstance(L"Mga.MgaProject") ); - ASSERT( mgaProject != NULL ); - - COMTHROW( mgaProject->EnableAutoAddOns(VARIANT_TRUE)); - msg = _T("Could not create project"); - HRESULT hr = mgaProject->Create(PutInBstr(conn), PutInBstr(metaname)) ; - if(hr == E_MGA_PARADIGM_NOTREG || hr == E_MGA_PARADIGM_INVALID) { - TCHAR buf[200]; - _stprintf_s(buf, _T("Could not open current version of paradigm %s"), - static_cast(metaname)); - - AfxMessageBox(buf); - DiagnoseParadigm(metaname); - } - if(hr == E_MGA_COMPONENT_ERROR) { - _bstr_t errorInfo; - GetErrorInfo(errorInfo.GetAddress()); - _bstr_t err(_T("ERROR: automatic addon components could not start up:\n")); - err += errorInfo; - err += "\nDo you want to create the project without addons?"; - if (AfxMessageBox(err, MB_YESNO) == IDYES) { - mgaProject->EnableAutoAddOns(VARIANT_FALSE); - hr = mgaProject->Create(PutInBstr(conn), PutInBstr(metaname)) ; - } - } - if( hr == E_UNKNOWN_STORAGE && conn.Left(5) == _T("MGX=\"")) { - CloseProject(); - return; // no more exception handler explanatory messages - } - COMTHROW(hr); - - AfterOpenOrCreateProject(conn); - // TODO: set RootFolder name to filename? - hr = mgaProject->Notify(GLOBALEVENT_OPEN_PROJECT_FINISHED); - ASSERT(SUCCEEDED(hr)); - } - MSGCATCH(_T("Could not create project"), CloseProject()) -} - - -void CGMEApp::SaveProject(const CString &conn) { - if( mgaProject != NULL ) { - HRESULT hr = mgaProject->Save(CComBSTR(conn), VARIANT_FALSE); - if(hr != S_OK) { - CComBSTR error; - if (GetErrorInfo(&error)) { - CString errmsg = _T("Could not save project: "); - errmsg += error; - if (hr == HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED)) { - // FIXME: KMS: not too sure why this is ACCESS_DENIED from MoveFile instead of SHARING_VIOLATION - errmsg += _T("\nCheck that no other GME has this file open"); - } - AfxMessageBox(errmsg); - } else { - AfxMessageBox(_T("ERROR: Could not save project\nCheck access permissions")); - } - } - } - - if ((!conn.IsEmpty()) && (currentConnection != conn)) { - ChangedProjectConnStrings(); - currentConnection = conn; - m_RecentProjectList.AddAndWriteList(conn); - } -} - - - -// ******************************************************************************************** - - -void CGMEApp::GetSettings() -{ - bool oldUseAutoRouting = useAutoRouting; - MSGTRY - { - CComObjPtr registrar; - COMTHROW( registrar.CoCreateInstance(L"Mga.MgaRegistrar") ); - - // Icons - CComBSTR bstr; - COMTHROW( registrar->get_IconPath(REGACCESS_BOTH,&bstr)); - CopyTo(bstr,bitmapPath); - - // Multiview - VARIANT_BOOL enabledmv; - COMTHROW( registrar->get_ShowMultipleView(REGACCESS_USER, &enabledmv) ); - multipleView = (enabledmv != VARIANT_FALSE); - - // Autosave - VARIANT_BOOL autosaveenable; - COMTHROW( registrar->get_AutosaveEnabled(REGACCESS_USER, &autosaveenable) ); - autosaveEnabled = (autosaveenable == VARIANT_FALSE) ? FALSE : TRUE; - - long autosavefreq; - COMTHROW( registrar->get_AutosaveFreq(REGACCESS_USER, &autosavefreq) ); - autosaveFreq = (int)autosavefreq; - - VARIANT_BOOL autosaveusedir; - COMTHROW( registrar->get_AutosaveUseDir(REGACCESS_USER, &autosaveusedir) ); - autosaveUseDir = (autosaveusedir == VARIANT_FALSE) ? 0 : 1; - - COMTHROW( registrar->get_AutosaveDir(REGACCESS_USER, PutOut(autosaveDir)) ); - - //Event Logging - VARIANT_BOOL enablelogging; - COMTHROW( registrar->get_EventLoggingEnabled(REGACCESS_USER, &enablelogging) ); - if(enablelogging != VARIANT_FALSE) - { - CGMEEventLogger::initialize(); - CGMEEventLogger::LogGMEEvent(_T("CGMEApp::GetSettings() Event Logging Enabled\r\n")); - } - else - { - CGMEEventLogger::LogGMEEvent(_T("CGMEApp::GetSettings() Event Logging Disabled\r\n")); - CGMEEventLogger::StopLogging(); - } - - // Autorouter - VARIANT_BOOL useautorouting = VARIANT_TRUE; - COMTHROW( registrar->get_UseAutoRouting(REGACCESS_USER, &useautorouting) ); - useAutoRouting = (useautorouting != VARIANT_FALSE); - - VARIANT_BOOL labelavoidance; - COMTHROW( registrar->get_LabelAvoidance(REGACCESS_USER, &labelavoidance) ); - labelAvoidance = (labelavoidance != VARIANT_FALSE); - - // Default Zoom Level - CComBSTR bstr_zl; - COMTHROW( registrar->GetDefZoomLevel( REGACCESS_USER, &bstr_zl)); - if( bstr_zl) - CopyTo( bstr_zl, defZoomLev); - - // SendMouseOver notification - VARIANT_BOOL send_mouse_over; - COMTHROW( registrar->GetMouseOverNotify(REGACCESS_USER, &send_mouse_over)); - mouseOverNotify = ( send_mouse_over != VARIANT_FALSE); - - // Real number format string - CComBSTR bstr_fmt; - COMTHROW( registrar->GetRealNmbFmtStr( REGACCESS_USER, &bstr_fmt)); - if( bstr_fmt) - CopyTo( bstr_fmt, realFmtStr); - - // History Maintained? - VARIANT_BOOL history_maintained; - COMTHROW( registrar->GetNavigation( REGACCESS_USER, &history_maintained)); - maintainHistory = ( history_maintained != VARIANT_FALSE); - } - MSGCATCH(_T("Error while trying to get program settings"),;); - if(CGMEDoc::theInstance) { - // Global AutoRouting policy changed, convert opened views if necessary - if (!useAutoRouting && oldUseAutoRouting) { - CComPtr nullPtr; - CGMEDoc::theInstance->ConvertPathToCustom(nullPtr); - } - if (autosaveEnabled) { - CMainFrame::theInstance->StartAutosaveTimer(autosaveFreq); - } - else { - CMainFrame::theInstance->StopAutosaveTimer(); - } - CGMEDoc::theInstance->ResetAllViews(); - } -} - -LONG GetRegKey(HKEY key, LPCTSTR subkey, LPTSTR retdata) -{ - HKEY hKey; - LONG lResult = RegOpenKeyEx(key, subkey, 0, KEY_QUERY_VALUE, &hKey); - - if( lResult == ERROR_SUCCESS) - { - long lDataSize = MAX_PATH; - TCHAR data[MAX_PATH]; - - RegQueryValue( hKey, NULL, data, &lDataSize); - lstrcpy( retdata,data); - RegCloseKey( hKey); - } - - return lResult; -} - -HINSTANCE GotoURL(LPCTSTR url, int showcmd) -{ - TCHAR key[MAX_PATH + MAX_PATH]; - - // First try ShellExecute() - HINSTANCE hResult = ShellExecute( NULL, _T("open"), url, NULL,NULL, showcmd); - //HINSTANCE hResult; - // If it failed, get the .htm regkey and lookup the program - if((UINT)hResult <= HINSTANCE_ERROR) - { - if( GetRegKey( HKEY_CLASSES_ROOT, _T(".htm"), key) == ERROR_SUCCESS) - { - lstrcat( key, _T("\\shell\\open\\command")); - - if( GetRegKey( HKEY_CLASSES_ROOT,key,key) == ERROR_SUCCESS) - { - TCHAR *pos; - pos = _tcsstr( key, _T("\"%1\"")); - - if( pos == NULL) - { - // No quotes found - pos = _tcsstr( key, _T("%1")); // Check for % 1, without quotes - if( pos == NULL) // No parameter at all... - pos = key+lstrlen( key)-1; - else - *pos = '\0'; // Remove the parameter - } - else - *pos = '\0'; - // Remove the parameter - - lstrcat(pos, _T(" ")); - lstrcat(pos, url); - - // FIXME: should use CreateProcess - hResult = (HINSTANCE)WinExec( CStringA(key),showcmd); - } - } - } - - return hResult; -} - -///////////////////////////////////////////////////////////////////////////// -// CGMEApp message handlers - -// ******************************************************************************* -// ******************************************************************************* -// FILE -// ******************************************************************************* -// ******************************************************************************* - - -void CGMEApp::OnFileOpen() -{ - CMgaOpenDlg dlg(CMgaOpenDlg::OpenDialog); - CString conn = dlg.AskConnectionString(true, true); - - CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileOpen ")+conn+_T("\r\n")); - - if( conn.IsEmpty() ) - return; - - CWaitCursor wait; - - if( mgaProject != NULL ) - CloseProject(); - - if (conn.Left(4) == _T("MGX=")) { - CString fullPath = conn.Right(conn.GetLength() - 4); - TCHAR buffer[MAX_PATH]; - TCHAR* filepart = NULL; - GetFullPathName(fullPath, MAX_PATH, buffer, &filepart); - if (filepart == NULL) { - DisplayError(_T("Error opening MGX file"), E_FILEOPEN); - return; - } - // FIXME: KMS: yes, the quotes are necessary... - conn = _T("MGX=\""); - // FIXME: KMS: yes, a trailing slash makes it not work - conn += fullPath.Left(fullPath.GetLength() - _tcslen(filepart) - 1); - conn += _T("\""); - } - OpenProject(conn); -} - - -#define PROJECT_STATUS_CHANGED 4 - -void CGMEApp::OnAppExit() -{ - if (SaveAllModified()) - { - CWinAppEx::OnAppExit(); - return; - } -} - -BOOL CGMEApp::SaveAllModified() -{ - // Focus must be killed to flush ObjectInspector and Browser - ::SetFocus(NULL); - if (mgaProject != NULL && (proj_type_is_mga || proj_type_is_xmlbackend)) { - int ret = IDNO; - long l; - COMTHROW(mgaProject->get_ProjectStatus(&l)); - if (l & PROJECT_STATUS_CHANGED) - { - CString filename; - CString connstr = static_cast(mgaProject->ProjectConnStr); - if (connstr.Mid(0, 4) == "MGA=") - { - CString dirname; - GetFullPathName(connstr.Mid(4), filename, dirname); - filename = L" (" + filename + ")"; - } - CString message = _T("Do you want to save changes to '") + projectName + L"'" + filename + _T("?"); - ret = AfxMessageBox(message, MB_YESNOCANCEL); - } - if (ret == IDCANCEL) { - return FALSE; - } else if (ret == IDNO) { - abort_on_close = true; - OnFileAbortProject(); - } else { - ((CMainFrame*)m_pMainWnd)->clearMgaProj(); - return SafeCloseProject(); - } - } - return TRUE; -} - -int CGMEApp::ExitInstance() -{ - CloseProject(false); - -#ifdef _DEBUG - // Do this under Debug to silence memory leaks - // Don't do it under Release, since we may yet crash, and it's wasteful since we're exiting anyway - crUninstall(); -#endif - - return CWinAppEx::ExitInstance(); -} - -void CGMEApp::OnFileNew() -{ - CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileNew\r\n")); - - MSGTRY { - CString metaname; - CString dataconn; - CMgaOpenDlg dlg(CMgaOpenDlg::NewDialog); - - CComObjPtr launcher; - COMTHROW( launcher.CoCreateInstance(L"Mga.MgaLauncher", 0, CLSCTX_INPROC_SERVER) ); - - meta_label: - HRESULT hr = launcher->MetaDlg(METADLG_NEWFILE); - if( hr == S_FALSE ) - return; - COMTHROW( hr ); - - metaname.Empty(); - COMTHROW( launcher->get_ParadigmName(PutOut(metaname)) ); - - dataconn = dlg.AskConnectionString(false, false); - - if( dlg.pressed_back ) - goto meta_label; - - if( dataconn.IsEmpty() ) - return; - - CWaitCursor wait; - - if( mgaProject != NULL ) - CloseProject(); - - CreateProject(metaname, dataconn); - - if (mgaProject != NULL && (proj_type_is_mga||proj_type_is_xmlbackend)) { - OnFileSave(); - } - } - MSGCATCH(_T("Error creating new project"),;) - -} - -BOOL CGMEApp::OnOpenRecentProject(UINT nID) -{ - ASSERT_VALID(this); - - ASSERT(nID >= ID_FILE_MRU_PRJ1); - ASSERT(nID < ID_FILE_MRU_PRJ1 + (UINT)m_RecentProjectList.GetSize()); - - int nIndex = nID - ID_FILE_MRU_PRJ1; - CString conn = m_RecentProjectList[nIndex]; - - ASSERT(conn.GetLength() != 0); - - CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnOpenRecentProject ")+conn+_T("\r\n")); - - CWaitCursor wait; - - if( mgaProject != NULL ) - CloseProject(); - - OpenProject(conn); - - return TRUE; -} - - -bool CGMEApp::SafeCloseProject() { -// In case of an MGA file, try to save it first to find out - abort_on_close = false; - if(mgaProject != NULL && (proj_type_is_mga||proj_type_is_xmlbackend)) { - HRESULT hr = mgaProject->Save(NULL, VARIANT_FALSE); - if(hr != S_OK) { - CComBSTR error; - if (GetErrorInfo(&error)) { - CString errmsg = _T("Could not save project: "); - - errmsg += error; - if (hr == HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED)) { - // FIXME: KMS: not too sure why this is ACCESS_DENIED from MoveFile instead of SHARING_VIOLATION - errmsg += _T("\nCheck that no other GME has this file open"); - } - AfxMessageBox(errmsg); - return false; - } - else { - AfxMessageBox(_T("ERROR: Could not save project\nCheck access permissions")); - return false; - } - } - abort_on_close = true; - } - - BeginWaitCursor(); - if(CGMEDoc::theInstance) - CGMEDoc::theInstance->OnCloseDocument(); - EndWaitCursor(); - return true; -} - -void CGMEApp::OnFileCloseproject() -{ - CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileCloseproject\r\n")); - SaveAllModified(); -#ifdef _DEBUG - //CoFreeUnusedLibraries(); - HMODULE mga = GetModuleHandle(L"Mga.dll"); - if (mga) - { - typedef HRESULT (__stdcall *DllCanUnloadNow)(void); - DllCanUnloadNow proc = (DllCanUnloadNow)GetProcAddress(mga, "DllCanUnloadNow"); - if (proc && (*proc)() != S_OK) - { - DebugBreak(); - // If Mga.dll is compiled with /D_ATL_DEBUG_INTERFACES, this will dump the leaks via OutputDebugString (then crash later) - FreeLibrary(mga); - } - } -#endif -} - - -void CGMEApp::OnFileSaveAs() { - CMgaOpenDlg dlg(CMgaOpenDlg::SaveAsDialog); - CString conn = dlg.AskMGAConnectionString(); - - CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileSaveAs ")+conn+_T("\r\n")); - - if( conn.IsEmpty() ) - return; - BeginWaitCursor(); - SaveProject(conn); - EndWaitCursor(); -} - -void CGMEApp::OnFileSave() -{ - CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileSave\r\n")); - // GME-307 Focus must be killed to flush ObjectInspector and Browser - ::SetFocus(NULL); - - BeginWaitCursor(); - SaveProject(_T("")); - EndWaitCursor(); -} - -void CGMEApp::OnFileAbortProject() -{ - CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileAbortProject\r\n")); - ((CMainFrame*)m_pMainWnd)->clearMgaProj(); - - long l; - COMTHROW(mgaProject->get_ProjectStatus(&l)); - if(!abort_on_close && IsUndoPossible() && (l & PROJECT_STATUS_CHANGED) && - AfxMessageBox(_T("Discard edits to project ") + projectName + _T("?"), - MB_OKCANCEL) == IDCANCEL) { - return; - } - abort_on_close = true; - - BeginWaitCursor(); - if(CGMEDoc::theInstance) - CGMEDoc::theInstance->OnCloseDocument(true); - EndWaitCursor(); -} - - -void CGMEApp::OnFileExportxml() -{ - CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileExportxml ")); - MSGTRY - { - CComPtr dumper; - COMTHROW( dumper.CoCreateInstance(L"Mga.MgaDumper") ); - ASSERT( dumper != NULL ); - - CString initialFile; - CString initialDir; - if (theApp.isMgaProj()) { - getMgaPaths(initialFile, initialDir); - if (initialFile.Right(3) == _T("mga")) { - initialFile.Truncate(initialFile.GetLength() - 3); - initialFile += _T("xme"); - } - } - - CFileDialog dlg(FALSE, _T("xme"), initialFile, - OFN_EXPLORER | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR, - _T("Exported Files (*.xme)|*.xme|All Files (*.*)|*.*||")); - if (initialDir) - { - dlg.GetOFN().lpstrInitialDir = initialDir; - } - if( dlg.DoModal() != IDOK ) - { - CGMEEventLogger::LogGMEEvent(_T("Canceled\r\n")); - return; - } - CGMEEventLogger::LogGMEEvent(dlg.GetPathName()+_T("\r\n")); - - CWaitCursor wait; - IMgaDumper2Ptr dumper2 = (IMgaDumper*)dumper; - if (dumper2 && m_pMainWnd) - dumper2->__DumpProject2(theApp.mgaProject, _bstr_t(dlg.GetPathName()), (ULONGLONG)(m_pMainWnd->GetSafeHwnd())); - else - dumper->__DumpProject(theApp.mgaProject, _bstr_t(dlg.GetPathName())); - - if( CMainFrame::theInstance) CMainFrame::theInstance->m_console.Message( CString( _T("Project successfully exported into ")) + dlg.GetPathName() + _T("."), 1); - } - MSGCATCH(_T("Error while generating XML file"),;) -} - - -void CGMEApp::OnFileImportxml() -{ - CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileImportxml ")); - - CString new_file_name = _T(""); - - MSGTRY - { - CFileDialog dlg(TRUE, _T("xme"), (LPCTSTR) new_file_name, - OFN_EXPLORER | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | - OFN_FILEMUSTEXIST, - _T("GME Exported Files (*.xme;*.xml)|*.xme; *.xml|All Files (*.*)|*.*||")); - if( dlg.DoModal() != IDOK ) - { - CGMEEventLogger::LogGMEEvent(_T("Cancelled\r\n")); - return; - } - CGMEEventLogger::LogGMEEvent(dlg.GetPathName()+_T("\r\n")); - CString fullPath = dlg.GetPathName(); - CString fname = dlg.GetFileName(); - CString ftitle = dlg.GetFileTitle(); - Importxml(fullPath, fname, ftitle); - } - MSGCATCH(_T("Error importing XML file"),;) -} - -void CGMEApp::Importxml(CString fullPath, CString fname, CString ftitle) -{ - CComPtr parser; - COMTHROW( parser.CoCreateInstance(L"Mga.MgaParser") ); - ASSERT( parser != NULL ); - - CString folderPath = fullPath.Left(fullPath.GetLength() - fname.GetLength()); - - if (fullPath.Right(3).CompareNoCase(_T("xml")) == 0 ) { - AfxMessageBox( - _T("Newer versions of GME use the \".xme.\" filename extension\n") - _T("for exported XML data files.\n") - _T("Please, rename your existing files to avoid further problems!\n"), - MB_OK | MB_ICONINFORMATION); - } - - bool newproject = !mgaProject; - if (newproject) { - CString dataconn; - COMTRY { - CComBstrObj xmeparadigm, xmeparversion, xmebasename, xmeversion; - CComVariant xmeparguid, parguid; - - COMTHROW( parser->GetXMLInfo(PutInBstr(fullPath), PutOut(xmeparadigm), PutOut(xmeparversion), &xmeparguid, PutOut(xmebasename), PutOut(xmeversion)) ); - parguid = xmeparguid; - - CMgaOpenDlg opdlg(CMgaOpenDlg::ImportDialog); - if (ftitle.IsEmpty()) - opdlg.SetFileNameHint(PutInCString(xmebasename)); - else - opdlg.SetFileNameHint(ftitle); - opdlg.SetFolderPathHint(folderPath); - dataconn = opdlg.AskConnectionString(false, false); - if (dataconn.IsEmpty()) { - CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileImportxml exited because empty connection string has been given")); - return; - } - - { - CComPtr reg; - COMTHROW( reg.CoCreateInstance(L"Mga.MgaRegistrar") ); - CComBstrObj conn; - HRESULT h1 = reg->QueryParadigm(xmeparadigm, PutOut(conn), &xmeparguid, REGACCESS_PRIORITY); - CComVariant regparguid; - conn.Empty(); - HRESULT h2 = reg->QueryParadigm(xmeparadigm, PutOut(conn), ®parguid, REGACCESS_PRIORITY); - CComBstrObj regCurrentVersion; - if (SUCCEEDED(h2)) { - reg->VersionFromGUID(xmeparadigm, regparguid, ®CurrentVersion.p, REGACCESS_PRIORITY); - } - - CComVariant regGuidFromVersion; - HRESULT h3GuidFromVersion = E_FAIL; - if (xmeparversion.Length() != 0) { - h3GuidFromVersion = reg->GUIDFromVersion(xmeparadigm, xmeparversion, ®GuidFromVersion, REGACCESS_PRIORITY); - if (SUCCEEDED(h3GuidFromVersion)) - { - xmeparguid = regGuidFromVersion; - } else - { - h1 = E_MGA_PARADIGM_NOTREG; - } - } - - TCHAR buf[300]; - if(h2 != S_OK) { - ASSERT(h1 != S_OK); - CString msg = _T("Could not find paradigm paradigm '") + CString(xmeparadigm) + "'"; - if (CString(xmeparadigm) == _T("MetaGME2000")) - msg += _T("\n (In GME3 the MetaGME2000 paradigm was renamed to MetaGME)"); - msg += _T("\nDo you want to import with an other registered paradigm ?"); - if (AfxMessageBox(msg ,MB_OKCANCEL) == IDOK) { - CComObjPtr launcher; - COMTHROW( launcher.CoCreateInstance(CComBSTR(L"Mga.MgaLauncher")) ); - if (SUCCEEDED(launcher->MetaDlg(METADLG_NONE))) { - // parguid = true; - parguid.Clear(); - xmeparadigm.Empty(); - COMTHROW( launcher->get_ParadigmName(PutOut(xmeparadigm)) ); - } - else { - return; // safe before create - } - } - else { - return; // safe before create - } - } - else { - CComBstrObj bstrxmeparguid, bstrregparguid; - GUID gg; - - CopyTo(xmeparguid,gg); - CopyTo(gg, bstrxmeparguid); - - CopyTo(regparguid,gg); - CopyTo(gg, bstrregparguid); - - if(h1 != S_OK) { - _stprintf_s(buf, _T("Could not locate paradigm %s, version '%s'.\n\n") - _T("Do you want to upgrade to the current version ('%s') instead?"), - static_cast(xmeparadigm), - static_cast(xmeparversion.Length() != 0 ? xmeparversion : bstrxmeparguid), - static_cast(regCurrentVersion.Length() != 0 ? regCurrentVersion : bstrregparguid)); - if(AfxMessageBox(buf, MB_OKCANCEL | MB_ICONQUESTION) == IDOK) { - parguid = regparguid; - } - else { - // AfxMessageBox(_T("Import canceled")); - return; // safe before create - } - - } - else if(bstrxmeparguid.Compare(bstrregparguid)) { - _stprintf_s(buf, _T("This model was exported using paradigm %s, version '%s'.\n\n") - _T("Do you want to upgrade to the current version ('%s')?"), - static_cast(xmeparadigm), - static_cast(xmeparversion.Length() != 0 ? xmeparversion : bstrxmeparguid), - static_cast(regCurrentVersion.Length() != 0 ? regCurrentVersion : bstrregparguid)); - int answer = AfxMessageBox(buf,MB_YESNOCANCEL | MB_ICONQUESTION); - if(answer == IDYES) { - parguid = regparguid; - } - else if(answer == IDCANCEL) { - // AfxMessageBox(_T("Import canceled")); - return; // safe before create - } - } - } - } - COMTHROW( mgaProject.CoCreateInstance(L"Mga.MgaProject") ); - COMTHROW( mgaProject->EnableAutoAddOns(VARIANT_TRUE)); - HRESULT hr = mgaProject->CreateEx(PutInBstr(dataconn), PutInBstr(xmeparadigm), parguid); - if(hr == E_MGA_PARADIGM_NOTREG || hr == E_MGA_PARADIGM_INVALID) { - TCHAR buf[300]; - CComBstrObj parguid1; - GUID gg; - CopyTo(parguid,gg); - CopyTo(gg, parguid1); - _stprintf_s(buf, _T("Could not open paradigm %s\nVersion ID: %s"), - static_cast(xmeparadigm), static_cast(parguid1)); - - AfxMessageBox(buf); - } - if(hr == E_MGA_COMPONENT_ERROR) { - _bstr_t errorInfo; - GetErrorInfo(errorInfo.GetAddress()); - _bstr_t err(_T("ERROR: automatic addon components could not start up:\n")); - err += errorInfo; - err += "\nDo you want to create the project without addons?"; - if (AfxMessageBox(err, MB_YESNO) == IDYES) { - mgaProject->EnableAutoAddOns(VARIANT_FALSE); - hr = mgaProject->CreateEx(PutInBstr(dataconn), PutInBstr(xmeparadigm), parguid); - } - } - COMTHROW(hr); - AfterOpenOrCreateProject(dataconn); - } catch(hresult_exception &e) { - CloseProject(); - DisplayError(_T("Could not create the project"), e.hr); - throw; - } - } - - //UpdateProjectName(); // moved below - - CWaitCursor wait; - if(mgaConstMgr) COMTHROW(mgaConstMgr->Enable(VARIANT_FALSE)); - - CString file_name = fullPath; - if( CMainFrame::theInstance) CMainFrame::theInstance->m_console.Message( CString( _T("Importing ")) + file_name + _T("..."), 1); - IMgaParser2Ptr parser2 = (IMgaParser*)parser; - if (parser2 && m_pMainWnd) - parser2->__ParseProject2(theApp.mgaProject, _bstr_t(fullPath), (ULONGLONG)(m_pMainWnd->GetSafeHwnd())); - else - COMTHROW(parser->ParseProject(theApp.mgaProject, PutInBstr(fullPath))); - - // mgaproject has been filled with data, let's update title: - UpdateProjectName(); - - if(newproject && (proj_type_is_mga||proj_type_is_xmlbackend)) { - OnFileSave(); - } - - if (CMainFrame::theInstance) - CMainFrame::theInstance->m_console.Message(fullPath + _T(" was successfully imported."), 1); - else - AfxMessageBox(fullPath + _T(" was successfully imported.")); - - if (mgaConstMgr) - COMTHROW(mgaConstMgr->Enable(VARIANT_TRUE)); - HRESULT hr = mgaProject->Notify(GLOBALEVENT_OPEN_PROJECT_FINISHED); - ASSERT(SUCCEEDED(hr)); -} - - - -void CGMEApp::OnFileXMLUpdate() -{ - CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileXMLUpdate\r\n")); - ASSERT(mgaProject); - ASSERT(mgaMetaProject); - - TCHAR xmlname[MAX_PATH]; - GetTempFileName(_T("."), _T("XEX"),0, xmlname); - - if(currentConnection.Find(_T("MGA=")) != 0) { - AfxMessageBox(_T("Function is available only for .mga models")); - } - - CString fname = currentConnection.Mid(4); - CString backupname; - - MSGTRY - { - CWaitCursor wait; - CComBstrObj parname; - COMTHROW( mgaMetaProject->get_Name(PutOut(parname)) ); - CComBstrObj metaconn; - - CComPtr reg; - COMTHROW( reg.CoCreateInstance(L"Mga.MgaRegistrar") ); - CComBstrObj currentguid; - GUID currentguid_guid; - { - CComVariant parguid; - COMTHROW( mgaMetaProject->get_GUID(&parguid) ); - - CComVariant pg2; - - COMTHROW(reg->QueryParadigm(parname, PutOut(metaconn), &pg2, REGACCESS_PRIORITY)); - - CComBstrObj parguid1; - GUID gg; - CopyTo(parguid,gg); - CopyTo(gg, parguid1); - - CopyTo(pg2,gg); - currentguid_guid = gg; - CopyTo(gg, currentguid); - - if(!parguid1.Compare(currentguid)) { - TCHAR buf[200]; - _stprintf_s(buf, _T("There is no need to upgrade this model\nIts Meta Version ID is the current ID\nCurrent ID: %s"), - static_cast(currentguid)); - AfxMessageBox(buf); - return; - } - } - - CComPtr dumper; - COMTHROW( dumper.CoCreateInstance(L"Mga.MgaDumper") ); - ASSERT( dumper != NULL ); - - COMTHROW( dumper->DumpProject(theApp.mgaProject, PutInBstr(CString(xmlname))) ); - - - SafeCloseProject(); - ASSERT(!mgaProject); - - backupname = fname; - int p = backupname.ReverseFind('.'); - if(!p || backupname.Find('\\',p) != -1) p = backupname.GetLength(); - backupname.Insert(p,_T("-backup")); - DeleteFile(backupname); - if(!MoveFile(fname, backupname)) { - backupname = fname; - CString buf; - buf.Format(L"Could not save original file '%s' to '%s'", - static_cast(fname), static_cast(backupname)); - AfxMessageBox(buf); - COMTHROW(E_NOTFOUND); - } - - - - CreateProject(PutInCString(parname), currentConnection); - - if(!mgaProject || !mgaMetaProject) { - AfxMessageBox(_T("Error creating project")); - return; - } - - UpdateComponentLists(); - ChangedProjectConnStrings(); - - CComPtr parser; - COMTHROW( parser.CoCreateInstance(L"Mga.MgaParser") ); - ASSERT( parser != NULL ); - if(mgaConstMgr) COMTHROW(mgaConstMgr->Enable(VARIANT_FALSE)); - IMgaParser2Ptr parser2 = (IMgaParser*)parser; - if (parser2 && m_pMainWnd) - COMTHROW(parser2->ParseProject2(mgaProject,PutInBstr(CString(xmlname)), (ULONGLONG)(m_pMainWnd->GetSafeHwnd()))); - else - COMTHROW(parser->ParseProject(mgaProject,PutInBstr(CString(xmlname))) ); - { - _bstr_t version; - _variant_t v_guid; - CopyTo(currentguid_guid, &v_guid); - reg->VersionFromGUID(parname, v_guid, version.GetAddress(), REGACCESS_PRIORITY); - CString buf = CString(_T("The model has been updated.\nCurrent version: ")) - + (version.length() ? static_cast(version) : currentguid) + L"\nThe original model has been saved to " + backupname; - AfxMessageBox(buf); - } - } - catch(hresult_exception &e) { - if(backupname.IsEmpty()) { - CString buf; - buf.Format(L"The upgrade failed: 0x%x\nThe model has not been closed", e.hr); - AfxMessageBox(buf); - } - else { - if(backupname.Compare(fname)) { - if(MoveFile(backupname, fname)) backupname = fname; - } - CString buf; - buf.Format(L"The upgrade failed: 0x%x\nThe original model is in file %s", e.hr, - static_cast(backupname)); - AfxMessageBox(buf); - } - } - - if (mgaConstMgr) COMTHROW(mgaConstMgr->Enable(VARIANT_TRUE)); -} - - - -void CGMEApp::OnFileRegcomponents() -{ - CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileRegcomponents ")); - MSGTRY - { - CComObjPtr launcher; - COMTHROW( launcher.CoCreateInstance(L"Mga.MgaLauncher") ); - COMTHROW( launcher->put_ParadigmName(PutInBstr(guiMetaProject->name))); - COMTHROW( launcher->put_ComponentType(COMPONENTTYPE_ALL) ); - - ATLASSERT(mgaProject); - CComBSTR runningcomps; - { - CComPtr comps; - COMTHROW(mgaProject->get_AddOnComponents(&comps)); - MGACOLL_ITERATE(IMgaComponent, comps) { - CComQIPtr compx = MGACOLL_ITER; - CComBSTR p; - if(compx) COMTHROW(compx->get_ComponentProgID(&p)); - else COMTHROW(MGACOLL_ITER->get_ComponentName(&p)); - if(runningcomps) runningcomps += _T(" "); - runningcomps += p; - } - MGACOLL_ITERATE_END; - } - // FIXME: huge kludge here: enables CCompDlg to show which addons are running - COMTHROW(launcher->put_Parameter(CComVariant(runningcomps))); - - CGMEEventLogger::LogGMEEvent(CString(runningcomps)+_T("\r\n")); - - COMTHROW( launcher->ComponentDlg(COMPONENTDLG_INTERP)); - UpdateComponentLists(true); - } - MSGCATCH(_T("Error while trying to register the interpreter"),;) -} - -void CGMEApp::OnFileSettings() -{ - CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileSettings\r\n")); - MSGTRY - { - CComObjPtr launcher; - COMTHROW( launcher.CoCreateInstance(L"Mga.MgaLauncher") ); - COMTHROW( launcher->GmeDlg()); - } - MSGCATCH(_T("Error while trying to get GME settings"),;) - GetSettings(); -} - -void CGMEApp::OnFileClearLocks() -{ - if( mgaProject != NULL || mgaMetaProject != NULL ) - return; - - MSGTRY - { - CMgaOpenDlg dlg(CMgaOpenDlg::ClearLocksDialog); - CString conn = dlg.AskConnectionString(false, true); - - if( conn.IsEmpty() ) - return; - - CWaitCursor wait; - - CComObjPtr project; - COMTHROW( project.CoCreateInstance(OLESTR("MGA.MgaProject")) ); - ASSERT( project != NULL ); - COMTHROW( project->CheckLocks(PutInBstr(conn), VARIANT_TRUE) ); - - AfxMessageBox(_T("Database locks are cleared")); - } - MSGCATCH(_T("Error while clearing locks in database"),;) -} - -void CGMEApp::OnHelpContents() -{ - CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnHelpContents\r\n")); - - MSGTRY { - CComObjPtr launcher; - COMTHROW( launcher.CoCreateInstance(L"Mga.MgaLauncher") ); - COMTHROW( launcher->ShowHelp(NULL) ); - } - MSGCATCH(_T("Error while showing help contents."),;) -} - -void CGMEApp::OnFileCheckall() -{ - CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileCheckall\r\n")); - ASSERT(mgaConstMgr); - if (!mgaConstMgr) - return; - // message boxes displayed from constraint manager if in interactive mode - mgaConstMgr->ObjectsInvokeEx(mgaProject, NULL, NULL, NULL); -} - -void CGMEApp::OnFileDisplayConstraints() -{ - CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileDisplayConstraints\r\n")); - ASSERT(mgaConstMgr); - if (!mgaConstMgr) - return; - mgaConstMgr->ObjectsInvokeEx(mgaProject, NULL, NULL, CONSTMGR_SHOW_CONSTRAINTS); - -} - - - -void CGMEApp::OnFileRegparadigms() -{ - CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileRegparadigms\r\n")); - MSGTRY - { - CComPtr launcher; - COMTHROW( launcher.CoCreateInstance(L"Mga.MgaLauncher", 0, CLSCTX_INPROC_SERVER) ); - - while(1) { - HRESULT hr = launcher->MetaDlg(METADLG_PARREG); - if( hr == S_FALSE ) return; - - COMTHROW( launcher->put_ComponentType(COMPONENTTYPE_ALL) ); - - bool workonrunningparadigm = false; - if(guiMetaProject) { - CComBstrObj metaname; - COMTHROW( launcher->get_ParadigmName(PutOut(metaname)) ); - if(metaname == PutInBstr(guiMetaProject->name)) workonrunningparadigm = true; - } - - if(workonrunningparadigm) { - ATLASSERT(mgaProject); - CComBSTR runningcomps; - CComPtr comps; - COMTHROW(mgaProject->get_AddOnComponents(&comps)); - MGACOLL_ITERATE(IMgaComponent, comps) { - CComQIPtr compx = MGACOLL_ITER; - CComBSTR p; - if(compx) COMTHROW(compx->get_ComponentProgID(&p)); - else COMTHROW(MGACOLL_ITER->get_ComponentName(&p)); - if(runningcomps) runningcomps += _T(" "); - runningcomps += p; - } - MGACOLL_ITERATE_END; - COMTHROW(launcher->put_Parameter(CComVariant(runningcomps))); - } - - COMTHROW( launcher->ComponentDlg(COMPONENTDLG_INTERP)); - - if(workonrunningparadigm) UpdateComponentLists(true); - } - } MSGCATCH(_T("Error registering paradigms"), ;); -} - - -// ******************************************************************************* - -void CGMEApp::OnUpdateFileNew(CCmdUI* pCmdUI) -{ - pCmdUI->Enable(guiMetaProject == NULL); -} - -void CGMEApp::OnUpdateFileOpen(CCmdUI* pCmdUI) -{ - pCmdUI->Enable(guiMetaProject == NULL); -} - -void CGMEApp::OnUpdateFileCloseproject(CCmdUI* pCmdUI) -{ - pCmdUI->Enable(guiMetaProject != NULL); -} - -void CGMEApp::OnUpdateFileSave(CCmdUI* pCmdUI) -{ - pCmdUI->Enable(mgaProject != NULL && (proj_type_is_mga||proj_type_is_xmlbackend)); -} - -void CGMEApp::OnUpdateFileSaveAs(CCmdUI* pCmdUI) -{ - pCmdUI->Enable(mgaProject != NULL && proj_type_is_mga); -} - -void CGMEApp::OnUpdateFileAbortProject(CCmdUI* pCmdUI) -{ - pCmdUI->Enable(mgaProject != NULL && proj_type_is_mga); -} - -void CGMEApp::OnUpdateFileExportxml(CCmdUI* pCmdUI) -{ - pCmdUI->Enable(guiMetaProject != NULL); -} - -void CGMEApp::OnUpdateFileXMLUpdate(CCmdUI* pCmdUI) -{ - pCmdUI->Enable(mgaProject != NULL && proj_type_is_mga); -} - -void CGMEApp::OnUpdateFileCheckall(CCmdUI* pCmdUI) -{ - pCmdUI->Enable(mgaConstMgr != NULL); -} - -void CGMEApp::OnUpdateFileDisplayConstraints(CCmdUI* pCmdUI) -{ - pCmdUI->Enable(mgaConstMgr != NULL); - -} - -void CGMEApp::OnUpdateFileRegcomponents(CCmdUI* pCmdUI) -{ - pCmdUI->Enable(guiMetaProject != NULL); -} - -void CGMEApp::OnUpdateRecentProjectMenu(CCmdUI* pCmdUI) -{ - ASSERT_VALID(this); - m_RecentProjectList.UpdateMenu(pCmdUI,guiMetaProject == NULL); -} - - -// ******************************************************************************* -// ******************************************************************************* -// EDIT -// ******************************************************************************* -// ******************************************************************************* - - -void CGMEApp::OnEditProjectproperties() -{ - CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnEditProjectproperties ") + projectName +_T("\r\n")); - CProjectPropertiesDlg dlg; - if(dlg.DoModal() == IDOK) { - if(CGMEDoc::theInstance) - CGMEDoc::theInstance->SetTitle(projectName); - UpdateMainFrameTitle(projectName); - } -} - - -void CGMEApp::OnEditUndo() -{ - CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnEditUndo\r\n")); - mgaProject->Undo(); -} - -void CGMEApp::OnEditRedo() -{ - CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnEditRedo\r\n")); - mgaProject->Redo(); -} - -void CGMEApp::OnEditClearUndo() -{ - CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnEditClearUndo\r\n")); - if( mgaProject == NULL ) - return; - - if(AfxMessageBox(_T("You are about to lose all Undo/Redo information. Proceed?"),MB_YESNO | MB_ICONQUESTION) == IDYES) { - MSGTRY - { - COMTHROW( mgaProject->FlushUndoQueue() ); - } - MSGCATCH(_T("Error while clearing the undo queue"),;) - } -} - - -// ******************************************************************************* - -void CGMEApp::OnUpdateEditUndo(CCmdUI* pCmdUI) -{ - if(guiMetaProject != NULL) { - short undoSize; - short redoSize; - mgaProject->UndoRedoSize(&undoSize,&redoSize); - pCmdUI->Enable(undoSize > 0); - } - else - pCmdUI->Enable(FALSE); -} - -void CGMEApp::OnUpdateEditRedo(CCmdUI* pCmdUI) -{ - if(guiMetaProject != NULL) { - short undoSize; - short redoSize; - mgaProject->UndoRedoSize(&undoSize,&redoSize); - pCmdUI->Enable(redoSize > 0); - } - else - pCmdUI->Enable(FALSE); -} - -void CGMEApp::OnUpdateEditClearUndo(CCmdUI* pCmdUI) -{ - if(mgaProject != NULL) { - short undoSize; - short redoSize; - mgaProject->UndoRedoSize(&undoSize,&redoSize); - pCmdUI->Enable(undoSize > 0); - } - else - pCmdUI->Enable(FALSE); -} - -void CGMEApp::OnUpdateEditProjectproperties(CCmdUI* pCmdUI) -{ - pCmdUI->Enable(CGMEDoc::theInstance != 0); -} - - - -/* -void CGMEApp::OnUpdateFileRunplugin1(CCmdUI* pCmdUI) -{ - - CMenu *filemenu = pCmdUI->m_pMenu; - UINT idx = pCmdUI->m_nIndex; -if(idx == 0) return; - CString label; - ASSERT(filemenu); - filemenu->GetMenuString(idx,label,MF_BYPOSITION); - filemenu->DeleteMenu(idx,MF_BYPOSITION); - CMenu pluginmenu; - pluginmenu.CreatePopupMenu(); - pluginmenu.GetMenuItemID - for(int i = 0; i < comps.GetSize(); ++i) { - pluginmenu.AppendMenu(MF_ENABLED, pCmdUI->m_nID + i,comps[i]); - } - filemenu->InsertMenu(idx, - comps.GetSize() ? MF_BYPOSITION|MF_POPUP|MF_ENABLED: MF_BYPOSITION|MF_POPUP|MF_GRAYED, - (UINT)pluginmenu.Detach(),label); - -} -*/ - -void CGMEApp::OnRunPlugin(UINT nID) { - CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnRunPlugin ")+plugins[nID - ID_FILE_RUNPLUGIN1]+_T("\r\n")); - - // Focus must be killed to flush ObjectInspector and Browser - ::SetFocus(NULL); - - RunComponent(plugins[nID - ID_FILE_RUNPLUGIN1]); -} - -void CGMEApp::OnRunInterpreter(UINT nID) { - CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnRunInterpreter ")+interpreters[nID - ID_FILE_INTERPRET1]+_T("\r\n")); - - // Focus must be killed to flush ObjectInspector and Browser - ::SetFocus(NULL); - - RunComponent(interpreters[nID - ID_FILE_INTERPRET1]); -} - - - -void CGMEApp::RunComponent(const CString &compname) -{ - - IMgaLauncherPtr launcher; - launcher.CreateInstance(L"Mga.MgaLauncher"); - if(!launcher) { - AfxMessageBox(_T("Cannot start up component launcher")); - } - else { - CComPtr focus; - CComPtr selfcos; - COMTHROW(selfcos.CoCreateInstance(OLESTR("Mga.MgaFCOs"))); - CMDIChildWnd *pChild = CMainFrame::theInstance->MDIGetActive(); - if (pChild) { -#if !defined (ACTIVEXGMEVIEW) - CGMEView *view = (CGMEView*)pChild->GetActiveView(); - if (view) { - COMTHROW(view->currentModel.QueryInterface(&focus)); - POSITION pos = view->selected.GetHeadPosition(); - while (pos) { - CGuiFco *gfco = view->selected.GetNext(pos); - COMTHROW(selfcos->Append(gfco->mgaFco)); - } - } -#endif - } - - if(theApp.bNoProtect) COMTHROW( launcher->put_Parameter(CComVariant(true))); - // Disable the DCOM wait dialogs: if interpreters want them, they can do it themselves; but if they don't want them, they need to link to GME's mfc1xxu.dll - COleMessageFilter* messageFilter = AfxOleGetMessageFilter(); - messageFilter->EnableBusyDialog(FALSE); - messageFilter->EnableNotRespondingDialog(FALSE); - std::shared_ptr busyRestore(messageFilter, [](COleMessageFilter* filter){ filter->EnableBusyDialog(TRUE); } ); - std::shared_ptr notRespondingRestore(messageFilter, [](COleMessageFilter* filter){ filter->EnableNotRespondingDialog(TRUE); } ); - if(launcher->RunComponent(PutInBstr(compname), mgaProject, focus, selfcos, GME_MENU_START) != S_OK) { - CComObjPtr errinfo; - GetErrorInfo(0, PutOut(errinfo)); - if (errinfo) { - _bstr_t desc; - errinfo->GetDescription(desc.GetAddress()); - std::wstring error; - error += L"Component execution failed: "; - error += desc; - AfxMessageBox(error.c_str()); - } else { - AfxMessageBox(_T("Component execution failed")); - } - } - } -} - -class CGmePrintSetup : public CPrintDialog -{ -public: - enum { IDD = IDD_PRINT_DIALOG }; - CGmePrintSetup() : CPrintDialog(true, 0, NULL) {} -}; - -void CGMEApp::OnUniquePrintSetup() -{ - CGmePrintSetup setup; - setup.m_pd.Flags = PD_PRINTSETUP | // actually the current aspect - PD_ENABLESETUPTEMPLATE | - PD_ENABLEPRINTHOOK | PD_ENABLESETUPHOOK ; - setup.m_pd.hInstance = AfxGetInstanceHandle(); - setup.m_pd.lpSetupTemplateName = MAKEINTRESOURCE(IDD_PRINTSETUP_DIALOG); - DoPrintDialog(&setup); -} - -void CGMEApp::ImportDroppedFile(const CString& fname) -{ - CGMEEventLogger::LogGMEEvent(_T("CGMEApp::ImportDroppedFile ")); - - CString file_name = fname; - - MSGTRY - { - int fnameStart = fname.ReverseFind('\\'); - if (fnameStart == -1) - fnameStart = fname.ReverseFind('/'); - - CString ftitle; - CString fpath; - if (fnameStart != -1) { - fpath = fname.Left(fnameStart + 1); - ftitle = fname.Right(fname.GetLength() - fnameStart - 1); - int extStart = ftitle.ReverseFind('.'); - if (extStart != -1) - ftitle = ftitle.Left(extStart); - } - Importxml(file_name, file_name.Right(file_name.GetLength() - fnameStart), ftitle); - } - MSGCATCH(_T("Error importing XML file"),;) -} - -void CGMEApp::RegisterDroppedFile( const CString& fname, bool userReg/* = true*/) -{ - try - { - CWaitCursor wait; - IMgaRegistrarPtr registrar; - COMTHROW(registrar.CreateInstance(L"Mga.MgaRegistrar")); - - regaccessmode_enum reg_access = REGACCESS_USER; - - _bstr_t newname; - registrar->__RegisterParadigmFromData(_bstr_t(fname), newname.GetAddress(), reg_access); - - CMainFrame::theInstance->m_console.Message( _T("Done."), 1); - } - catch( hresult_exception &e) - { - CMainFrame::theInstance->m_console.Message( _T("Error while registering paradigm."), 3); - } - catch(_com_error &e) - { - _bstr_t error(L""); - if (e.Description() != _bstr_t()) - error = e.Description(); - else - GetErrorInfo(e.Error(), error.GetAddress()); - CMainFrame::theInstance->m_console.Message(CString("Error while registering paradigm: ") + static_cast(error), 3); - } -} - -void CGMEApp::OnUpdateFilePluginX(CCmdUI* pCmdUI) -{ - bool enabled = m_vecDisabledPlugIns.find( pCmdUI->m_nID) == m_vecDisabledPlugIns.end(); - if( pCmdUI->m_nID >= ID_FILE_RUNPLUGIN1 && pCmdUI->m_nID <= ID_FILE_RUNPLUGIN_LAST) - pCmdUI->Enable( enabled ); -} - -void CGMEApp::OnUpdateFileInterpretX(CCmdUI* pCmdUI) -{ - bool enabled = m_vecDisabledComps.find( pCmdUI->m_nID) == m_vecDisabledComps.end(); - if( pCmdUI->m_nID >= ID_FILE_INTERPRET1 && pCmdUI->m_nID <= ID_FILE_INTERPRET_LAST) - pCmdUI->Enable( enabled ); -} - -// this method is used internally -void CGMEApp::ClearDisabledComps() -{ - m_vecDisabledPlugIns.clear(); - m_vecDisabledComps.clear(); -} - -// this method is called from CGMEOLEApp::DisableComp -// and CGMEApp::UpdateCompList4CurrentKind -void CGMEApp::DisableComp( const CString& pCompToFind, bool pbHide) -{ - UINT id_of_comp = 0; - bool is_plugin = false; - for(int i = 0; !id_of_comp && i < plugins.GetSize(); ++i) - { - if( plugins[i] == pCompToFind) - { - id_of_comp = ID_FILE_RUNPLUGIN1 + i; - is_plugin = true; - } - } - - for(int i = 0; !id_of_comp && i < interpreters.GetSize(); ++i) - { - if( interpreters[i] == pCompToFind) - { - id_of_comp = ID_FILE_INTERPRET1 + i; - is_plugin = false; - } - } - - if( id_of_comp) // a valid command ID - { - //ActivateComp( id_of_comp, is_plugin, pbShow); - if( is_plugin) - { - ONE_ID_LIST::const_iterator pos = m_vecDisabledPlugIns.find( id_of_comp); - if( pbHide) // disable, so id_of_comp must be inserted into the vector - { - if( m_vecDisabledPlugIns.end() == pos) // not found - m_vecDisabledPlugIns.insert( m_vecDisabledPlugIns.end(), id_of_comp); - } - else // enable, so remove id_of_comp from the vector - { - if( m_vecDisabledPlugIns.end() != pos) // if really found - m_vecDisabledPlugIns.erase( pos); - } - } - else - { - ONE_ID_LIST::const_iterator pos = m_vecDisabledComps.find( id_of_comp); - if( pbHide) // disable, so id_of_comp must be inserted into the vector - { - if( m_vecDisabledComps.end() == pos) // not found - m_vecDisabledComps.insert( m_vecDisabledComps.end(), id_of_comp); - } - else // enable, so remove id_of_comp from the vector - { - if( m_vecDisabledComps.end() != pos) // if really found - m_vecDisabledComps.erase( pos); - } - } - } -} - -// this method is called from CGMEOLEApp::DisableCompForKinds -void CGMEApp::DisableCompForKinds( const CString& pComp, const CString& pKindSeq) -{ - int nm_of_tokens = 0; // will count the parsed kind names - int pos = 0; - CString t_kind; - t_kind = pKindSeq.Tokenize( _T(";"), pos); // tokenize by ';' - while( t_kind != _T("")) - { - ONE_COMP_LIST &my_comps = m_compsOfKind[ t_kind ]; - ONE_COMP_LIST::const_iterator it = my_comps.find( pComp); - if( it == my_comps.end()) // not found, so insert it - m_compsOfKind[ t_kind ].insert( pComp); - - ++nm_of_tokens; - t_kind = pKindSeq.Tokenize( _T(";"), pos); // move to next token - } -} - -// this method is called from CGMEView::OnActivateView (with the kindname shown) -// CGMEView::~CGMEView (with the special string: _NO_MODEL_IS_OPEN_ == m_no_model_open_string) -// CGMEApp::SetCompFiltering (with one from the items above) -void CGMEApp::UpdateCompList4CurrentKind( const CString& pKind) -{ - // if filter is OFF return - if( !m_compFilterOn) - { - return; - } - - // kind name should not be empty - if( pKind.IsEmpty()) { ASSERT(0); return; } - - ClearDisabledComps(); // reset all to original state (enabled) - - if( m_compsOfKind.find( pKind) != m_compsOfKind.end()) // if it has an entry - { - ONE_COMP_LIST &my_comps = m_compsOfKind[ pKind]; // this key already existed - for( ONE_COMP_LIST::const_iterator it = my_comps.begin(); it != my_comps.end(); ++it) - { - DisableComp( *it, true); // disable comps which are registered for this kind - } - } // if this kind has no assigned [excluded] component set: NOP [every component is enabled] -} - -void CGMEApp::SetCompFiltering( bool pOn) -{ - m_compFilterOn = pOn; - if( !m_compFilterOn) // if turned OFF - { - ClearDisabledComps(); // reset all to original state (enabled) - } - else // turned ON - { - // find the current view - bool found = false; - CMDIChildWnd *pChild = CMainFrame::theInstance->MDIGetActive(); - if( pChild) - { -#if !defined (ACTIVEXGMEVIEW) - CGMEView *view = (CGMEView*)pChild->GetActiveView(); - if( view && view->guiMeta) - { - found = true; - this->UpdateCompList4CurrentKind( view->guiMeta->name); - } -#endif - } - - if( !found) - this->UpdateCompList4CurrentKind( CGMEApp::m_no_model_open_string); - } -} - -bool CGMEApp::GetCompFiltering() -{ - return m_compFilterOn; -} - -bool CGMEApp::SetWorkingDirectory( LPCTSTR pPath) -{ - return SetCurrentDirectory( pPath) == TRUE; - //int sc = _chdir( pPath); - //return sc == 0; -} - -void CGMEApp::UpdateMainTitle(bool retrievePath) -{ - if (CMainFrame::theInstance) - UpdateMainFrameTitle(projectName, retrievePath); -} - -bool CGMEApp::IsUndoPossible(void) const -{ - if(!mgaProject) - return false; - - if (guiMetaProject != NULL) { - short undoSize; - short redoSize; - mgaProject->UndoRedoSize(&undoSize,&redoSize); - return undoSize > 0; - } - - return false; -} - -void CGMEApp::OnFocusBrowser() -{ - if( !mgaProject) return; - - CComObjPtr terry; - COMTHROW(mgaProject->CreateTerritory(NULL, PutOut(terry), NULL) ); - - LPUNKNOWN objs = CGMEObjectInspector::theInstance->GetObjects(); - CComQIPtr one_obj_coll( objs); - long len = 0; - if( one_obj_coll) COMTHROW( one_obj_coll->get_Count( &len)); - if( len >= 1) - { - MSGTRY - { - CComPtr one_obj, one_obj2; - long status = OBJECT_ZOMBIE; - CComBSTR id; - COMTHROW( one_obj_coll->get_Item( 1, &one_obj)); - COMTHROW( mgaProject->BeginTransaction(terry,TRANSACTION_READ_ONLY)); - - if( one_obj) COMTHROW( terry->OpenObj( one_obj, &one_obj2)); - if( one_obj2) { - COMTHROW( one_obj2->get_Status( &status)); - COMTHROW( one_obj2->get_ID( &id)); - } - - COMTHROW( mgaProject->CommitTransaction()); - - if( id.Length() > 0 && status == OBJECT_EXISTS) - { - CGMEBrowser::theInstance->FocusItem( id); - return; - } - } - MSGCATCH(_T("Error getting project rootfolder"), mgaProject->AbortTransaction()) - } - - MSGTRY - { - CComBSTR id; - CComPtr rf; - COMTHROW(mgaProject->BeginTransaction(terry,TRANSACTION_READ_ONLY)); - COMTHROW(mgaProject->get_RootFolder( &rf)); - if( rf) COMTHROW(rf->get_ID(&id)); - COMTHROW(mgaProject->CommitTransaction()); - - if( id.Length() > 0) - CGMEBrowser::theInstance->FocusItem( id); - } - MSGCATCH(_T("Error getting project rootfolder"), mgaProject->AbortTransaction()) -} - -void CGMEApp::OnFocusInspector() -{ - HWND hwnd = CGMEObjectInspector::theInstance->GetSafeHwnd(); - if( hwnd) ::SetFocus( hwnd); -} - -void CGMEApp::consoleMessage( const CString& p_msg, short p_type) -{ - if( CMainFrame::theInstance) // 99.99% of cases - CMainFrame::theInstance->m_console.Message( p_msg, p_type); - else - AfxMessageBox( p_msg); -} - -#ifdef _DEBUG -extern "C" FILE * __cdecl __iob_func(void) -{ - terminate(); - return NULL; -} - -// https://msdn.microsoft.com/en-us/library/bb531344.aspx#BK_CRT "Visual C++ 2015 Conformance Changes C Runtime Library(CRT)" -#pragma comment(lib, "legacy_stdio_definitions.lib") -#endif +// GMEApp.cpp : Defines the class behaviors for the application. +// + +#include "stdafx.h" +#include // for CWaitCursor +#include "GMEApp.h" +#include "GMEVersion.h" + + +#include "Parser.h" + +#include "GMEstd.h" +#include "GuiMeta.h" +#include "MainFrm.h" +#include "ChildFrm.h" +#include "GMEDoc.h" +#include "GMEView.h" +#include "GMEChildFrame.h" +#include "GMEBrowser.h" +#include "GMEObjectInspector.h" +#include +#include "MgaOpenDlg.h" +#include "GmeDocTemplate.h" +#include "ProjectPropertiesDlg.h" +#include "GmeLib.h" +#include "GMEOLEApp.h" +#include "GMEEventLogger.h" +#include "GMEPrintDialog.h" +#include + +#include "CrashRpt.h" +#ifdef _DEBUG +#pragma comment(lib, "CrashRpt1403.lib") +// https://msdn.microsoft.com/en-us/library/bb531344.aspx#BK_CRT +#pragma comment(lib, "legacy_stdio_definitions.lib") +#else +#pragma comment(lib, "CrashRpt1403.lib") +#endif + +#import "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorlib.tlb" no_implementation +namespace CSGUI { +using namespace mscorlib; +} +#import "CSGUI.tlb" no_implementation + +#ifndef _DEBUG +#pragma comment(linker, "\"/manifestdependency:type='win32' name='Core' version='1.0.0.0' language='*'\"") +#pragma comment(linker, "\"/manifestdependency:type='win32' name='Meta' version='1.0.0.0' language='*'\"") +#pragma comment(linker, "\"/manifestdependency:type='win32' name='Mga' version='1.0.0.0' language='*'\"") +#endif + +#include "CrashTest.h" +#include +#include "GraphicsUtil.h" +#include + + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +// ATL /////////////////////////////////////////////////////////////////////////// +#include +#include "mga_i.c" +#include "meta_i.c" +#include "Splash.h" + +CComModule _Module; + + +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// CGMEApp + +BEGIN_MESSAGE_MAP(CGMEApp, CWinAppEx) + //{{AFX_MSG_MAP(CGMEApp) + ON_COMMAND(ID_APP_ABOUT, OnAppAbout) + ON_COMMAND(ID_FILE_OPEN, OnFileOpen) + ON_COMMAND(ID_FILE_NEW, OnFileNew) + ON_UPDATE_COMMAND_UI(ID_FILE_CLOSEPROJECT, OnUpdateFileCloseproject) + ON_COMMAND(ID_FILE_CLOSEPROJECT, OnFileCloseproject) + ON_UPDATE_COMMAND_UI(ID_FILE_NEW, OnUpdateFileNew) + ON_UPDATE_COMMAND_UI(ID_FILE_OPEN, OnUpdateFileOpen) + ON_COMMAND(ID_EDIT_UNDO, OnEditUndo) + ON_COMMAND(ID_EDIT_REDO, OnEditRedo) + ON_UPDATE_COMMAND_UI(ID_EDIT_REDO, OnUpdateEditRedo) + ON_UPDATE_COMMAND_UI(ID_FILE_EXPORTXML, OnUpdateFileExportxml) + ON_COMMAND(ID_FILE_EXPORTXML, OnFileExportxml) + ON_COMMAND(ID_FILE_IMPORTXML, OnFileImportxml) + ON_UPDATE_COMMAND_UI(ID_EDIT_PROJECTPROPERTIES, OnUpdateEditProjectproperties) + ON_COMMAND(ID_EDIT_PROJECTPROPERTIES, OnEditProjectproperties) + ON_COMMAND(ID_FILE_SETTINGS, OnFileSettings) + ON_COMMAND(ID_FILE_CLEARLOCKS, OnFileClearLocks) + ON_COMMAND(ID_EDIT_CLEARUNDO, OnEditClearUndo) + ON_UPDATE_COMMAND_UI(ID_EDIT_CLEARUNDO, OnUpdateEditClearUndo) + ON_COMMAND(ID_HELP_CONTENTS, OnHelpContents) + ON_COMMAND(ID_FILE_CHECKALL, OnFileCheckall) + ON_UPDATE_COMMAND_UI(ID_FILE_CHECKALL, OnUpdateFileCheckall) + ON_UPDATE_COMMAND_UI(ID_FILE_SAVEPROJECT, OnUpdateFileSave) + ON_UPDATE_COMMAND_UI(ID_FILE_SAVEPROJECTAS, OnUpdateFileSaveAs) + ON_COMMAND(ID_FILE_SAVEPROJECTAS, OnFileSaveAs) + ON_COMMAND(ID_FILE_SAVEPROJECT, OnFileSave) + ON_COMMAND(ID_FILE_ABORTPROJECT, OnFileAbortProject) + ON_UPDATE_COMMAND_UI(ID_FILE_ABORTPROJECT, OnUpdateFileAbortProject) + ON_COMMAND(ID_FILE_REGCOMPONENTS, OnFileRegcomponents) + ON_COMMAND(ID_FILE_REGPARADIGMS, OnFileRegparadigms) + ON_UPDATE_COMMAND_UI(ID_FILE_REGCOMPONENTS, OnUpdateFileRegcomponents) + ON_UPDATE_COMMAND_UI(ID_FILE_UPDATETHROUGHXML, OnUpdateFileXMLUpdate) + ON_COMMAND(ID_FILE_UPDATETHROUGHXML, OnFileXMLUpdate) + ON_COMMAND(ID_FILE_DISPLAY_CONSTRAINTS, OnFileDisplayConstraints) + ON_UPDATE_COMMAND_UI(ID_FILE_DISPLAY_CONSTRAINTS, OnUpdateFileDisplayConstraints) + ON_COMMAND(ID_APP_EXIT, OnAppExit) + ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO, OnUpdateEditUndo) + //}}AFX_MSG_MAP + // Standard file based document commands +// ON_COMMAND(ID_FILE_NEW, CWinAppEx::OnFileNew) +// ON_COMMAND(ID_FILE_OPEN, CWinAppEx::OnFileOpen) + // Standard print setup command + ON_COMMAND(ID_FILE_PRINT_SETUP, OnUniquePrintSetup) // CWinAppEx::OnFilePrintSetup) + // MRU - most recently used project menu + ON_UPDATE_COMMAND_UI(ID_FILE_MRU_PRJ1, OnUpdateRecentProjectMenu) + ON_COMMAND_EX_RANGE(ID_FILE_MRU_PRJ1, ID_FILE_MRU_PRJ16, OnOpenRecentProject) + ON_COMMAND_RANGE(ID_FILE_RUNPLUGIN1, ID_FILE_RUNPLUGIN_LAST, OnRunPlugin) + ON_COMMAND_RANGE(ID_FILE_INTERPRET1, ID_FILE_INTERPRET_LAST, OnRunInterpreter) + ON_COMMAND_RANGE(ID_HELP_PARADIGMHELP_FIRST, ID_HELP_PARADIGMHELP_LAST, OnRunParadigmHelp) + ON_COMMAND_RANGE(ID_HELP_COMPONENTHELP_FIRST, ID_HELP_COMPONENTHELP_LAST, OnRunComponentHelp) + ON_UPDATE_COMMAND_UI_RANGE(ID_FILE_RUNPLUGIN1, ID_FILE_RUNPLUGIN_LAST, OnUpdateFilePluginX) + ON_UPDATE_COMMAND_UI_RANGE(ID_FILE_INTERPRET1, ID_FILE_INTERPRET_LAST, OnUpdateFileInterpretX) + ON_COMMAND(ID_FOCUS_BROWSER, OnFocusBrowser) + ON_COMMAND(ID_FOCUS_INSPECTOR, OnFocusInspector) +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// The one and only CGMEApp object + +CGMEApp theApp; + +// This identifier was generated to be statistically unique for your app. +// You may change it if you prefer to choose a specific identifier. + + +/*static*/ const TCHAR * CGMEApp::m_no_model_open_string = _T("_NO_MODEL_IS_OPEN_"); + +CComBSTR StringFromGUID2(const CComVariant& guid) +{ + ASSERT(guid.vt == (VT_UI1 | VT_ARRAY)); + GUID guid2; + CopyTo(guid, guid2); + CComBSTR strGuid; + CopyTo(guid2, &strGuid.m_str); + return strGuid; +} + +///////////////////////////////////////////////////////////////////////////// +// CGMEApp construction + +CGMEApp::CGMEApp() : + m_RecentProjectList(0, _T("Recent Project List"), _T("Project%d"), 8) + , m_compFilterOn( false) +{ + multipleView = false; + useAutoRouting = true; + labelAvoidance = false; + defZoomLev = _T("100"); + mouseOverNotify = false; + maintainHistory = false; + realFmtStr = _T("%.12g"); + // TODO: add construction code here, + + // Place all significant initialization in InitInstance + SIZE size; + size.cx = 16; + size.cy = 16; + m_userImages.SetImageSize(size); +} + +CGMEApp::~CGMEApp() +{ +} + +class CGMECommandLineInfo : public CCommandLineInfo { +public: + bool bNoProtect, bOpenLast; + CString run; + CGMECommandLineInfo() : bNoProtect(false), bOpenLast(false) { ; } + + virtual void ParseParam(const TCHAR* pszParam, BOOL bFlag, BOOL bLast) { + + if(bFlag && !_wcsicmp(pszParam, L"d")) bNoProtect = true; + else if(bFlag && !_wcsicmp(pszParam, L"l")) bOpenLast = true; + else if(bFlag && _wcsnicmp(pszParam, L"run:", 4) == 0) + { + run = pszParam + 4; + } + else CCommandLineInfo::ParseParam(pszParam, bFlag, bLast); + } + +}; + + +bool CheckInterfaceVersions() { + bool err = false; + LPCOLESTR components[] = { + L"Mga.MgaProject", + L"Mga.MgaMetaProject", + L"Mga.CoreProject", + L"Mga.MgaRegistrar", + L"Mga.MgaParser", + L"Mga.AddOn.ConstraintManager", + NULL }; + CString errstring; + HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + TCHAR hrbuf[20]; + if(hr != S_OK) AfxMessageBox(CString(_T("Coinitialize failure. Err: #")) + _ltot(hr,hrbuf,16)); + for(LPCOLESTR *p = components; *p; p++) { + GMEInterfaceVersion verid = GMEInterfaceVersion_None; + CComPtr unk; + CString ee; + if(S_OK != (hr = unk.CoCreateInstance(*p))) { + { + _com_error error(hr); + errstring.Format(_T("Cannot create object %%s (Err: #%X, %s)"), hr, error.ErrorMessage()); + } +gerr: + CString a; + a.Format(errstring, *p, verid/0x1000, verid%0x1000, GMEInterfaceVersion_Current/0x1000,GMEInterfaceVersion_Current%0x1000); + AfxMessageBox(a); + err = true; + continue; + } + CComQIPtr vinf = unk; + if(!vinf) { + errstring = _T("Incompatible version of object %s (does not support version information)"); + goto gerr; + } + if(S_OK != vinf->get_version(&verid)) { + errstring = _T("Get_Version failed for object %s"); + goto gerr; + } + if(verid != GMEInterfaceVersion_Current) { + errstring = _T("Interface version for class %s (%d.%d) differs from GME interface version (%d.%d)"); + goto gerr; + } + } + return err; +} + + +CString getUserRegistryStringValue(const TCHAR* name) { + CString ret; + HKEY hKey; + if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Software\\GME\\"), + 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) + { + TCHAR szData[256]; + DWORD dwKeyDataType; + DWORD dwDataBufSize = sizeof(szData) / sizeof(TCHAR); + + if (RegQueryValueEx(hKey, name, NULL, &dwKeyDataType, + (LPBYTE)&szData, &dwDataBufSize) == ERROR_SUCCESS) + { + ret = CString(szData, dwDataBufSize); + } + + RegCloseKey(hKey); + } + return ret; +} + +///////////////////////////////////////////////////////////////////////////// +// CGMEApp initialization + +BOOL CGMEApp::InitInstance() +{ + // InitCommonControlsEx() is required on Windows XP if an application + // manifest specifies use of ComCtl32.dll version 6 or later to enable + // visual styles. Otherwise, any window creation will fail. + INITCOMMONCONTROLSEX InitCtrls; + InitCtrls.dwSize = sizeof(InitCtrls); + // Set this to include all the common control classes you want to use + // in your application. + InitCtrls.dwICC = ICC_WIN95_CLASSES; + InitCommonControlsEx(&InitCtrls); + +#if _MSC_VER < 1700 + // See MSDN example code for CWinApp::InitInstance: http://msdn.microsoft.com/en-us/library/ae6yx0z0.aspx + // MFC module state handling code is changed with VC80. + // We follow the Microsoft's suggested way, but in case of any trouble the set the + // HKCU\Software\GME\AfxSetAmbientActCtxMod key to 0 + UINT uAfxSetAmbientActCtxMod = 1; + HKEY hKey; + if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Software\\GME\\"), + 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) + { + TCHAR szData[128]; + DWORD dwKeyDataType; + DWORD dwDataBufSize = sizeof(szData)/sizeof(TCHAR); + + if (RegQueryValueEx(hKey, _T("AfxSetAmbientActCtxMod"), NULL, &dwKeyDataType, + (LPBYTE) &szData, &dwDataBufSize) == ERROR_SUCCESS) + { + uAfxSetAmbientActCtxMod = _tcstoul(szData, NULL, 10); + } + + RegCloseKey(hKey); + } + if (uAfxSetAmbientActCtxMod != 0) + { + AfxSetAmbientActCtx(FALSE); + } +#endif + + CWinAppEx::InitInstance(); + + // CG: The following block was added by the Splash Screen component. + CGMECommandLineInfo cmdInfo; + ParseCommandLine(cmdInfo); + + if( cmdInfo.m_nShellCommand == CCommandLineInfo::FileOpen || cmdInfo.m_nShellCommand == CCommandLineInfo::AppRegister) + ; + cmdInfo.m_bShowSplash = false; + + CSplashWnd::EnableSplashScreen(cmdInfo.m_bShowSplash); + // CG: The following block was inserted by 'Status Bar' component. + { + //Set up date and time defaults so they're the same as system defaults + setlocale(LC_ALL, ""); + } + + //if(CheckInterfaceVersions()) return FALSE; + + + // Initialize OLE libraries + if (!AfxOleInit()) + { + AfxMessageBox(IDP_OLE_INIT_FAILED); + return FALSE; + } + + AfxEnableControlContainer(); + + EnableTaskbarInteraction(); + + // Standard initialization + // If you are not using these features and wish to reduce the size + // of your final executable, you should remove from the following + // the specific initialization routines you do not need. + +#ifdef _AFXDLL + //Enable3dControls(); // deprecated +#else + Enable3dControlsStatic(); // Call this when linking to MFC statically +#endif + + + // Enable assigning shortcut keys to the menus + InitKeyboardManager(); + + // Enabling user tools + EnableUserTools(ID_TOOLS_EXTERNAL_TOOLS, ID_USER_TOOL1, ID_USER_TOOL10, RUNTIME_CLASS(CUserTool)/*, IDR_MENU_ARGS, IDR_MENU_DIRS*/); + + InitContextMenuManager(); + + // Change the registry key under which our settings are stored. + // TODO: You should modify this string to be something appropriate + // such as the name of your company or organization. + SetRegistryKey(_T("GME\\GUI")); + + LoadStdProfileSettings(); // Load standard INI file options (including MRU) + m_RecentProjectList.ReadList(); + + + // Load Accelerator Table for CGMEView + + m_GMEView_hAccel = LoadAccelerators(m_hInstance, MAKEINTRESOURCE(IDR_GMEVIEW)); + ASSERT( m_GMEView_hAccel ); + + // Register the application's document templates. Document templates + // serve as the connection between documents, frame windows and views. + + pDocTemplate = new CGmeDocTemplate( + IDR_GMETYPE, + RUNTIME_CLASS(CGMEDoc), + RUNTIME_CLASS(CChildFrame), // custom MDI child frame +#if !defined(ACTIVEXGMEVIEW) + RUNTIME_CLASS(CGMEView)); +#else + RUNTIME_CLASS(CGMEChildFrame)); +#endif + pDocTemplate->SetContainerInfo(IDR_GMETYPE_CNTR_IP); + AddDocTemplate(pDocTemplate); + + + + // create main MDI Frame window + CMainFrame* pMainFrame = new CMainFrame; + if (!pMainFrame->LoadFrame(IDR_MAINFRAME)) + { + // n.b. if LoadFrame fails, CFrameWnd::PostNcDestroy is called which does `delete this` + // delete pMainFrame; + return FALSE; + } + m_pMainWnd = pMainFrame; + pMainFrame->CheckForOffscreenPanes(); + +#if !defined(ADDCRASHTESTMENU) && defined(_DEBUG) + bNoProtect = true; +#else + bNoProtect = cmdInfo.bNoProtect; +#endif + + //initialize the logfile - first check registry to see if the user wants logging + MSGTRY + { + CComPtr registrar; + COMTHROW(registrar.CoCreateInstance(CComBSTR(L"Mga.MgaRegistrar"))); + VARIANT_BOOL enablelogging; + COMTHROW( registrar->get_EventLoggingEnabled(REGACCESS_USER, &enablelogging) ); + if(enablelogging != VARIANT_FALSE) + { + CGMEEventLogger::initialize(); + CGMEEventLogger::LogGMEEvent("GME started\r\n"); + } + } + MSGCATCH(_T("Error while trying to get logfile settings"),;); + + ASSERT((CMainFrame*)m_pMainWnd); + CGMEOLEApp *t_pGmeOleApp = new CGMEOLEApp(); + ((CMainFrame*)m_pMainWnd)->setGmeOleApp( t_pGmeOleApp ); + + // Register all OLE server factories as running. This enables the + // OLE libraries to create objects from other applications. + COleObjectFactory::RegisterAll(); + // Note: MDI applications register all server objects without regard + // to the /Embedding or /Automation on the command line. + // Note: we switched the default REGCLS_MULTIPLEUSE behavior to REGCLS_SINGLEUSE, + // see GMEOLEApp.cpp's MY_IMPLEMENT_OLECREATE macro, and + // "How to use single or multiple instances of an OLE object in MFC by using Visual C++" KB article: + // http://support.microsoft.com/kb/141154 + + // Check to see if launched as OLE server + if (cmdInfo.m_bRunEmbedded || cmdInfo.m_bRunAutomated) + { + // Application was run with /Embedding or /Automation. Don't show the + // main window in this case. + + // + // load settings in this case as well + GetSettings(); + + return TRUE; + } + + // Updates system registry with all creatable classes (_OLECREATE) + // PETER: It works only with administrator priviledges + COleObjectFactory::UpdateRegistryAll(); + + // Make sure the type library is registered or dual interface won't work. + AfxOleRegisterTypeLib(AfxGetInstanceHandle(), __uuidof(__GmeLib)); + + // Dispatch commands specified on the command line + if ((cmdInfo.m_nShellCommand == CCommandLineInfo::AppRegister || cmdInfo.m_nShellCommand == CCommandLineInfo::AppUnregister) && !ProcessShellCommand(cmdInfo)) + return FALSE; + + // The main window has been initialized, so show and update it. + pMainFrame->ShowWindow(m_nCmdShow); + pMainFrame->UpdateWindow(); + + + dynmenus_need_refresh = true; + + GetSettings(); + m_pMainWnd->DragAcceptFiles(TRUE); + + return TRUE; +} + +BOOL CGMEApp::PreTranslateMessage(MSG* pMsg) +{ + // CG: The following lines were added by the Splash Screen component. + if (CSplashWnd::PreTranslateAppMessage(pMsg)) + return TRUE; + // KMS: m_pMainWnd->PreTranslateMessage here for Alt-F,C. Otherwise, CGMEView::PreTranslateMessage TranslateAccelerator will return TRUE + if (m_pMainWnd && m_pMainWnd->PreTranslateMessage(pMsg)) + return TRUE; + + return CWinAppEx::PreTranslateMessage(pMsg); +} + + + +///////////////////////////////////////////////////////////////////////////// +// CGMEApp emergency + +void CGMEApp::EmergencySave(void) +{ + CGMEEventLogger::LogGMEEvent("EMERGENCY EVENT\r\n"); + if (mgaProject && (proj_type_is_mga || proj_type_is_xmlbackend)) { + CString embackupname = currentConnection; + int p = embackupname.ReverseFind('.'); + if ((p == -1) || embackupname.Find('\\', p) != -1) + p = embackupname.GetLength(); + CString emcode; + static int emnum; + emcode.Format(_T("-emergency%ld"), ++emnum); + embackupname.Insert(p, emcode); + long status = 0; + mgaProject->get_ProjectStatus(&status); // ignore failure + if (status == 3 || status == 4) // i.e. in tx + mgaProject->AbortTransaction(); // ignore failure + HRESULT hr = mgaProject->Save(PutInBstr(embackupname), VARIANT_TRUE); + if (proj_type_is_xmlbackend) { + AfxMessageBox(_T("Your current work can be found in the local checkout directory.")); + } else { + CString emergencySaveMsg; + emergencySaveMsg.FormatMessage(_T("Your current work %1 been saved to %2.\n") + _T("The original project file has not been modified. ") + _T("We apologize for the inconvenience."), + (hr == S_OK)? _T("has") : _T("might have"), + embackupname); + AfxMessageBox(emergencySaveMsg); + m_RecentProjectList.AddAndWriteList(embackupname); + } + } +} + +BOOL CGMEApp::OpenCommandLineProject() +{ + CGMECommandLineInfo cmdInfo; + ParseCommandLine(cmdInfo); + // We don't want a new document at startup + if(cmdInfo.m_nShellCommand == CCommandLineInfo::FileNew) + cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing; + if (cmdInfo.m_nShellCommand == CCommandLineInfo::AppRegister) + cmdInfo.bOpenLast = true; + if(cmdInfo.m_nShellCommand == CCommandLineInfo::FileOpen) + { + CString conn = cmdInfo.m_strFileName; + if(conn.Find(_T("=")) < 0) { + if (conn.Right(4).CompareNoCase(_T(".xme")) == 0) + conn.Insert(0, _T("XML=")); + else + conn.Insert(0,_T("MGA=")); + } + OpenProject(conn); + + cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing; + return TRUE; + } + else if(cmdInfo.bOpenLast && !m_RecentProjectList[0].IsEmpty()) + { + OpenProject(m_RecentProjectList[0]); + cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing; + return TRUE; + } else if(cmdInfo.run != "") + { + if (CMainFrame::theInstance) + CMainFrame::theInstance->m_console.m_Console.RunCode(CComBSTR(cmdInfo.run)); + return TRUE; + } + + // Dispatch commands specified on the command line + //if (!ProcessShellCommand(cmdInfo)) + // return FALSE; + if (!(cmdInfo.m_bRunEmbedded || cmdInfo.m_bRunAutomated)) + { + ShowWelcomeWindow(); + } + return FALSE; +} + +BOOL CGMEApp::ShowWelcomeWindow() +{ + CSGUI::_WelcomeScreenExpPtr ws; + ws.CreateInstance(L"CSGUI.WelcomeScreenExp"); + if (ws) + try { + ATL::CComSafeArray recents; + for (int i = 0; i < m_RecentProjectList.GetSize(); i++) + { + recents.Add(CComBSTR(m_RecentProjectList[i])); + } + VARIANT vrecents; + vrecents.parray = (SAFEARRAY*)recents; + vrecents.vt = VT_ARRAY | VT_BSTR; + ws->SetRecentProjects(_variant_t(vrecents)); + _bstr_t SelectedProject = ws->ShowWelcomeWindow((unsigned long)m_pMainWnd->GetSafeHwnd()); + + if (SelectedProject != _bstr_t()) { + if (SelectedProject == ws->CREATE_SENTINEL) { + OnFileNew(); + } else { + CString conn = static_cast(SelectedProject); + if(conn.Find(_T("=")) < 0) { + if (conn.Right(4).CompareNoCase(_T(".xme")) == 0) + conn.Insert(0, _T("XML=")); + else if (conn.Right(4).CompareNoCase(_T(".mgx")) == 0) + { + CString filename, dirname; + GetFullPathName(conn, filename, dirname); + conn = CString(L"MGX=\"") + dirname + L"\""; + } + else + conn.Insert(0,_T("MGA=")); + } + OpenProject(conn); + } + } + } catch (_com_error& e) { + //AfxMessageBox(e.ErrorMessage()); + } + return TRUE; +} + +// CInvalidArgException _simpleInvalidArgException(FALSE); +static void (__stdcall *InvalidArg)() = nullptr; +void __stdcall InvalidArgReplacement() { + CR_EXCEPTION_INFO ei; + memset(&ei, 0, sizeof(CR_EXCEPTION_INFO)); + ei.cb = sizeof(CR_EXCEPTION_INFO); + ei.exctype = CR_SEH_EXCEPTION; + ei.code = 1234; + ei.pexcptrs = NULL; + + int result = crGenerateErrorReport(&ei); + + if (result != 0) + { + TCHAR szErrorMsg[256]; + crGetLastErrorMsg(szErrorMsg, 256); + AfxMessageBox(szErrorMsg); + } + // FIXME: this shows "Internal application error" instead of invalid argument + throw new CInvalidArgException(); +} + +static void HookInvalidArg() { +#if defined(_M_IX86) + // reg add HKCU\Software\GME /v HookInvalidArg /d 1 /t REG_SZ /f + if (getUserRegistryStringValue(L"HookInvalidArg") == L"1") { + InvalidArg = &AfxThrowInvalidArgException; + int** invalidArg = (int**)(2 + ((char*)(void*)InvalidArg)); + DWORD oldProtect; + if (VirtualProtect((LPVOID)**invalidArg, 5, PAGE_EXECUTE_READWRITE, &oldProtect)) { + int invalidArgHook = (int)(void*)&InvalidArgReplacement; + ptrdiff_t diff = invalidArgHook - **invalidArg; + diff -= 5; + *((char*)**invalidArg) = 0xe9; + *((int*)(1 + (char*)**invalidArg)) = diff; + // AfxThrowInvalidArgException(); + } + } +#endif +} + +int CGMEApp::Run() +{ + CoFreeUnusedLibraries(); // JIRA 221: GME 9.12.15 Crashing + // Unload ConstraintManager.dll, GME crashes if the system unloads it by itself + + Gdiplus::GdiplusStartupInput gdiplusStartupInput; + Gdiplus::GdiplusStartupOutput gdiplusStartupOutput; + ULONG_PTR gdiplusToken; + ULONG_PTR gdiplusHookToken; + + // Tihamer: Initializing GDI+ + // See "Special CWinApp Services" MSDN topic http://msdn.microsoft.com/en-us/library/001tckck.aspx + gdiplusStartupInput.SuppressBackgroundThread = TRUE; + VERIFY(Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, &gdiplusStartupOutput) == Gdiplus::Ok); + gdiplusStartupOutput.NotificationHook(&gdiplusHookToken); + graphics.Initialize(); + + + // KMS: set up CrashRpt info + CR_INSTALL_INFO info; + memset(&info, 0, sizeof(CR_INSTALL_INFO)); + info.cb = sizeof(CR_INSTALL_INFO); + info.pszAppName = _T("GME"); + info.pszAppVersion = _T(GME_VERSION_ID); + info.pszEmailSubject = _T("GME CrashRpt"); + info.uPriorities[CR_SMTP] = CR_NEGATIVE_PRIORITY; + info.uPriorities[CR_SMAPI] = CR_NEGATIVE_PRIORITY; + info.pszUrl = _T("https://gme-crashrpt.metamorphsoftware.com/crashrpt"); + info.dwFlags = CR_INST_SEH_EXCEPTION_HANDLER | CR_INST_PURE_CALL_HANDLER | CR_INST_SECURITY_ERROR_HANDLER + | CR_INST_INVALID_PARAMETER_HANDLER | CR_INST_SIGABRT_HANDLER | CR_INST_SIGINT_HANDLER | CR_INST_SIGTERM_HANDLER; + // missing: CR_INST_NEW_OPERATOR_ERROR_HANDLER: the default std::bad_alloc is fine (sometimes we handle it) +#ifdef _DEBUG + bNoProtect = true; +#endif + auto disableCrashRpt = []() -> bool { + // reg add HKCU\Software\GME /v InstallCrashRpt /d 0 /t REG_SZ /f + if (getUserRegistryStringValue(L"InstallCrashRpt") == L"0") { + return true; + } + return false; + }; + bNoProtect = bNoProtect || disableCrashRpt(); + bNoProtect = bNoProtect || static_cast(IsDebuggerPresent()); + if (!bNoProtect) { + if (crInstall(&info) != 0) + { + TCHAR buff[1024]; + crGetLastErrorMsg(buff, 1024); + AfxMessageBox(buff); + return FALSE; + } + HookInvalidArg(); + } + + OpenCommandLineProject(); + + int retVal = 0; + if (bNoProtect) { + retVal = CWinAppEx::Run(); + } else { + __try { + retVal = CWinAppEx::Run(); + } + __except(crExceptionFilter(GetExceptionCode(), GetExceptionInformation())) { + EmergencySave(); + + // KMS: As our state may be corrupted, TerminateProcess so we don't run any atexits and crash again + TerminateProcess(GetCurrentProcess(), GetExceptionCode()); + } + } + // KMS: need to unload decorators before closing GDI+: e.g. ~Facilities() does GDI+ ops + CoFreeUnusedLibraries(); + // Closing GDI+ + graphics.Uninitialize(); + gdiplusStartupOutput.NotificationUnhook(gdiplusHookToken); + Gdiplus::GdiplusShutdown(gdiplusToken); + + return retVal; +} + +///////////////////////////////////////////////////////////////////////////// +// CGMEApp Autosave +void CGMEApp::Autosave() +{ + + if(mgaProject == NULL || (0&&!proj_type_is_mga) || (!autosaveEnabled)) { + // The KillTimer function does not remove WM_TIMER messages + // already posted to the message queue ... + CGMEEventLogger::LogGMEEvent(_T("WARNING: CGMEApp::Autosave was called with no active project or autosave disabled.\r\n")); + return; + } + + // Figure out the filename + CString conn; + if (autosaveUseDir) { + int p = currentConnection.ReverseFind('\\'); + CString fname = currentConnection.Mid(p + 1); + + conn = CString(_T("MGA=")) + autosaveDir + CString(_T("\\")) + fname + GME_AUTOSAVE_EXTENSION; + } + else { + conn = currentConnection + GME_AUTOSAVE_EXTENSION; + } + + // autosave in case of xmlbackend means saving into the sourcecontrol + if( proj_type_is_xmlbackend) + conn = currentConnection; + + // Check if in transaction + bool inTrans; + try { + long status; + COMTHROW(mgaProject->get_ProjectStatus(&status)); + inTrans = (status & 0x08L) != 0; + } + catch(hresult_exception &) { + // Safe presumption + inTrans = true; + } + + if (inTrans) { + CGMEEventLogger::LogGMEEvent(_T("WARNING: CGMEApp::Autosave failed ") + + conn + _T(". We are in transaction.\r\n")); + return; + } + + // Save the project + try { + COMTHROW(mgaProject->Save(CComBSTR(conn), VARIANT_TRUE)); + CGMEEventLogger::LogGMEEvent(_T("CGMEApp::Autosave succeeded ") + + conn + _T("\r\n")); + } + catch(hresult_exception &e) { + CGMEEventLogger::LogGMEEvent(_T("WARNING: CGMEApp::Autosave failed ") + + conn + _T(" ") + e.what() + _T("\r\n")); + } +} + + +///////////////////////////////////////////////////////////////////////////// +// CGMEApp MGA project management + + +void CGMEApp::CloseProject(bool updateStatusBar, bool force_abort) +{ + + CWaitCursor wait; + + if(CGMEDataSource::myData) // it is true when object copied to the clipboard from the view + OleFlushClipboard(); + + if( CMainFrame::theInstance != NULL ) { + CMainFrame::theInstance->StopAutosaveTimer(); + CMainFrame::theInstance->SetPartBrowserMetaModel(NULL); + CMainFrame::theInstance->SetPartBrowserBg(::GetSysColor(COLOR_APPWORKSPACE)); + } + + if( CGMEBrowser::theInstance != NULL ) + CGMEBrowser::theInstance->CloseProject(); + + if(CGMEObjectInspector::theInstance!=NULL) + CGMEObjectInspector::theInstance->CloseProject(); + + if(CGMESearch::theInstance!=NULL) + CGMESearch::theInstance->CloseProject(); + + if (CGMEPartBrowser::theInstance) + CGMEPartBrowser::theInstance->SetProject(CComPtr(0)); + + + + if( guiMetaProject != NULL ) + { + delete guiMetaProject; + guiMetaProject = NULL; + } + + mgaMetaProject = NULL; + UpdateComponentLists(); + + if( mgaProject != NULL ) { + mgaClient = NULL; + if(mgaProject->Close((abort_on_close || force_abort) ? VARIANT_TRUE : VARIANT_FALSE) != S_OK) { + AfxMessageBox(CString(_T("Error occurred ")) + ((abort_on_close || force_abort) ? _T("aborting") : _T("closing")) + _T(" the project")); + } + mgaProject.Release(); + } + + + if(updateStatusBar) { + CMainFrame::theInstance->WriteStatusParadigm(_T("-")); + CMainFrame::theInstance->WriteStatusMode(_T("EDIT")); + CMainFrame::theInstance->WriteStatusZoom(100); + } + projectName.Empty(); + ChangedProjectConnStrings(); + + if(CGMEDoc::theInstance) + CGMEDoc::theInstance->SetTitle(_T("")); + if(CMainFrame::theInstance) { + CMainFrame::theInstance->SetTitle(m_pszAppName); + CMainFrame::theInstance->UpdateTitle(0);//WAS: "" .By passing 0 instead of "" we won't get title such as "GME-" after a project was closed + } +} + + +void CGMEApp::ChangedProjectConnStrings() { + if(!mgaProject) { // project closed + paradigmDir.Empty(); + projectDir.Empty(); + proj_type_is_mga = false; + proj_type_is_xmlbackend = false; + return; + } + CString conn, metaconn; + CComBstrObj cc; + conn = cc; + COMTHROW(mgaProject->get_ProjectConnStr(PutOut(cc))); + conn = cc; + cc.Empty(); + COMTHROW(mgaProject->get_ParadigmConnStr(PutOut(cc))); + metaconn = cc; + if(!conn.IsEmpty()) { + TCHAR cd[200]; + GetCurrentDirectory(200, cd); + projectDir = cd; + if (conn.Find(_T("MGA=")) == 0) { + proj_type_is_mga = true; + int epos = conn.ReverseFind('\\'); + if(epos >= 4) { + projectDir = conn.Mid(4, epos-4); + if(projectDir.IsEmpty()) projectDir= '\\'; + SetCurrentDirectory(projectDir); + } + } + else proj_type_is_mga = false; + + if( conn.Find(_T("MGX=")) == 0 ) + proj_type_is_xmlbackend = true; + else + proj_type_is_xmlbackend = false; + } + if(!metaconn.IsEmpty()) { + if (metaconn.Find(_T("MGA=")) == 0) { + int epos = metaconn.ReverseFind('\\'); + if(epos >= 4) { + paradigmDir = metaconn.Mid(4, epos-4); + if(paradigmDir.IsEmpty()) paradigmDir= '\\'; + } + } + } +} + + +// throws exceptions!! +void CGMEApp::UpdateProjectName(bool retrievePath) { + if( mgaProject == NULL ) { + projectName.Empty(); + } + else { + + + CComObjPtr terry; + COMTHROW(mgaProject->CreateTerritory(NULL, PutOut(terry), NULL) ); + CComBSTR nm; + + MSGTRY + { + COMTHROW(mgaProject->BeginTransaction(terry,TRANSACTION_READ_ONLY)); + COMTHROW(mgaProject->get_Name(&nm)); + COMTHROW(mgaProject->CommitTransaction()); + } + MSGCATCH(_T("Error getting project name"), mgaProject->AbortTransaction()) + + CopyTo(nm,projectName); + } + + if(CGMEDoc::theInstance) + CGMEDoc::theInstance->SetTitle(projectName); + UpdateMainFrameTitle(projectName, retrievePath); +} + +void CGMEApp::UpdateMainFrameTitle(const CString& projName, bool retrievePath) +{ + CString projectName = projName; + + if (retrievePath) { + CDocument* pDocument = CGMEDoc::theInstance; + if (pDocument) { + POSITION pos = pDocument->GetFirstViewPosition(); + while (pos != NULL) { +#if !defined(ACTIVEXGMEVIEW) + CGMEView* pView = (CGMEView*) pDocument->GetNextView(pos); + ASSERT(pView); + pView->RetrievePath(); + pView->SetTitles(); + } +#endif + } + } + CMDIChildWnd* pChild = CMainFrame::theInstance->MDIGetActive(); + if (pChild && pChild->IsKindOf(RUNTIME_CLASS(CChildFrame))) { +#if !defined (ACTIVEXGMEVIEW) + if (retrievePath) { + CGMEView* view = (CGMEView*)pChild->GetActiveView(); + if (view) { + view->RetrievePath(); + view->SetTitles(); + } + } +#endif + CChildFrame* childFrame = STATIC_DOWNCAST(CChildFrame, pChild); + projectName = childFrame->GetTitle() + _T(" - ") + childFrame->GetAppTitle(); + } + if (mgaProject && isMgaProj()) { + CString filename, dirname; + getMgaPaths(filename, dirname); + projectName = projectName + L" (" + filename + L")"; + } + CMainFrame::theInstance->UpdateTitle(projectName); +} + +void CGMEApp::FindConstraintManager() +{ + CComPtr comps; + COMTHROW( mgaProject->get_AddOnComponents(&comps)); + MGACOLL_ITERATE(IMgaComponent, comps) { + CComBSTR name; + COMTHROW(MGACOLL_ITER->get_ComponentName(&name)); + if(name == _T("ConstraintManager")) { + mgaConstMgr = CComQIPtr(MGACOLL_ITER); + COMTHROW(mgaConstMgr->put_InteractiveMode(VARIANT_TRUE)); + break; + } + } MGACOLL_ITERATE_END; +} + + +void CGMEApp::UpdateComponentToolbar() +{ + if (!CMainFrame::theInstance) + return; + CComponentBar &componentBar = CMainFrame::theInstance->m_wndComponentBar; + componentBar.ShowWindow(SW_HIDE); + CMainFrame::theInstance->ShowPane(&componentBar, FALSE, FALSE, FALSE); + + // Removing the add-in and plug-in buttons + const CObList &componentButtons = componentBar.GetAllButtons(); + for(POSITION pos = componentButtons.GetHeadPosition(); pos!= NULL; ) + { + const CMFCToolBarButton* pCurrent = (const CMFCToolBarButton*) componentButtons.GetNext(pos); + if(pCurrent->m_bUserButton == TRUE) + { + // FIXME: this doesn't work, so we leak all the icons. Maybe we could m_userImages.UpdateImage instead? + // VERIFY(m_userImages.DeleteImage(pCurrent->GetImage())); + int buttonIndex = componentBar.ButtonToIndex(pCurrent); + componentBar.RemoveButton(buttonIndex); + } + } + + componentBar.AdjustLayout(); // CMFCToolBar::AdjustLayout + componentBar.AdjustSizeImmediate(TRUE); + componentBar.RecalcLayout(); // CPane::RecalcLayout + + if (!mgaMetaProject) + { + return; + } + + // Updating the Component toolbar + CComPtr registrar; + if(registrar.CoCreateInstance(L"Mga.MgaRegistrar") != S_OK) return; + + + // Traversing the plugins and interpreters + int plugins_size = min((int)plugins.GetSize(), ID_FILE_RUNPLUGIN_LAST - ID_FILE_RUNPLUGIN1); + int interpreters_size = min((int)interpreters.GetSize(), ID_FILE_INTERPRET_LAST - ID_FILE_INTERPRET1); + for(int i = 0; i < plugins_size + interpreters_size; ++i) + { + // Querying component name + CComBSTR componentName; + if(i < plugins_size) // if it is a plugin + { + componentName = plugins[i]; + } + else // if it is an interpreter + { + componentName = interpreters[i-plugins_size]; + } + + // Obtaining ToolTip + HRESULT errCode; + CString toolTip; + errCode = registrar->get_ComponentExtraInfo(REGACCESS_PRIORITY, componentName, CComBSTR(L"Tooltip"), PutOut(toolTip)); + if(errCode != S_OK || toolTip.IsEmpty()) + { + toolTip = componentName; + } + if(i < plugins_size) + { + pluginTooltips.Add(toolTip); + } + else + { + interpreterTooltips.Add(toolTip); + } + + // Querying icon information + CString iconInfo; + errCode = registrar->get_ComponentExtraInfo(REGACCESS_PRIORITY, componentName, CComBSTR(L"Icon"), PutOut(iconInfo)); + if(errCode != S_OK || iconInfo.IsEmpty()) + { + continue; + } + + // Loading icon + HICON hIcon = NULL; //, hictofree = NULL; + int commaPos; + HMODULE hModule = NULL; + if((commaPos = iconInfo.Find(',')) >= 0) //Format: , + { + if(commaPos) // module name present; + { + // XP doesn't support LOAD_LIBRARY_AS_IMAGE_RESOURCE + hModule = LoadLibraryEx(iconInfo.Left(commaPos), NULL, LOAD_LIBRARY_AS_DATAFILE); + } + else // No module name provided, + { + _bstr_t modulePath; + registrar->get_LocalDllPath(componentName, modulePath.GetAddress()); + if(modulePath.length() != 0) + { + // XP doesn't support LOAD_LIBRARY_AS_IMAGE_RESOURCE + hModule = LoadLibraryEx(modulePath, NULL, LOAD_LIBRARY_AS_DATAFILE); + } + } + } + + int cx = m_userImages.GetImageSize().cx; + int cy = m_userImages.GetImageSize().cy; + + if( hModule != NULL ) + { + hIcon = (HICON)::LoadImage(hModule, iconInfo.Mid(commaPos+1), IMAGE_ICON, cx, cy, LR_DEFAULTCOLOR); + } + else + { + // simple .ico file with path + hIcon =(HICON)LoadImage(NULL, iconInfo, IMAGE_ICON, cx, cy, LR_LOADFROMFILE); + } + + // If icon is not found either in the DLL or a standalone file + if(!hIcon) + { + // Displaying component not found icon: red X + hIcon = (HICON)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_COMPNOTFOUND), IMAGE_ICON, 16,16, LR_DEFAULTCOLOR); + } + + //Adding button icon + int nIndex = m_userImages.AddIcon(hIcon); + ASSERT(nIndex >= 0); + BOOL succ = CMFCToolBar::SetUserImages(&m_userImages); + ASSERT(succ == TRUE); + + // Adding button + UINT commandID = (i < plugins_size) ? ID_FILE_RUNPLUGIN1 + i : ID_FILE_INTERPRET1 + i - plugins_size; + CMFCToolBarButton toolBarButton(commandID, nIndex, componentName + '\n' + toolTip, TRUE); + + VERIFY(componentBar.InsertButton(toolBarButton) != -1); + if (hModule) + FreeLibrary(hModule); + } + if (plugins_size + interpreters_size != 0) { + componentBar.AdjustLayout(); // CMFCToolBar::AdjustLayout + componentBar.AdjustSizeImmediate(TRUE); + componentBar.RecalcLayout(); // CPane::RecalcLayout + CMainFrame::theInstance->ShowPane(&componentBar, TRUE, FALSE, FALSE); + componentBar.ShowWindow(SW_SHOW); + } +} + + +void CGMEApp::UpdateComponentLists(bool restart_addons) +{ + ClearDisabledComps(); + plugins.RemoveAll(); + pluginTooltips.RemoveAll(); + interpreters.RemoveAll(); + interpreterTooltips.RemoveAll(); + CStringArray tempaddons; tempaddons.Copy(addons); + addons.RemoveAll(); + mgaConstMgr = NULL; + if(mgaMetaProject) { + CComBSTR b; + COMTHROW(mgaMetaProject->get_Name(&b)); + CComPtr reg; + COMTHROW(reg.CoCreateInstance(CComBSTR(L"Mga.MgaRegistrar"))); + { + CComVariant v; + COMTHROW(reg->get_AssociatedComponents(b, COMPONENTTYPE_PLUGIN, REGACCESS_BOTH, &v)); + CopyTo(v, plugins); + } + { + CComVariant v; + COMTHROW(reg->get_AssociatedComponents(b, COMPONENTTYPE_INTERPRETER, REGACCESS_BOTH, &v)); + CopyTo(v, interpreters); + } + { + CComVariant v; + COMTHROW(reg->get_AssociatedComponents(b, COMPONENTTYPE_ADDON, REGACCESS_BOTH, &v)); + + CopyTo(v, addons); + if(restart_addons) { + bool redo = false; + if(tempaddons.GetSize() != addons.GetSize()) redo = true; + else { + for(int j = 0 ; j < tempaddons.GetSize(); j++) { + if(addons[j].Compare(tempaddons[j])) { + redo = true; + break; + } + } + } + if(redo && AfxMessageBox(_T("AddOn configuration has changed.\nRestart addons?"), MB_YESNO) == IDYES) { + COMTHROW(mgaProject->EnableAutoAddOns(VARIANT_FALSE)); + COMTHROW(mgaProject->EnableAutoAddOns(VARIANT_TRUE)); + } + } + } + + this->addonOnlineHelp.RemoveAll(); this->addonOfflineHelp.RemoveAll(); + this->pluginOnlineHelp.RemoveAll(); this->pluginOfflineHelp.RemoveAll(); + this->interpreterOnlineHelp.RemoveAll(); this->interpreterOfflineHelp.RemoveAll(); + for (INT i = 0; i < this->plugins.GetSize() + this->interpreters.GetSize() + this->addons.GetSize(); ++i) { + HRESULT errCode; + CString onlineHelp; + CString offlineHelp; + CComBSTR componentName = + (i < plugins.GetSize() + ? plugins[i] + : (i < plugins.GetSize() + interpreters.GetSize() + ? interpreters[i - plugins.GetSize()] + : addons[i - plugins.GetSize() - interpreters.GetSize()])); + + errCode = reg->get_ComponentExtraInfo(REGACCESS_PRIORITY, componentName, CComBSTR(L"OnlineHelp"), PutOut(onlineHelp)); + if (errCode != S_OK || onlineHelp.IsEmpty()) + { + onlineHelp = L""; + } + errCode = reg->get_ComponentExtraInfo(REGACCESS_PRIORITY, componentName, CComBSTR(L"OfflineHelp"), PutOut(offlineHelp)); + if (errCode != S_OK || offlineHelp.IsEmpty()) + { + offlineHelp = L""; + } + if (i < this->plugins.GetSize()) + { + this->pluginOnlineHelp.Add(onlineHelp); + this->pluginOfflineHelp.Add(offlineHelp); + } + else if (i < this->plugins.GetSize() + this->interpreters.GetSize()) + { + this->interpreterOnlineHelp.Add(onlineHelp); + this->interpreterOfflineHelp.Add(offlineHelp); + } + else + { + this->addonOnlineHelp.Add(onlineHelp); + this->addonOfflineHelp.Add(offlineHelp); + } + } + + // access constraint mgr + FindConstraintManager(); + + } + dynmenus_need_refresh = true; + UpdateComponentToolbar(); +} + +void CGMEApp::UpdateDynMenus(CMenu *toolmenu) +{ + CString runPluginLabel = _T("R&un Plug-In"); + CString runInterpreterLabel = _T("Run In&terpreter"); + CString helpParadigmLabel = _T("&Paradigm Help"); + CString helpComponentLabel = _T("C&omponent Help"); + CString label; + // [ Begin workaround + // If you just go left to the Window menu next to the Tools menu, and back to the Tools menu (so not even abandoming the menubar) + // the original menu (without added intepreters and plugins) is switched back. + // To workaround this we check always if the original plugin and interpreter placeholder menus are present, + // because if they are present we have to populate the interpreters plugins again. + // Step 1: Get tools menu if we got NULL menu + if (toolmenu == NULL) { + CMenu* mainMenu = CMainFrame::theInstance->GetMenu(); + if (mainMenu == NULL || mainMenu->m_hMenu == NULL) { + HMENU mainHMenu = CMainFrame::theInstance->GetMenuBar()->GetHMenu(); + mainMenu = CMenu::FromHandle(mainHMenu); + } + ASSERT(mainMenu); + for(UINT idxa = 0; idxa < mainMenu->GetMenuItemCount(); idxa++) { + CString labela; + mainMenu->GetMenuString(idxa, labela, MF_BYPOSITION); + if (!labela.CompareNoCase(_T("&Tools"))) { + toolmenu = mainMenu->GetSubMenu(idxa); + break; + } + } + } + // Step 2: Check if placeholder menus are present -> we switch trigger in that case + if (toolmenu != NULL) { + for(UINT idx = 0; idx < toolmenu->GetMenuItemCount(); idx++) { + toolmenu->GetMenuString(idx, label, MF_BYPOSITION); + UINT menuID = toolmenu->GetMenuItemID(idx); + if (menuID == ID_TOOLS_RUNPLUG || menuID == ID_FILE_RUNINTERPRETER || menuID == ID_HELP_COMPONENTHELP || menuID == ID_HELP_PARADIGMHELP) { + dynmenus_need_refresh = true; + break; + } + } + } + // End workaround ] + if (!dynmenus_need_refresh) + return; + ASSERT(toolmenu); + bool found = false; + for(UINT idx = 0; idx < toolmenu->GetMenuItemCount(); idx++) { + toolmenu->GetMenuString(idx, label, MF_BYPOSITION); + UINT menuID = toolmenu->GetMenuItemID(idx); + if (!label.CompareNoCase(runPluginLabel) || + menuID == ID_TOOLS_RUNPLUG || menuID == ID_FILE_RUNPLUGIN1) + { + if (dynmenus_need_refresh) { + toolmenu->DeleteMenu(idx, MF_BYPOSITION); + if (plugins.GetSize() == 1) { + toolmenu->InsertMenu(idx, MF_BYPOSITION | MF_ENABLED, + ID_FILE_RUNPLUGIN1, pluginTooltips[0]); + } + else { + CMenu pluginmenu; + pluginmenu.CreatePopupMenu(); + for(int i = 0; i < min(plugins.GetSize(), ID_FILE_RUNPLUGIN_LAST - ID_FILE_RUNPLUGIN1); ++i) { + pluginmenu.AppendMenu(MF_ENABLED, ID_FILE_RUNPLUGIN1 + i, pluginTooltips[i]); + } + toolmenu->InsertMenu(idx, + plugins.GetSize() ? MF_BYPOSITION | MF_POPUP | MF_ENABLED : MF_BYPOSITION | MF_POPUP | MF_GRAYED, + (UINT_PTR)pluginmenu.Detach(), runPluginLabel); + } + found = true; + } + } + else if (!label.CompareNoCase(runInterpreterLabel) || + menuID == ID_FILE_RUNINTERPRETER || menuID == ID_FILE_INTERPRET1) + { + if (dynmenus_need_refresh) { + toolmenu->DeleteMenu(idx, MF_BYPOSITION); + if (interpreters.GetSize() == 1) { + toolmenu->InsertMenu(idx, MF_BYPOSITION | MF_ENABLED, + ID_FILE_INTERPRET1, interpreterTooltips[0]); + } + else { + CMenu pluginmenu; + pluginmenu.CreatePopupMenu(); + + struct TooltipSorter { + CString tooltip; + int id; + bool operator<(const TooltipSorter& that) { + return this->tooltip < that.tooltip; + } + }; + std::vector interpreters_sorted; + + for (int i = 0; i < min(interpreters.GetSize(), ID_FILE_INTERPRET_LAST - ID_FILE_INTERPRET1); ++i) { + TooltipSorter tt = { interpreterTooltips[i], ID_FILE_INTERPRET1 + i }; + interpreters_sorted.push_back(std::move(tt)); + } + std::sort(begin(interpreters_sorted), end(interpreters_sorted)); + std::for_each(begin(interpreters_sorted), end(interpreters_sorted), [&](const TooltipSorter& tt) + { + pluginmenu.AppendMenu(MF_ENABLED, tt.id, tt.tooltip); + }); + toolmenu->InsertMenu(idx, + interpreters.GetSize() ? MF_BYPOSITION | MF_POPUP | MF_ENABLED : MF_BYPOSITION | MF_POPUP | MF_GRAYED, + (UINT_PTR)pluginmenu.Detach(), runInterpreterLabel); + } + found = true; + } + } + else if (!label.CompareNoCase(helpComponentLabel) || + menuID == ID_HELP_COMPONENTHELP || menuID == ID_HELP_COMPONENTHELP_FIRST) + { + if (dynmenus_need_refresh) { + toolmenu->DeleteMenu(idx, MF_BYPOSITION); + CMenu helpComponent; + helpComponent.CreatePopupMenu(); + for (int i = 0; i < min(plugins.GetSize() + interpreters.GetSize() + addons.GetSize(), ID_HELP_COMPONENTHELP_LAST - ID_HELP_COMPONENTHELP_FIRST);) { + int index = i / 2; + CString componentName = (index < plugins.GetSize() ? + pluginTooltips[index] : (index < plugins.GetSize() + interpreters.GetSize() ? + interpreterTooltips[index - plugins.GetSize()] : addons[index - plugins.GetSize() - interpreters.GetSize()])); + CString onlineHelpLocation = (index < plugins.GetSize() ? + pluginOnlineHelp[index] : (index < plugins.GetSize() + interpreters.GetSize() ? + interpreterOnlineHelp[index - plugins.GetSize()] : addonOnlineHelp[index - plugins.GetSize() - interpreters.GetSize()])); + CString offlineHelpLocation = (index < plugins.GetSize() ? + pluginOfflineHelp[index] : (index < plugins.GetSize() + interpreters.GetSize() ? + interpreterOfflineHelp[index - plugins.GetSize()] : addonOfflineHelp[index - plugins.GetSize() - interpreters.GetSize()])); + + CMenu help; + help.CreatePopupMenu(); + if (!onlineHelpLocation.IsEmpty()) + { + help.AppendMenu(MF_ENABLED, ID_HELP_COMPONENTHELP_FIRST + i++, L"Online Help"); + } + else + { + ++i; + } + + if (!offlineHelpLocation.IsEmpty()) + { + help.AppendMenu(MF_ENABLED, ID_HELP_COMPONENTHELP_FIRST + i++, L"Offline Help"); + } + else + { + ++i; + } + + if (help.GetMenuItemCount() != 0) + { + helpComponent.InsertMenu(index, MF_BYPOSITION | MF_POPUP | MF_ENABLED, (UINT_PTR)help.Detach(), componentName); + } + } + toolmenu->InsertMenu(idx, + helpComponent.GetMenuItemCount() ? MF_BYPOSITION | MF_POPUP | MF_ENABLED : MF_BYPOSITION | MF_POPUP | MF_GRAYED, + (UINT_PTR)helpComponent.Detach(), helpComponentLabel); + found = true; + } + } + else if (!label.CompareNoCase(helpParadigmLabel) || + menuID == ID_HELP_PARADIGMHELP || menuID == ID_HELP_PARADIGMHELP_FIRST) + { + if (dynmenus_need_refresh && mgaProject) { + toolmenu->DeleteMenu(idx, MF_BYPOSITION); + CComBSTR pname = guiMetaProject->name; + CComBSTR pguidstr = guiMetaProject->guid; + + CMenu help; + help.CreatePopupMenu(); + CComPtr reg; + HRESULT hr = reg.CoCreateInstance(CComBSTR(L"Mga.MgaRegistrar")); + if (SUCCEEDED(hr)) + { + reg->GetParadigmExtraInfoDisp(pname, pguidstr, CComBSTR(L"OnlineHelp"), PutOut(this->paradigmOnlineHelp)); + reg->GetParadigmExtraInfoDisp(pname, pguidstr, CComBSTR(L"OfflineHelp"), PutOut(this->paradigmOfflineHelp)); + } + + if (!this->paradigmOnlineHelp.IsEmpty()) + { + help.AppendMenu(MF_ENABLED, ID_HELP_PARADIGMHELP_FIRST, L"Online Help"); + } + if (!this->paradigmOfflineHelp.IsEmpty()) + { + help.AppendMenu(MF_ENABLED, ID_HELP_PARADIGMHELP_LAST, L"Offline Help"); + } + toolmenu->InsertMenu(idx, + help.GetMenuItemCount() != 0 ? MF_BYPOSITION | MF_POPUP | MF_ENABLED : MF_BYPOSITION | MF_POPUP | MF_GRAYED, + (UINT_PTR)help.Detach(), pname); + found = true; + } + } + } + if (found) + dynmenus_need_refresh = false; +} + +// throws exceptions!! +void CGMEApp::AfterOpenOrCreateProject(const CString &conn) +{ + UpdateProjectName(); + if( mgaProject != NULL ) { + abort_on_close = false; +// get meta + COMTHROW( mgaProject->get_RootMeta(&mgaMetaProject) ); + UpdateComponentLists(); + +// create guimetaproject + ASSERT( guiMetaProject == NULL ); + guiMetaProject = new CGuiMetaProject(mgaMetaProject); + CMainFrame::theInstance->WriteStatusParadigm(guiMetaProject->displayedName); + CMainFrame::theInstance->SetTitle(guiMetaProject->displayedName); + UpdateProjectName(); + +// Register OLE Server / MGA Client + CGMEOLEApp *oleApp = ((CMainFrame*)m_pMainWnd)->mGmeOleApp; + CComBSTR clientName(OLESTR("GME.Application")); + COMTHROW(mgaProject->RegisterClient(clientName, oleApp->GetIDispatch(FALSE), &mgaClient)); // mgaClient increments the refcount of oleApp->idispatch by 1 + + ((CMainFrame*)m_pMainWnd)->setMgaProj(); + +// notify object inspector + ASSERT(CGMEObjectInspector::theInstance!=NULL); + CGMEObjectInspector::theInstance->SetProject(mgaProject); + +// notify Part Browser + ASSERT(CGMEPartBrowser::theInstance!=NULL); + CGMEPartBrowser::theInstance->SetProject(mgaProject); + +// by swapping the order of SetProject (first ObjectInspector, then Browser), +// the user will see the properties of the initally selected project at once +// notify browser + ASSERT( CGMEBrowser::theInstance != NULL ); + CGMEBrowser::theInstance->SetProject(mgaProject); + +// notify search control + ASSERT(CGMESearch::theInstance!=NULL); + CGMESearch::theInstance->SetProject(mgaProject); + + +// change dir + ChangedProjectConnStrings(); +// record connection name + currentConnection = conn; + m_RecentProjectList.AddAndWriteList(conn); + if (!CGMEDoc::theInstance) { + CWinAppEx::OnFileNew(); + } +// start autosave + if (autosaveEnabled) { + CMainFrame::theInstance->StartAutosaveTimer(autosaveFreq); + } + } +} + + +static int guidcmp(VARIANT &qGUID, VARIANT &pGUID) { + GUID g1, g2; + CopyTo(qGUID, g1); + CopyTo(pGUID, g2); + return memcmp(&g1, &g2, sizeof(g1)); +} + +static int versioncmp(CComBSTR &qVer, CComBSTR &pVer) { + CString q(qVer); + CString p(pVer); + + if ((!p.IsEmpty()) && (!q.IsEmpty())) { + return p.Compare(q); + } + return 1; +} + + +bool DiagnoseParadigm(CString metaname, bool syscheck = false) { + CComPtr reg; + try { + HRESULT hr = reg.CoCreateInstance(CComBSTR(L"Mga.MgaRegistrar")); + if(hr != S_OK) { + throw CString(_T("Cannot create the registrar component\n") + _T("We recommend you to reinstall GME")); + } + CComBSTR conn; + CComVariant guid; + hr = reg->QueryParadigm(CComBSTR(metaname), &conn, &guid, + syscheck ? REGACCESS_SYSTEM : REGACCESS_PRIORITY); + if(hr != S_OK) { + throw CString(_T("Cannot access registry info for paradigm ") + metaname + + _T("\nWe recommend you remove and re-register the paradigm")); + } + CComObjPtr paradigm; + hr = paradigm.CoCreateInstance(OLESTR("MGA.MgaMetaProject")); + if(hr != S_OK) { + throw CString(_T("Cannot create the meta component\n") + _T("We recommend you reinstall GME")); + } + + hr = paradigm->Open(conn); + + if(hr != S_OK) { + throw CString(_T("Cannot open the paradigm ") + metaname + _T("\n") + _T("Probable cause is file non-existence,\n") + _T("insufficient access, or format error\n") + _T("Connection string: ") + CString(conn)); + } + + + CComBSTR parname; + CComVariant gguid; + hr = paradigm->get_Name(&parname); + if(hr == S_OK) paradigm->get_GUID(&gguid); + hr |= paradigm->Close(); + + if(hr != S_OK) { + throw CString(_T("Cannot read the paradigm ") + metaname + _T("\n") + _T("Probable cause is file format error\n") + _T("Connection string: ") + CString(conn)); + } + if(!( parname == CComBSTR( (LPCTSTR) metaname))) { + throw CString(_T("The paradigm opened '") + CString(parname) + _T("'\n") + _T("differs from the requested paradigm '")+ metaname + _T("'\n") + _T("We recommend you unregister '") + metaname + _T("'\n") + _T("Connection string: ") + CString(conn)); + + } + + CComBstrObj parg1, parg2; + GUID g; + CopyTo(gguid, g); + CopyTo(g, parg1); + CopyTo(guid, g); + CopyTo(g, parg2); + if(parg1 != parg2) { + throw CString(_T("The GUID in paradigm '") + CString(parname) + _T("'\n") + _T("{") + CString(parg1) + _T("}\n") + _T("differs from the requested GUID for '")+ metaname + _T("'\n") + _T("{") + CString(parg2) + _T("}\n") + _T("We recommend you unregister '") + metaname + _T("'\n") + _T("Connection string: ") + CString(conn)); + } + } catch( CString &c) { + if(!syscheck) { + AfxMessageBox(c); + CComBSTR cc; CComVariant gg; + if(reg && E_NOTFOUND != reg->QueryParadigm(CComBSTR(metaname), &cc, &gg, REGACCESS_SYSTEM)) { + if(DiagnoseParadigm(metaname, true)) { + AfxMessageBox(_T("SYSTEM registry for '") + metaname + _T("' is correct\n") + _T("We recommend you remove the USER registration for ") + metaname); + } + else { + AfxMessageBox(_T("SYSTEM registry for '") + metaname + _T("' is also incorrect\n") + _T("We recommend you reinstall the paradigm.")); + } + } + } + return false; + } + catch(...) { + return false; + } + return true; +} + + + +void CGMEApp::OpenProject(const CString &conn) { + + MSGTRY + { + if (conn.Left(4) == _T("XML=")) { + CString fullPath = conn.Right(conn.GetLength() - 4); + TCHAR buffer[MAX_PATH]; + TCHAR* filepart = NULL; + GetFullPathName(fullPath, MAX_PATH, buffer, &filepart); + if (filepart == NULL) { + COMTHROW(E_FILEOPEN); + } + CString filename = filepart; + CString title = filename.Left(filename.ReverseFind('.')); + Importxml(fullPath, filepart, title); + return; + } + + CWaitCursor wait; + + ASSERT( mgaProject == 0 ); + COMTHROW( mgaProject.CoCreateInstance(OLESTR("Mga.MgaProject")) ); + + VARIANT_BOOL enableAutoAddOns = VARIANT_TRUE; + VARIANT_BOOL readable_only; + + COMTHROW( mgaProject->EnableAutoAddOns(VARIANT_TRUE)); + HRESULT hr = mgaProject->Open(PutInBstr(conn), &readable_only); + if(hr != S_OK) { + _bstr_t mgaProjectOpenError; + GetErrorInfo(mgaProjectOpenError.GetAddress()); + CComBSTR parn; + CComBSTR parv; + long version; + CComVariant parg; + VARIANT_BOOL ro_mode; + if( conn.Left(5) == _T("MGX=\"")) + { + if( E_FILEOPEN == hr) { + consoleMessage( _T("Could not open project!"), MSG_ERROR); + } + else if( E_MGA_PARADIGM_INVALID == hr) { + consoleMessage( _T("Project could not access its original version of paradigm!"), MSG_ERROR); + } + else if( E_MGA_PARADIGM_NOTREG == hr) { + consoleMessage( _T("Project could not access its paradigm!"), MSG_ERROR); + } + else if( E_MGA_META_INCOMPATIBILITY == hr) { + consoleMessage( _T("Versioned project is not compatible with the registered paradigm!"), MSG_ERROR); + } + else if( E_UNKNOWN_STORAGE == hr) { + // no additional comment in this case + } + else { + consoleMessage( _T("Could not open project (unknown error)!"), MSG_ERROR); + } + CloseProject(); + return; // ensures no more exception handlers or explanatory messages (or QueryProjectInfo calls) + } + + COMTHROW(mgaProject->QueryProjectInfo(PutInBstr(conn), &version, &parn, &parv, &parg, &ro_mode)); + while (true) { + CString msg; + CComVariant guidpar; + CString newparname; + bool tryit = false; + + if(hr == E_MGA_MODULE_INCOMPATIBILITY) { + msg = _T("WARNING: The project data is not in the current MGA format\n") + _T("Do you want to upgrade it?"); + if (AfxMessageBox(msg ,MB_OKCANCEL) == IDOK) { + tryit = true; + } + } + if(hr == E_MGA_PARADIGM_INVALID) { + msg = _T("WARNING: Project could not access its original version of\n") + _T("paradigm '") + CString(parn) + _T("'\n"); + if (mgaProjectOpenError.length()) + msg += static_cast(mgaProjectOpenError); + msg += _T("Do you want to try with the current version of the paradigm?"); + if (AfxMessageBox(msg ,MB_OKCANCEL) == IDOK) { + guidpar = true; + tryit = true; + newparname = parn; + } + } + if(hr == E_MGA_PARADIGM_NOTREG) { + CString msg = _T("Could not find paradigm '") + CString(parn) + "'"; + if (parv != "") { + msg += CString(" version ") + static_cast(parv); + } else if (parg.vt == (VT_UI1 | VT_ARRAY)) { + msg += CString(" with GUID ") + StringFromGUID2(parg); + } + IMgaRegistrarPtr registrar; + COMTHROW(registrar.CreateInstance(L"Mga.MgaRegistrar")); + _variant_t current_guid; + _bstr_t current_version; + registrar->QueryParadigm(static_cast(parn), _bstr_t().GetAddress(), current_guid.GetAddress(), REGACCESS_BOTH); + registrar->VersionFromGUID(static_cast(parn), current_guid, current_version.GetAddress(), REGACCESS_BOTH); + if (current_guid.vt != VT_EMPTY || current_version.length()) + { + CString msg_current = msg; + msg_current += L"\nDo you want to open with the current version ("; + if (current_version.length()) + { + msg_current += static_cast(current_version); + } + else if (current_guid.vt == (VT_UI1 | VT_ARRAY)) + { + msg_current += StringFromGUID2(current_guid); + } + msg_current += L")?"; + int mbRes = AfxMessageBox(msg_current, MB_YESNOCANCEL); + if (mbRes == IDCANCEL) + { + break; + } + if (mbRes == IDYES) + { + guidpar = true; + tryit = true; + newparname = parn; + } + } + + if (!tryit) + { + if (CString(parn) == _T("MetaGME2000")) + msg += _T("\n (In GME3 the MetaGME2000 paradigm was renamed to MetaGME)"); + msg += _T("\nDo you want to import with another registered paradigm ?"); + if (AfxMessageBox(msg ,MB_OKCANCEL) == IDOK) { + + CComObjPtr launcher; + COMTHROW( launcher.CoCreateInstance(CComBSTR(L"Mga.MgaLauncher")) ); + if (SUCCEEDED(launcher->MetaDlg(METADLG_NONE))) { + guidpar = true; + newparname.Empty(); + COMTHROW( launcher->get_ParadigmName(PutOut(newparname)) ); + tryit = !newparname.IsEmpty(); + } + } + } + } + if(hr == E_MGA_META_INCOMPATIBILITY && (parv.Length() > 0)) { + msg = _T("WARNING: Versioned project is not compatible with the paradigm '") + CString(parn) + _T("'\n") + _T(" (Eg.: Same version string was assigned to incompatible paradigms)\n") + _T("Do you want to open it based on the paradigm GUID?"); + if (AfxMessageBox(msg ,MB_OKCANCEL) == IDOK) { + guidpar = parg; + tryit = true; + newparname = parn; + } + } + if(hr == E_MGA_COMPONENT_ERROR) { + _bstr_t err(_T("ERROR: automatic addon components could not start up:\n")); + err += mgaProjectOpenError; + err += "\nDo you want to open the project without addons?"; + if (AfxMessageBox(err, MB_YESNO) == IDYES) { + enableAutoAddOns = VARIANT_FALSE; + mgaProject->EnableAutoAddOns(enableAutoAddOns); + tryit = true; + } + } + if(tryit) { + hr = mgaProject->OpenEx(PutInBstr(conn), CComBSTR(newparname), guidpar); + if(hr == E_MGA_PARADIGM_NOTREG || hr == E_MGA_PARADIGM_INVALID) { + DiagnoseParadigm(CString(parn)); + } + } + else break; + } + COMTHROW(hr); + } + + if(readable_only != VARIANT_FALSE) { + AfxMessageBox(_T("WARNING: Project file is read-only\nChange file access or use Save As to save your work")); + } + else { + CComVariant g, g2; + CComBSTR pname; + CComBSTR pver, pver2; + { + CComPtr t; + COMTHROW(mgaProject->CreateTerritory(NULL, &t, NULL)); + COMTHROW(mgaProject->BeginTransaction(t, TRANSACTION_READ_ONLY)); + COMTHROW(mgaProject->get_MetaName(&pname)); + COMTHROW(mgaProject->get_MetaGUID(&g)); + COMTHROW(mgaProject->get_MetaVersion(&pver)); + // COMTHROW(mgaProject->AbortTransaction()); PETER: Why abort ? + COMTHROW(mgaProject->CommitTransaction()); + CComPtr mgareg; + COMTHROW(mgareg.CoCreateInstance(OLESTR("MGA.MgaRegistrar"))); + CComBSTR connstr; + COMTHROW(mgareg->QueryParadigm(pname, &connstr, &g2, REGACCESS_PRIORITY)); + mgareg->VersionFromGUID(pname, g2, &pver2, REGACCESS_PRIORITY); + } + if(guidcmp(g, g2) && versioncmp(pver, pver2)) { + CString project_version = pver; + if (project_version == _T("")) + project_version = StringFromGUID2(g); + CString registered_paradigm_version = pver2; + if (pver2 == _T("")) + registered_paradigm_version = StringFromGUID2(g2); + CString prompt; + prompt.Format(_T("The '%s' paradigm version used to save this file, '%s', is not the currently-registered version, '%s'.\n\n") + _T("Do you want to upgrade to the current paradigm?"), + static_cast(pname), project_version, registered_paradigm_version); + int answer = AfxMessageBox(prompt, MB_YESNO); + if(answer == IDYES) { + COMTHROW(mgaProject->Close(VARIANT_FALSE)); + + // PETER: Create new MgaProject COM object (workaround MGA addon bug) + mgaProject.Release(); + COMTHROW( mgaProject.CoCreateInstance(OLESTR("Mga.MgaProject")) ); + COMTHROW( mgaProject->EnableAutoAddOns(enableAutoAddOns)); + + HRESULT hr = mgaProject->OpenEx(PutInBstr(conn), pname, g2); + if(hr == E_MGA_PARADIGM_NOTREG || hr == E_MGA_PARADIGM_INVALID) { + AfxMessageBox(_T("Paradigm error")); + DiagnoseParadigm(CString(pname)); + } + else if(hr != S_OK) { + AfxMessageBox(_T("Upgrade failed, probably due to incompatibility.\n") + _T("You can probably reopen the file without upgrade,\n") + _T("and use the 'Upgrade through XML' function later.")); + throw_last_com_error(hr); + } + else readable_only = false; + COMTHROW(hr); + } + } + } + AfterOpenOrCreateProject(conn); + hr = mgaProject->Notify(GLOBALEVENT_OPEN_PROJECT_FINISHED); + ASSERT(SUCCEEDED(hr)); + } + MSGCATCH(_T("Could not open project"), CloseProject(true, true)) + + UpdateProjectName(); + +} + + + +void CGMEApp::CreateProject(const CString &metaname, const CString &conn) +{ + CString msg; + try + { + CWaitCursor wait; + + // create the project + msg = _T("Fatal error while initializing project"); + ASSERT( mgaProject == 0 ); + COMTHROW( mgaProject.CoCreateInstance(L"Mga.MgaProject") ); + ASSERT( mgaProject != NULL ); + + COMTHROW( mgaProject->EnableAutoAddOns(VARIANT_TRUE)); + msg = _T("Could not create project"); + HRESULT hr = mgaProject->Create(PutInBstr(conn), PutInBstr(metaname)) ; + if(hr == E_MGA_PARADIGM_NOTREG || hr == E_MGA_PARADIGM_INVALID) { + TCHAR buf[200]; + _stprintf_s(buf, _T("Could not open current version of paradigm %s"), + static_cast(metaname)); + + AfxMessageBox(buf); + DiagnoseParadigm(metaname); + } + if(hr == E_MGA_COMPONENT_ERROR) { + _bstr_t errorInfo; + GetErrorInfo(errorInfo.GetAddress()); + _bstr_t err(_T("ERROR: automatic addon components could not start up:\n")); + err += errorInfo; + err += "\nDo you want to create the project without addons?"; + if (AfxMessageBox(err, MB_YESNO) == IDYES) { + mgaProject->EnableAutoAddOns(VARIANT_FALSE); + hr = mgaProject->Create(PutInBstr(conn), PutInBstr(metaname)) ; + } + } + if( hr == E_UNKNOWN_STORAGE && conn.Left(5) == _T("MGX=\"")) { + CloseProject(); + return; // no more exception handler explanatory messages + } + COMTHROW(hr); + + AfterOpenOrCreateProject(conn); + // TODO: set RootFolder name to filename? + hr = mgaProject->Notify(GLOBALEVENT_OPEN_PROJECT_FINISHED); + ASSERT(SUCCEEDED(hr)); + } + MSGCATCH(_T("Could not create project"), CloseProject()) +} + + +void CGMEApp::SaveProject(const CString &conn) { + if( mgaProject != NULL ) { + HRESULT hr = mgaProject->Save(CComBSTR(conn), VARIANT_FALSE); + if(hr != S_OK) { + CComBSTR error; + if (GetErrorInfo(&error)) { + CString errmsg = _T("Could not save project: "); + errmsg += error; + if (hr == HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED)) { + // FIXME: KMS: not too sure why this is ACCESS_DENIED from MoveFile instead of SHARING_VIOLATION + errmsg += _T("\nCheck that no other GME has this file open"); + } + AfxMessageBox(errmsg); + } else { + AfxMessageBox(_T("ERROR: Could not save project\nCheck access permissions")); + } + } + } + + if ((!conn.IsEmpty()) && (currentConnection != conn)) { + ChangedProjectConnStrings(); + currentConnection = conn; + m_RecentProjectList.AddAndWriteList(conn); + } +} + + + +// ******************************************************************************************** + + +void CGMEApp::GetSettings() +{ + bool oldUseAutoRouting = useAutoRouting; + MSGTRY + { + CComObjPtr registrar; + COMTHROW( registrar.CoCreateInstance(L"Mga.MgaRegistrar") ); + + // Icons + CComBSTR bstr; + COMTHROW( registrar->get_IconPath(REGACCESS_BOTH,&bstr)); + CopyTo(bstr,bitmapPath); + + // Multiview + VARIANT_BOOL enabledmv; + COMTHROW( registrar->get_ShowMultipleView(REGACCESS_USER, &enabledmv) ); + multipleView = (enabledmv != VARIANT_FALSE); + + // Autosave + VARIANT_BOOL autosaveenable; + COMTHROW( registrar->get_AutosaveEnabled(REGACCESS_USER, &autosaveenable) ); + autosaveEnabled = (autosaveenable == VARIANT_FALSE) ? FALSE : TRUE; + + long autosavefreq; + COMTHROW( registrar->get_AutosaveFreq(REGACCESS_USER, &autosavefreq) ); + autosaveFreq = (int)autosavefreq; + + VARIANT_BOOL autosaveusedir; + COMTHROW( registrar->get_AutosaveUseDir(REGACCESS_USER, &autosaveusedir) ); + autosaveUseDir = (autosaveusedir == VARIANT_FALSE) ? 0 : 1; + + COMTHROW( registrar->get_AutosaveDir(REGACCESS_USER, PutOut(autosaveDir)) ); + + //Event Logging + VARIANT_BOOL enablelogging; + COMTHROW( registrar->get_EventLoggingEnabled(REGACCESS_USER, &enablelogging) ); + if(enablelogging != VARIANT_FALSE) + { + CGMEEventLogger::initialize(); + CGMEEventLogger::LogGMEEvent(_T("CGMEApp::GetSettings() Event Logging Enabled\r\n")); + } + else + { + CGMEEventLogger::LogGMEEvent(_T("CGMEApp::GetSettings() Event Logging Disabled\r\n")); + CGMEEventLogger::StopLogging(); + } + + // Autorouter + VARIANT_BOOL useautorouting = VARIANT_TRUE; + COMTHROW( registrar->get_UseAutoRouting(REGACCESS_USER, &useautorouting) ); + useAutoRouting = (useautorouting != VARIANT_FALSE); + + VARIANT_BOOL labelavoidance; + COMTHROW( registrar->get_LabelAvoidance(REGACCESS_USER, &labelavoidance) ); + labelAvoidance = (labelavoidance != VARIANT_FALSE); + + // Default Zoom Level + CComBSTR bstr_zl; + COMTHROW( registrar->GetDefZoomLevel( REGACCESS_USER, &bstr_zl)); + if( bstr_zl) + CopyTo( bstr_zl, defZoomLev); + + // SendMouseOver notification + VARIANT_BOOL send_mouse_over; + COMTHROW( registrar->GetMouseOverNotify(REGACCESS_USER, &send_mouse_over)); + mouseOverNotify = ( send_mouse_over != VARIANT_FALSE); + + // Real number format string + CComBSTR bstr_fmt; + COMTHROW( registrar->GetRealNmbFmtStr( REGACCESS_USER, &bstr_fmt)); + if( bstr_fmt) + CopyTo( bstr_fmt, realFmtStr); + + // History Maintained? + VARIANT_BOOL history_maintained; + COMTHROW( registrar->GetNavigation( REGACCESS_USER, &history_maintained)); + maintainHistory = ( history_maintained != VARIANT_FALSE); + } + MSGCATCH(_T("Error while trying to get program settings"),;); + if(CGMEDoc::theInstance) { + // Global AutoRouting policy changed, convert opened views if necessary + if (!useAutoRouting && oldUseAutoRouting) { + CComPtr nullPtr; + CGMEDoc::theInstance->ConvertPathToCustom(nullPtr); + } + if (autosaveEnabled) { + CMainFrame::theInstance->StartAutosaveTimer(autosaveFreq); + } + else { + CMainFrame::theInstance->StopAutosaveTimer(); + } + CGMEDoc::theInstance->ResetAllViews(); + } +} + +LONG GetRegKey(HKEY key, LPCTSTR subkey, LPTSTR retdata) +{ + HKEY hKey; + LONG lResult = RegOpenKeyEx(key, subkey, 0, KEY_QUERY_VALUE, &hKey); + + if( lResult == ERROR_SUCCESS) + { + long lDataSize = MAX_PATH; + TCHAR data[MAX_PATH]; + + RegQueryValue( hKey, NULL, data, &lDataSize); + lstrcpy( retdata,data); + RegCloseKey( hKey); + } + + return lResult; +} + +HINSTANCE GotoURL(LPCTSTR url, int showcmd) +{ + TCHAR key[MAX_PATH + MAX_PATH]; + + // First try ShellExecute() + HINSTANCE hResult = ShellExecute( NULL, _T("open"), url, NULL,NULL, showcmd); + //HINSTANCE hResult; + // If it failed, get the .htm regkey and lookup the program + if((UINT)hResult <= HINSTANCE_ERROR) + { + if( GetRegKey( HKEY_CLASSES_ROOT, _T(".htm"), key) == ERROR_SUCCESS) + { + lstrcat( key, _T("\\shell\\open\\command")); + + if( GetRegKey( HKEY_CLASSES_ROOT,key,key) == ERROR_SUCCESS) + { + TCHAR *pos; + pos = _tcsstr( key, _T("\"%1\"")); + + if( pos == NULL) + { + // No quotes found + pos = _tcsstr( key, _T("%1")); // Check for % 1, without quotes + if( pos == NULL) // No parameter at all... + pos = key+lstrlen( key)-1; + else + *pos = '\0'; // Remove the parameter + } + else + *pos = '\0'; + // Remove the parameter + + lstrcat(pos, _T(" ")); + lstrcat(pos, url); + + // FIXME: should use CreateProcess + hResult = (HINSTANCE)WinExec( CStringA(key),showcmd); + } + } + } + + return hResult; +} + +///////////////////////////////////////////////////////////////////////////// +// CGMEApp message handlers + +// ******************************************************************************* +// ******************************************************************************* +// FILE +// ******************************************************************************* +// ******************************************************************************* + + +void CGMEApp::OnFileOpen() +{ + CMgaOpenDlg dlg(CMgaOpenDlg::OpenDialog); + CString conn = dlg.AskConnectionString(true, true); + + CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileOpen ")+conn+_T("\r\n")); + + if( conn.IsEmpty() ) + return; + + CWaitCursor wait; + + if( mgaProject != NULL ) + CloseProject(); + + if (conn.Left(4) == _T("MGX=")) { + CString fullPath = conn.Right(conn.GetLength() - 4); + TCHAR buffer[MAX_PATH]; + TCHAR* filepart = NULL; + GetFullPathName(fullPath, MAX_PATH, buffer, &filepart); + if (filepart == NULL) { + DisplayError(_T("Error opening MGX file"), E_FILEOPEN); + return; + } + // FIXME: KMS: yes, the quotes are necessary... + conn = _T("MGX=\""); + // FIXME: KMS: yes, a trailing slash makes it not work + conn += fullPath.Left(fullPath.GetLength() - _tcslen(filepart) - 1); + conn += _T("\""); + } + OpenProject(conn); +} + + +#define PROJECT_STATUS_CHANGED 4 + +void CGMEApp::OnAppExit() +{ + if (SaveAllModified()) + { + CWinAppEx::OnAppExit(); + return; + } +} + +BOOL CGMEApp::SaveAllModified() +{ + // Focus must be killed to flush ObjectInspector and Browser + ::SetFocus(NULL); + if (mgaProject != NULL && (proj_type_is_mga || proj_type_is_xmlbackend)) { + int ret = IDNO; + long l; + COMTHROW(mgaProject->get_ProjectStatus(&l)); + if (l & PROJECT_STATUS_CHANGED) + { + CString filename; + CString connstr = static_cast(mgaProject->ProjectConnStr); + if (connstr.Mid(0, 4) == "MGA=") + { + CString dirname; + GetFullPathName(connstr.Mid(4), filename, dirname); + filename = L" (" + filename + ")"; + } + CString message = _T("Do you want to save changes to '") + projectName + L"'" + filename + _T("?"); + ret = AfxMessageBox(message, MB_YESNOCANCEL); + } + if (ret == IDCANCEL) { + return FALSE; + } else if (ret == IDNO) { + abort_on_close = true; + OnFileAbortProject(); + } else { + ((CMainFrame*)m_pMainWnd)->clearMgaProj(); + return SafeCloseProject(); + } + } + return TRUE; +} + +int CGMEApp::ExitInstance() +{ + CloseProject(false); + +#ifdef _DEBUG + // Do this under Debug to silence memory leaks + // Don't do it under Release, since we may yet crash, and it's wasteful since we're exiting anyway + crUninstall(); +#endif + + return CWinAppEx::ExitInstance(); +} + +void CGMEApp::OnFileNew() +{ + CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileNew\r\n")); + + MSGTRY { + CString metaname; + CString dataconn; + CMgaOpenDlg dlg(CMgaOpenDlg::NewDialog); + + CComObjPtr launcher; + COMTHROW( launcher.CoCreateInstance(L"Mga.MgaLauncher", 0, CLSCTX_INPROC_SERVER) ); + + meta_label: + HRESULT hr = launcher->MetaDlg(METADLG_NEWFILE); + if( hr == S_FALSE ) + return; + COMTHROW( hr ); + + metaname.Empty(); + COMTHROW( launcher->get_ParadigmName(PutOut(metaname)) ); + + dataconn = dlg.AskConnectionString(false, false); + + if( dlg.pressed_back ) + goto meta_label; + + if( dataconn.IsEmpty() ) + return; + + CWaitCursor wait; + + if( mgaProject != NULL ) + CloseProject(); + + CreateProject(metaname, dataconn); + + if (mgaProject != NULL && (proj_type_is_mga||proj_type_is_xmlbackend)) { + OnFileSave(); + } + } + MSGCATCH(_T("Error creating new project"),;) + +} + +BOOL CGMEApp::OnOpenRecentProject(UINT nID) +{ + ASSERT_VALID(this); + + ASSERT(nID >= ID_FILE_MRU_PRJ1); + ASSERT(nID < ID_FILE_MRU_PRJ1 + (UINT)m_RecentProjectList.GetSize()); + + int nIndex = nID - ID_FILE_MRU_PRJ1; + CString conn = m_RecentProjectList[nIndex]; + + ASSERT(conn.GetLength() != 0); + + CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnOpenRecentProject ")+conn+_T("\r\n")); + + CWaitCursor wait; + + if( mgaProject != NULL ) + CloseProject(); + + OpenProject(conn); + + return TRUE; +} + + +bool CGMEApp::SafeCloseProject() { +// In case of an MGA file, try to save it first to find out + abort_on_close = false; + if(mgaProject != NULL && (proj_type_is_mga||proj_type_is_xmlbackend)) { + HRESULT hr = mgaProject->Save(NULL, VARIANT_FALSE); + if(hr != S_OK) { + CComBSTR error; + if (GetErrorInfo(&error)) { + CString errmsg = _T("Could not save project: "); + + errmsg += error; + if (hr == HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED)) { + // FIXME: KMS: not too sure why this is ACCESS_DENIED from MoveFile instead of SHARING_VIOLATION + errmsg += _T("\nCheck that no other GME has this file open"); + } + AfxMessageBox(errmsg); + return false; + } + else { + AfxMessageBox(_T("ERROR: Could not save project\nCheck access permissions")); + return false; + } + } + abort_on_close = true; + } + + BeginWaitCursor(); + if(CGMEDoc::theInstance) + CGMEDoc::theInstance->OnCloseDocument(); + EndWaitCursor(); + return true; +} + +void CGMEApp::OnFileCloseproject() +{ + CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileCloseproject\r\n")); + SaveAllModified(); +#ifdef _DEBUG + //CoFreeUnusedLibraries(); + HMODULE mga = GetModuleHandle(L"Mga.dll"); + if (mga) + { + typedef HRESULT (__stdcall *DllCanUnloadNow)(void); + DllCanUnloadNow proc = (DllCanUnloadNow)GetProcAddress(mga, "DllCanUnloadNow"); + if (proc && (*proc)() != S_OK) + { + DebugBreak(); + // If Mga.dll is compiled with /D_ATL_DEBUG_INTERFACES, this will dump the leaks via OutputDebugString (then crash later) + FreeLibrary(mga); + } + } +#endif +} + + +void CGMEApp::OnFileSaveAs() { + CMgaOpenDlg dlg(CMgaOpenDlg::SaveAsDialog); + CString conn = dlg.AskMGAConnectionString(); + + CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileSaveAs ")+conn+_T("\r\n")); + + if( conn.IsEmpty() ) + return; + BeginWaitCursor(); + SaveProject(conn); + EndWaitCursor(); +} + +void CGMEApp::OnFileSave() +{ + CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileSave\r\n")); + // GME-307 Focus must be killed to flush ObjectInspector and Browser + ::SetFocus(NULL); + + BeginWaitCursor(); + SaveProject(_T("")); + EndWaitCursor(); +} + +void CGMEApp::OnFileAbortProject() +{ + CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileAbortProject\r\n")); + ((CMainFrame*)m_pMainWnd)->clearMgaProj(); + + long l; + COMTHROW(mgaProject->get_ProjectStatus(&l)); + if(!abort_on_close && IsUndoPossible() && (l & PROJECT_STATUS_CHANGED) && + AfxMessageBox(_T("Discard edits to project ") + projectName + _T("?"), + MB_OKCANCEL) == IDCANCEL) { + return; + } + abort_on_close = true; + + BeginWaitCursor(); + if(CGMEDoc::theInstance) + CGMEDoc::theInstance->OnCloseDocument(true); + EndWaitCursor(); +} + + +void CGMEApp::OnFileExportxml() +{ + CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileExportxml ")); + MSGTRY + { + CComPtr dumper; + COMTHROW( dumper.CoCreateInstance(L"Mga.MgaDumper") ); + ASSERT( dumper != NULL ); + + CString initialFile; + CString initialDir; + if (theApp.isMgaProj()) { + getMgaPaths(initialFile, initialDir); + if (initialFile.Right(3) == _T("mga")) { + initialFile.Truncate(initialFile.GetLength() - 3); + initialFile += _T("xme"); + } + } + + CFileDialog dlg(FALSE, _T("xme"), initialFile, + OFN_EXPLORER | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR, + _T("Exported Files (*.xme)|*.xme|All Files (*.*)|*.*||")); + if (initialDir) + { + dlg.GetOFN().lpstrInitialDir = initialDir; + } + if( dlg.DoModal() != IDOK ) + { + CGMEEventLogger::LogGMEEvent(_T("Canceled\r\n")); + return; + } + CGMEEventLogger::LogGMEEvent(dlg.GetPathName()+_T("\r\n")); + + CWaitCursor wait; + IMgaDumper2Ptr dumper2 = (IMgaDumper*)dumper; + if (dumper2 && m_pMainWnd) + dumper2->__DumpProject2(theApp.mgaProject, _bstr_t(dlg.GetPathName()), (ULONGLONG)(m_pMainWnd->GetSafeHwnd())); + else + dumper->__DumpProject(theApp.mgaProject, _bstr_t(dlg.GetPathName())); + + if( CMainFrame::theInstance) CMainFrame::theInstance->m_console.Message( CString( _T("Project successfully exported into ")) + dlg.GetPathName() + _T("."), 1); + } + MSGCATCH(_T("Error while generating XML file"),;) +} + + +void CGMEApp::OnFileImportxml() +{ + CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileImportxml ")); + + CString new_file_name = _T(""); + + MSGTRY + { + CFileDialog dlg(TRUE, _T("xme"), (LPCTSTR) new_file_name, + OFN_EXPLORER | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | + OFN_FILEMUSTEXIST, + _T("GME Exported Files (*.xme;*.xml)|*.xme; *.xml|All Files (*.*)|*.*||")); + if( dlg.DoModal() != IDOK ) + { + CGMEEventLogger::LogGMEEvent(_T("Cancelled\r\n")); + return; + } + CGMEEventLogger::LogGMEEvent(dlg.GetPathName()+_T("\r\n")); + CString fullPath = dlg.GetPathName(); + CString fname = dlg.GetFileName(); + CString ftitle = dlg.GetFileTitle(); + Importxml(fullPath, fname, ftitle); + } + MSGCATCH(_T("Error importing XML file"),;) +} + +void CGMEApp::Importxml(CString fullPath, CString fname, CString ftitle) +{ + CComPtr parser; + COMTHROW( parser.CoCreateInstance(L"Mga.MgaParser") ); + ASSERT( parser != NULL ); + + CString folderPath = fullPath.Left(fullPath.GetLength() - fname.GetLength()); + + if (fullPath.Right(3).CompareNoCase(_T("xml")) == 0 ) { + AfxMessageBox( + _T("Newer versions of GME use the \".xme.\" filename extension\n") + _T("for exported XML data files.\n") + _T("Please, rename your existing files to avoid further problems!\n"), + MB_OK | MB_ICONINFORMATION); + } + + bool newproject = !mgaProject; + if (newproject) { + CString dataconn; + COMTRY { + CComBstrObj xmeparadigm, xmeparversion, xmebasename, xmeversion; + CComVariant xmeparguid, parguid; + + COMTHROW( parser->GetXMLInfo(PutInBstr(fullPath), PutOut(xmeparadigm), PutOut(xmeparversion), &xmeparguid, PutOut(xmebasename), PutOut(xmeversion)) ); + parguid = xmeparguid; + + CMgaOpenDlg opdlg(CMgaOpenDlg::ImportDialog); + if (ftitle.IsEmpty()) + opdlg.SetFileNameHint(PutInCString(xmebasename)); + else + opdlg.SetFileNameHint(ftitle); + opdlg.SetFolderPathHint(folderPath); + dataconn = opdlg.AskConnectionString(false, false); + if (dataconn.IsEmpty()) { + CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileImportxml exited because empty connection string has been given")); + return; + } + + { + CComPtr reg; + COMTHROW( reg.CoCreateInstance(L"Mga.MgaRegistrar") ); + CComBstrObj conn; + HRESULT h1 = reg->QueryParadigm(xmeparadigm, PutOut(conn), &xmeparguid, REGACCESS_PRIORITY); + CComVariant regparguid; + conn.Empty(); + HRESULT h2 = reg->QueryParadigm(xmeparadigm, PutOut(conn), ®parguid, REGACCESS_PRIORITY); + CComBstrObj regCurrentVersion; + if (SUCCEEDED(h2)) { + reg->VersionFromGUID(xmeparadigm, regparguid, ®CurrentVersion.p, REGACCESS_PRIORITY); + } + + CComVariant regGuidFromVersion; + HRESULT h3GuidFromVersion = E_FAIL; + if (xmeparversion.Length() != 0) { + h3GuidFromVersion = reg->GUIDFromVersion(xmeparadigm, xmeparversion, ®GuidFromVersion, REGACCESS_PRIORITY); + if (SUCCEEDED(h3GuidFromVersion)) + { + xmeparguid = regGuidFromVersion; + } else + { + h1 = E_MGA_PARADIGM_NOTREG; + } + } + + TCHAR buf[300]; + if(h2 != S_OK) { + ASSERT(h1 != S_OK); + CString msg = _T("Could not find paradigm paradigm '") + CString(xmeparadigm) + "'"; + if (CString(xmeparadigm) == _T("MetaGME2000")) + msg += _T("\n (In GME3 the MetaGME2000 paradigm was renamed to MetaGME)"); + msg += _T("\nDo you want to import with an other registered paradigm ?"); + if (AfxMessageBox(msg ,MB_OKCANCEL) == IDOK) { + CComObjPtr launcher; + COMTHROW( launcher.CoCreateInstance(CComBSTR(L"Mga.MgaLauncher")) ); + if (SUCCEEDED(launcher->MetaDlg(METADLG_NONE))) { + // parguid = true; + parguid.Clear(); + xmeparadigm.Empty(); + COMTHROW( launcher->get_ParadigmName(PutOut(xmeparadigm)) ); + } + else { + return; // safe before create + } + } + else { + return; // safe before create + } + } + else { + CComBstrObj bstrxmeparguid, bstrregparguid; + GUID gg; + + CopyTo(xmeparguid,gg); + CopyTo(gg, bstrxmeparguid); + + CopyTo(regparguid,gg); + CopyTo(gg, bstrregparguid); + + if(h1 != S_OK) { + _stprintf_s(buf, _T("Could not locate paradigm %s, version '%s'.\n\n") + _T("Do you want to upgrade to the current version ('%s') instead?"), + static_cast(xmeparadigm), + static_cast(xmeparversion.Length() != 0 ? xmeparversion : bstrxmeparguid), + static_cast(regCurrentVersion.Length() != 0 ? regCurrentVersion : bstrregparguid)); + if(AfxMessageBox(buf, MB_OKCANCEL | MB_ICONQUESTION) == IDOK) { + parguid = regparguid; + } + else { + // AfxMessageBox(_T("Import canceled")); + return; // safe before create + } + + } + else if(bstrxmeparguid.Compare(bstrregparguid)) { + _stprintf_s(buf, _T("This model was exported using paradigm %s, version '%s'.\n\n") + _T("Do you want to upgrade to the current version ('%s')?"), + static_cast(xmeparadigm), + static_cast(xmeparversion.Length() != 0 ? xmeparversion : bstrxmeparguid), + static_cast(regCurrentVersion.Length() != 0 ? regCurrentVersion : bstrregparguid)); + int answer = AfxMessageBox(buf,MB_YESNOCANCEL | MB_ICONQUESTION); + if(answer == IDYES) { + parguid = regparguid; + } + else if(answer == IDCANCEL) { + // AfxMessageBox(_T("Import canceled")); + return; // safe before create + } + } + } + } + COMTHROW( mgaProject.CoCreateInstance(L"Mga.MgaProject") ); + COMTHROW( mgaProject->EnableAutoAddOns(VARIANT_TRUE)); + HRESULT hr = mgaProject->CreateEx(PutInBstr(dataconn), PutInBstr(xmeparadigm), parguid); + if(hr == E_MGA_PARADIGM_NOTREG || hr == E_MGA_PARADIGM_INVALID) { + TCHAR buf[300]; + CComBstrObj parguid1; + GUID gg; + CopyTo(parguid,gg); + CopyTo(gg, parguid1); + _stprintf_s(buf, _T("Could not open paradigm %s\nVersion ID: %s"), + static_cast(xmeparadigm), static_cast(parguid1)); + + AfxMessageBox(buf); + } + if(hr == E_MGA_COMPONENT_ERROR) { + _bstr_t errorInfo; + GetErrorInfo(errorInfo.GetAddress()); + _bstr_t err(_T("ERROR: automatic addon components could not start up:\n")); + err += errorInfo; + err += "\nDo you want to create the project without addons?"; + if (AfxMessageBox(err, MB_YESNO) == IDYES) { + mgaProject->EnableAutoAddOns(VARIANT_FALSE); + hr = mgaProject->CreateEx(PutInBstr(dataconn), PutInBstr(xmeparadigm), parguid); + } + } + COMTHROW(hr); + AfterOpenOrCreateProject(dataconn); + } catch(hresult_exception &e) { + CloseProject(); + DisplayError(_T("Could not create the project"), e.hr); + throw; + } + } + + //UpdateProjectName(); // moved below + + CWaitCursor wait; + if(mgaConstMgr) COMTHROW(mgaConstMgr->Enable(VARIANT_FALSE)); + + CString file_name = fullPath; + if( CMainFrame::theInstance) CMainFrame::theInstance->m_console.Message( CString( _T("Importing ")) + file_name + _T("..."), 1); + IMgaParser2Ptr parser2 = (IMgaParser*)parser; + if (parser2 && m_pMainWnd) + parser2->__ParseProject2(theApp.mgaProject, _bstr_t(fullPath), (ULONGLONG)(m_pMainWnd->GetSafeHwnd())); + else + COMTHROW(parser->ParseProject(theApp.mgaProject, PutInBstr(fullPath))); + + // mgaproject has been filled with data, let's update title: + UpdateProjectName(); + + if(newproject && (proj_type_is_mga||proj_type_is_xmlbackend)) { + OnFileSave(); + } + + if (CMainFrame::theInstance) + CMainFrame::theInstance->m_console.Message(fullPath + _T(" was successfully imported."), 1); + else + AfxMessageBox(fullPath + _T(" was successfully imported.")); + + if (mgaConstMgr) + COMTHROW(mgaConstMgr->Enable(VARIANT_TRUE)); + HRESULT hr = mgaProject->Notify(GLOBALEVENT_OPEN_PROJECT_FINISHED); + ASSERT(SUCCEEDED(hr)); +} + + + +void CGMEApp::OnFileXMLUpdate() +{ + CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileXMLUpdate\r\n")); + ASSERT(mgaProject); + ASSERT(mgaMetaProject); + + TCHAR xmlname[MAX_PATH]; + GetTempFileName(_T("."), _T("XEX"),0, xmlname); + + if(currentConnection.Find(_T("MGA=")) != 0) { + AfxMessageBox(_T("Function is available only for .mga models")); + } + + CString fname = currentConnection.Mid(4); + CString backupname; + + MSGTRY + { + CWaitCursor wait; + CComBstrObj parname; + COMTHROW( mgaMetaProject->get_Name(PutOut(parname)) ); + CComBstrObj metaconn; + + CComPtr reg; + COMTHROW( reg.CoCreateInstance(L"Mga.MgaRegistrar") ); + CComBstrObj currentguid; + GUID currentguid_guid; + { + CComVariant parguid; + COMTHROW( mgaMetaProject->get_GUID(&parguid) ); + + CComVariant pg2; + + COMTHROW(reg->QueryParadigm(parname, PutOut(metaconn), &pg2, REGACCESS_PRIORITY)); + + CComBstrObj parguid1; + GUID gg; + CopyTo(parguid,gg); + CopyTo(gg, parguid1); + + CopyTo(pg2,gg); + currentguid_guid = gg; + CopyTo(gg, currentguid); + + if(!parguid1.Compare(currentguid)) { + TCHAR buf[200]; + _stprintf_s(buf, _T("There is no need to upgrade this model\nIts Meta Version ID is the current ID\nCurrent ID: %s"), + static_cast(currentguid)); + AfxMessageBox(buf); + return; + } + } + + CComPtr dumper; + COMTHROW( dumper.CoCreateInstance(L"Mga.MgaDumper") ); + ASSERT( dumper != NULL ); + + COMTHROW( dumper->DumpProject(theApp.mgaProject, PutInBstr(CString(xmlname))) ); + + + SafeCloseProject(); + ASSERT(!mgaProject); + + backupname = fname; + int p = backupname.ReverseFind('.'); + if(!p || backupname.Find('\\',p) != -1) p = backupname.GetLength(); + backupname.Insert(p,_T("-backup")); + DeleteFile(backupname); + if(!MoveFile(fname, backupname)) { + backupname = fname; + CString buf; + buf.Format(L"Could not save original file '%s' to '%s'", + static_cast(fname), static_cast(backupname)); + AfxMessageBox(buf); + COMTHROW(E_NOTFOUND); + } + + + + CreateProject(PutInCString(parname), currentConnection); + + if(!mgaProject || !mgaMetaProject) { + AfxMessageBox(_T("Error creating project")); + return; + } + + UpdateComponentLists(); + ChangedProjectConnStrings(); + + CComPtr parser; + COMTHROW( parser.CoCreateInstance(L"Mga.MgaParser") ); + ASSERT( parser != NULL ); + if(mgaConstMgr) COMTHROW(mgaConstMgr->Enable(VARIANT_FALSE)); + IMgaParser2Ptr parser2 = (IMgaParser*)parser; + if (parser2 && m_pMainWnd) + COMTHROW(parser2->ParseProject2(mgaProject,PutInBstr(CString(xmlname)), (ULONGLONG)(m_pMainWnd->GetSafeHwnd()))); + else + COMTHROW(parser->ParseProject(mgaProject,PutInBstr(CString(xmlname))) ); + { + _bstr_t version; + _variant_t v_guid; + CopyTo(currentguid_guid, &v_guid); + reg->VersionFromGUID(parname, v_guid, version.GetAddress(), REGACCESS_PRIORITY); + CString buf = CString(_T("The model has been updated.\nCurrent version: ")) + + (version.length() ? static_cast(version) : currentguid) + L"\nThe original model has been saved to " + backupname; + AfxMessageBox(buf); + } + } + catch(hresult_exception &e) { + if(backupname.IsEmpty()) { + CString buf; + buf.Format(L"The upgrade failed: 0x%x\nThe model has not been closed", e.hr); + AfxMessageBox(buf); + } + else { + if(backupname.Compare(fname)) { + if(MoveFile(backupname, fname)) backupname = fname; + } + CString buf; + buf.Format(L"The upgrade failed: 0x%x\nThe original model is in file %s", e.hr, + static_cast(backupname)); + AfxMessageBox(buf); + } + } + + if (mgaConstMgr) COMTHROW(mgaConstMgr->Enable(VARIANT_TRUE)); +} + + + +void CGMEApp::OnFileRegcomponents() +{ + CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileRegcomponents ")); + MSGTRY + { + CComObjPtr launcher; + COMTHROW( launcher.CoCreateInstance(L"Mga.MgaLauncher") ); + COMTHROW( launcher->put_ParadigmName(PutInBstr(guiMetaProject->name))); + COMTHROW( launcher->put_ComponentType(COMPONENTTYPE_ALL) ); + + ATLASSERT(mgaProject); + CComBSTR runningcomps; + { + CComPtr comps; + COMTHROW(mgaProject->get_AddOnComponents(&comps)); + MGACOLL_ITERATE(IMgaComponent, comps) { + CComQIPtr compx = MGACOLL_ITER; + CComBSTR p; + if(compx) COMTHROW(compx->get_ComponentProgID(&p)); + else COMTHROW(MGACOLL_ITER->get_ComponentName(&p)); + if(runningcomps) runningcomps += _T(" "); + runningcomps += p; + } + MGACOLL_ITERATE_END; + } + // FIXME: huge kludge here: enables CCompDlg to show which addons are running + COMTHROW(launcher->put_Parameter(CComVariant(runningcomps))); + + CGMEEventLogger::LogGMEEvent(CString(runningcomps)+_T("\r\n")); + + COMTHROW( launcher->ComponentDlg(COMPONENTDLG_INTERP)); + UpdateComponentLists(true); + } + MSGCATCH(_T("Error while trying to register the interpreter"),;) +} + +void CGMEApp::OnFileSettings() +{ + CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileSettings\r\n")); + MSGTRY + { + CComObjPtr launcher; + COMTHROW( launcher.CoCreateInstance(L"Mga.MgaLauncher") ); + COMTHROW( launcher->GmeDlg()); + } + MSGCATCH(_T("Error while trying to get GME settings"),;) + GetSettings(); +} + +void CGMEApp::OnFileClearLocks() +{ + if( mgaProject != NULL || mgaMetaProject != NULL ) + return; + + MSGTRY + { + CMgaOpenDlg dlg(CMgaOpenDlg::ClearLocksDialog); + CString conn = dlg.AskConnectionString(false, true); + + if( conn.IsEmpty() ) + return; + + CWaitCursor wait; + + CComObjPtr project; + COMTHROW( project.CoCreateInstance(OLESTR("MGA.MgaProject")) ); + ASSERT( project != NULL ); + COMTHROW( project->CheckLocks(PutInBstr(conn), VARIANT_TRUE) ); + + AfxMessageBox(_T("Database locks are cleared")); + } + MSGCATCH(_T("Error while clearing locks in database"),;) +} + +void CGMEApp::OnHelpContents() +{ + CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnHelpContents\r\n")); + + MSGTRY { + CComObjPtr launcher; + COMTHROW( launcher.CoCreateInstance(L"Mga.MgaLauncher") ); + COMTHROW( launcher->ShowHelp(NULL) ); + } + MSGCATCH(_T("Error while showing help contents."),;) +} + +void CGMEApp::OnFileCheckall() +{ + CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileCheckall\r\n")); + ASSERT(mgaConstMgr); + if (!mgaConstMgr) + return; + // message boxes displayed from constraint manager if in interactive mode + mgaConstMgr->ObjectsInvokeEx(mgaProject, NULL, NULL, NULL); +} + +void CGMEApp::OnFileDisplayConstraints() +{ + CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileDisplayConstraints\r\n")); + ASSERT(mgaConstMgr); + if (!mgaConstMgr) + return; + mgaConstMgr->ObjectsInvokeEx(mgaProject, NULL, NULL, CONSTMGR_SHOW_CONSTRAINTS); + +} + + + +void CGMEApp::OnFileRegparadigms() +{ + CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileRegparadigms\r\n")); + MSGTRY + { + CComPtr launcher; + COMTHROW( launcher.CoCreateInstance(L"Mga.MgaLauncher", 0, CLSCTX_INPROC_SERVER) ); + + while(1) { + HRESULT hr = launcher->MetaDlg(METADLG_PARREG); + if( hr == S_FALSE ) return; + + COMTHROW( launcher->put_ComponentType(COMPONENTTYPE_ALL) ); + + bool workonrunningparadigm = false; + if(guiMetaProject) { + CComBstrObj metaname; + COMTHROW( launcher->get_ParadigmName(PutOut(metaname)) ); + if(metaname == PutInBstr(guiMetaProject->name)) workonrunningparadigm = true; + } + + if(workonrunningparadigm) { + ATLASSERT(mgaProject); + CComBSTR runningcomps; + CComPtr comps; + COMTHROW(mgaProject->get_AddOnComponents(&comps)); + MGACOLL_ITERATE(IMgaComponent, comps) { + CComQIPtr compx = MGACOLL_ITER; + CComBSTR p; + if(compx) COMTHROW(compx->get_ComponentProgID(&p)); + else COMTHROW(MGACOLL_ITER->get_ComponentName(&p)); + if(runningcomps) runningcomps += _T(" "); + runningcomps += p; + } + MGACOLL_ITERATE_END; + COMTHROW(launcher->put_Parameter(CComVariant(runningcomps))); + } + + COMTHROW( launcher->ComponentDlg(COMPONENTDLG_INTERP)); + + if(workonrunningparadigm) UpdateComponentLists(true); + } + } MSGCATCH(_T("Error registering paradigms"), ;); +} + + +// ******************************************************************************* + +void CGMEApp::OnUpdateFileNew(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(guiMetaProject == NULL); +} + +void CGMEApp::OnUpdateFileOpen(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(guiMetaProject == NULL); +} + +void CGMEApp::OnUpdateFileCloseproject(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(guiMetaProject != NULL); +} + +void CGMEApp::OnUpdateFileSave(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(mgaProject != NULL && (proj_type_is_mga||proj_type_is_xmlbackend)); +} + +void CGMEApp::OnUpdateFileSaveAs(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(mgaProject != NULL && proj_type_is_mga); +} + +void CGMEApp::OnUpdateFileAbortProject(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(mgaProject != NULL && proj_type_is_mga); +} + +void CGMEApp::OnUpdateFileExportxml(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(guiMetaProject != NULL); +} + +void CGMEApp::OnUpdateFileXMLUpdate(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(mgaProject != NULL && proj_type_is_mga); +} + +void CGMEApp::OnUpdateFileCheckall(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(mgaConstMgr != NULL); +} + +void CGMEApp::OnUpdateFileDisplayConstraints(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(mgaConstMgr != NULL); + +} + +void CGMEApp::OnUpdateFileRegcomponents(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(guiMetaProject != NULL); +} + +void CGMEApp::OnUpdateRecentProjectMenu(CCmdUI* pCmdUI) +{ + ASSERT_VALID(this); + m_RecentProjectList.UpdateMenu(pCmdUI,guiMetaProject == NULL); +} + + +// ******************************************************************************* +// ******************************************************************************* +// EDIT +// ******************************************************************************* +// ******************************************************************************* + + +void CGMEApp::OnEditProjectproperties() +{ + CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnEditProjectproperties ") + projectName +_T("\r\n")); + CProjectPropertiesDlg dlg; + if(dlg.DoModal() == IDOK) { + if(CGMEDoc::theInstance) + CGMEDoc::theInstance->SetTitle(projectName); + UpdateMainFrameTitle(projectName); + } +} + + +void CGMEApp::OnEditUndo() +{ + CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnEditUndo\r\n")); + mgaProject->Undo(); +} + +void CGMEApp::OnEditRedo() +{ + CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnEditRedo\r\n")); + mgaProject->Redo(); +} + +void CGMEApp::OnEditClearUndo() +{ + CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnEditClearUndo\r\n")); + if( mgaProject == NULL ) + return; + + if(AfxMessageBox(_T("You are about to lose all Undo/Redo information. Proceed?"),MB_YESNO | MB_ICONQUESTION) == IDYES) { + MSGTRY + { + COMTHROW( mgaProject->FlushUndoQueue() ); + } + MSGCATCH(_T("Error while clearing the undo queue"),;) + } +} + + +// ******************************************************************************* + +void CGMEApp::OnUpdateEditUndo(CCmdUI* pCmdUI) +{ + if(guiMetaProject != NULL) { + short undoSize; + short redoSize; + mgaProject->UndoRedoSize(&undoSize,&redoSize); + pCmdUI->Enable(undoSize > 0); + } + else + pCmdUI->Enable(FALSE); +} + +void CGMEApp::OnUpdateEditRedo(CCmdUI* pCmdUI) +{ + if(guiMetaProject != NULL) { + short undoSize; + short redoSize; + mgaProject->UndoRedoSize(&undoSize,&redoSize); + pCmdUI->Enable(redoSize > 0); + } + else + pCmdUI->Enable(FALSE); +} + +void CGMEApp::OnUpdateEditClearUndo(CCmdUI* pCmdUI) +{ + if(mgaProject != NULL) { + short undoSize; + short redoSize; + mgaProject->UndoRedoSize(&undoSize,&redoSize); + pCmdUI->Enable(undoSize > 0); + } + else + pCmdUI->Enable(FALSE); +} + +void CGMEApp::OnUpdateEditProjectproperties(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(CGMEDoc::theInstance != 0); +} + + + +/* +void CGMEApp::OnUpdateFileRunplugin1(CCmdUI* pCmdUI) +{ + + CMenu *filemenu = pCmdUI->m_pMenu; + UINT idx = pCmdUI->m_nIndex; +if(idx == 0) return; + CString label; + ASSERT(filemenu); + filemenu->GetMenuString(idx,label,MF_BYPOSITION); + filemenu->DeleteMenu(idx,MF_BYPOSITION); + CMenu pluginmenu; + pluginmenu.CreatePopupMenu(); + pluginmenu.GetMenuItemID + for(int i = 0; i < comps.GetSize(); ++i) { + pluginmenu.AppendMenu(MF_ENABLED, pCmdUI->m_nID + i,comps[i]); + } + filemenu->InsertMenu(idx, + comps.GetSize() ? MF_BYPOSITION|MF_POPUP|MF_ENABLED: MF_BYPOSITION|MF_POPUP|MF_GRAYED, + (UINT)pluginmenu.Detach(),label); + +} +*/ + +void CGMEApp::OnRunPlugin(UINT nID) { + CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnRunPlugin ")+plugins[nID - ID_FILE_RUNPLUGIN1]+_T("\r\n")); + + // Focus must be killed to flush ObjectInspector and Browser + ::SetFocus(NULL); + + RunComponent(plugins[nID - ID_FILE_RUNPLUGIN1]); +} + +void CGMEApp::OnRunInterpreter(UINT nID) { + CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnRunInterpreter ")+interpreters[nID - ID_FILE_INTERPRET1]+_T("\r\n")); + + // Focus must be killed to flush ObjectInspector and Browser + ::SetFocus(NULL); + + RunComponent(interpreters[nID - ID_FILE_INTERPRET1]); +} + +void CGMEApp::OnRunComponentHelp(UINT nID) { + UINT id = (nID - ID_HELP_COMPONENTHELP_FIRST) / 2; + bool isEven = (nID - ID_HELP_COMPONENTHELP_FIRST) % 2 == 0; + CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnRunComponentHelp ") + + (id < plugins.GetSize() ? + plugins[id] : (id < plugins.GetSize() + interpreters.GetSize() ? + interpreters[id - plugins.GetSize()] : addons[id - plugins.GetSize() - interpreters.GetSize()])) + + _T("\r\n")); + + CString onlineHelpLocation = (id < plugins.GetSize() ? + pluginOnlineHelp[id] : (id < plugins.GetSize() + interpreters.GetSize() ? + interpreterOnlineHelp[id - plugins.GetSize()] : addonOnlineHelp[id - plugins.GetSize() - interpreters.GetSize()])); + CString offlineHelpLocation = (id < plugins.GetSize() ? + pluginOfflineHelp[id] : (id < plugins.GetSize() + interpreters.GetSize() ? + interpreterOfflineHelp[id - plugins.GetSize()] : addonOfflineHelp[id - plugins.GetSize() - interpreters.GetSize()])); + + ShellExecute(NULL, L"open", (isEven ? onlineHelpLocation : offlineHelpLocation), NULL, NULL, SW_SHOWNORMAL); +} + +void CGMEApp::OnRunParadigmHelp(UINT nID) +{ + CComBSTR pname = guiMetaProject->name; + + CGMEEventLogger::LogGMEEvent((_T("CGMEApp::OnRunParadigmHelp ") + + std::wstring(static_cast(pname)) + _T("\r\n")).c_str()); + + CString help = (nID == ID_HELP_PARADIGMHELP_FIRST ? this->paradigmOnlineHelp : this->paradigmOfflineHelp); + if (!help.IsEmpty()) + { + ShellExecute(NULL, L"open", help, NULL, NULL, SW_SHOWNORMAL); + } +} + +void CGMEApp::RunComponent(const CString &compname) +{ + + IMgaLauncherPtr launcher; + launcher.CreateInstance(L"Mga.MgaLauncher"); + if(!launcher) { + AfxMessageBox(_T("Cannot start up component launcher")); + } + else { + CComPtr focus; + CComPtr selfcos; + COMTHROW(selfcos.CoCreateInstance(OLESTR("Mga.MgaFCOs"))); + CMDIChildWnd *pChild = CMainFrame::theInstance->MDIGetActive(); + if (pChild) { +#if !defined (ACTIVEXGMEVIEW) + CGMEView *view = (CGMEView*)pChild->GetActiveView(); + if (view) { + COMTHROW(view->currentModel.QueryInterface(&focus)); + POSITION pos = view->selected.GetHeadPosition(); + while (pos) { + CGuiFco *gfco = view->selected.GetNext(pos); + COMTHROW(selfcos->Append(gfco->mgaFco)); + } + } +#endif + } + + if(theApp.bNoProtect) COMTHROW( launcher->put_Parameter(CComVariant(true))); + // Disable the DCOM wait dialogs: if interpreters want them, they can do it themselves; but if they don't want them, they need to link to GME's mfc1xxu.dll + COleMessageFilter* messageFilter = AfxOleGetMessageFilter(); + messageFilter->EnableBusyDialog(FALSE); + messageFilter->EnableNotRespondingDialog(FALSE); + std::shared_ptr busyRestore(messageFilter, [](COleMessageFilter* filter){ filter->EnableBusyDialog(TRUE); } ); + std::shared_ptr notRespondingRestore(messageFilter, [](COleMessageFilter* filter){ filter->EnableNotRespondingDialog(TRUE); } ); + if(launcher->RunComponent(PutInBstr(compname), mgaProject, focus, selfcos, GME_MENU_START) != S_OK) { + CComObjPtr errinfo; + GetErrorInfo(0, PutOut(errinfo)); + if (errinfo) { + _bstr_t desc; + errinfo->GetDescription(desc.GetAddress()); + std::wstring error; + error += L"Component execution failed: "; + error += desc; + AfxMessageBox(error.c_str()); + } else { + AfxMessageBox(_T("Component execution failed")); + } + } + } +} + +class CGmePrintSetup : public CPrintDialog +{ +public: + enum { IDD = IDD_PRINT_DIALOG }; + CGmePrintSetup() : CPrintDialog(true, 0, NULL) {} +}; + +void CGMEApp::OnUniquePrintSetup() +{ + CGmePrintSetup setup; + setup.m_pd.Flags = PD_PRINTSETUP | // actually the current aspect + PD_ENABLESETUPTEMPLATE | + PD_ENABLEPRINTHOOK | PD_ENABLESETUPHOOK ; + setup.m_pd.hInstance = AfxGetInstanceHandle(); + setup.m_pd.lpSetupTemplateName = MAKEINTRESOURCE(IDD_PRINTSETUP_DIALOG); + DoPrintDialog(&setup); +} + +void CGMEApp::ImportDroppedFile(const CString& fname) +{ + CGMEEventLogger::LogGMEEvent(_T("CGMEApp::ImportDroppedFile ")); + + CString file_name = fname; + + MSGTRY + { + int fnameStart = fname.ReverseFind('\\'); + if (fnameStart == -1) + fnameStart = fname.ReverseFind('/'); + + CString ftitle; + CString fpath; + if (fnameStart != -1) { + fpath = fname.Left(fnameStart + 1); + ftitle = fname.Right(fname.GetLength() - fnameStart - 1); + int extStart = ftitle.ReverseFind('.'); + if (extStart != -1) + ftitle = ftitle.Left(extStart); + } + Importxml(file_name, file_name.Right(file_name.GetLength() - fnameStart), ftitle); + } + MSGCATCH(_T("Error importing XML file"),;) +} + +void CGMEApp::RegisterDroppedFile( const CString& fname, bool userReg/* = true*/) +{ + try + { + CWaitCursor wait; + IMgaRegistrarPtr registrar; + COMTHROW(registrar.CreateInstance(L"Mga.MgaRegistrar")); + + regaccessmode_enum reg_access = REGACCESS_USER; + + _bstr_t newname; + registrar->__RegisterParadigmFromData(_bstr_t(fname), newname.GetAddress(), reg_access); + + CMainFrame::theInstance->m_console.Message( _T("Done."), 1); + } + catch( hresult_exception &e) + { + CMainFrame::theInstance->m_console.Message( _T("Error while registering paradigm."), 3); + } + catch(_com_error &e) + { + _bstr_t error(L""); + if (e.Description() != _bstr_t()) + error = e.Description(); + else + GetErrorInfo(e.Error(), error.GetAddress()); + CMainFrame::theInstance->m_console.Message(CString("Error while registering paradigm: ") + static_cast(error), 3); + } +} + +void CGMEApp::OnUpdateFilePluginX(CCmdUI* pCmdUI) +{ + bool enabled = m_vecDisabledPlugIns.find( pCmdUI->m_nID) == m_vecDisabledPlugIns.end(); + if( pCmdUI->m_nID >= ID_FILE_RUNPLUGIN1 && pCmdUI->m_nID <= ID_FILE_RUNPLUGIN_LAST) + pCmdUI->Enable( enabled ); +} + +void CGMEApp::OnUpdateFileInterpretX(CCmdUI* pCmdUI) +{ + bool enabled = m_vecDisabledComps.find( pCmdUI->m_nID) == m_vecDisabledComps.end(); + if( pCmdUI->m_nID >= ID_FILE_INTERPRET1 && pCmdUI->m_nID <= ID_FILE_INTERPRET_LAST) + pCmdUI->Enable( enabled ); +} + +// this method is used internally +void CGMEApp::ClearDisabledComps() +{ + m_vecDisabledPlugIns.clear(); + m_vecDisabledComps.clear(); +} + +// this method is called from CGMEOLEApp::DisableComp +// and CGMEApp::UpdateCompList4CurrentKind +void CGMEApp::DisableComp( const CString& pCompToFind, bool pbHide) +{ + UINT id_of_comp = 0; + bool is_plugin = false; + for(int i = 0; !id_of_comp && i < plugins.GetSize(); ++i) + { + if( plugins[i] == pCompToFind) + { + id_of_comp = ID_FILE_RUNPLUGIN1 + i; + is_plugin = true; + } + } + + for(int i = 0; !id_of_comp && i < interpreters.GetSize(); ++i) + { + if( interpreters[i] == pCompToFind) + { + id_of_comp = ID_FILE_INTERPRET1 + i; + is_plugin = false; + } + } + + if( id_of_comp) // a valid command ID + { + //ActivateComp( id_of_comp, is_plugin, pbShow); + if( is_plugin) + { + ONE_ID_LIST::const_iterator pos = m_vecDisabledPlugIns.find( id_of_comp); + if( pbHide) // disable, so id_of_comp must be inserted into the vector + { + if( m_vecDisabledPlugIns.end() == pos) // not found + m_vecDisabledPlugIns.insert( m_vecDisabledPlugIns.end(), id_of_comp); + } + else // enable, so remove id_of_comp from the vector + { + if( m_vecDisabledPlugIns.end() != pos) // if really found + m_vecDisabledPlugIns.erase( pos); + } + } + else + { + ONE_ID_LIST::const_iterator pos = m_vecDisabledComps.find( id_of_comp); + if( pbHide) // disable, so id_of_comp must be inserted into the vector + { + if( m_vecDisabledComps.end() == pos) // not found + m_vecDisabledComps.insert( m_vecDisabledComps.end(), id_of_comp); + } + else // enable, so remove id_of_comp from the vector + { + if( m_vecDisabledComps.end() != pos) // if really found + m_vecDisabledComps.erase( pos); + } + } + } +} + +// this method is called from CGMEOLEApp::DisableCompForKinds +void CGMEApp::DisableCompForKinds( const CString& pComp, const CString& pKindSeq) +{ + int nm_of_tokens = 0; // will count the parsed kind names + int pos = 0; + CString t_kind; + t_kind = pKindSeq.Tokenize( _T(";"), pos); // tokenize by ';' + while( t_kind != _T("")) + { + ONE_COMP_LIST &my_comps = m_compsOfKind[ t_kind ]; + ONE_COMP_LIST::const_iterator it = my_comps.find( pComp); + if( it == my_comps.end()) // not found, so insert it + m_compsOfKind[ t_kind ].insert( pComp); + + ++nm_of_tokens; + t_kind = pKindSeq.Tokenize( _T(";"), pos); // move to next token + } +} + +// this method is called from CGMEView::OnActivateView (with the kindname shown) +// CGMEView::~CGMEView (with the special string: _NO_MODEL_IS_OPEN_ == m_no_model_open_string) +// CGMEApp::SetCompFiltering (with one from the items above) +void CGMEApp::UpdateCompList4CurrentKind( const CString& pKind) +{ + // if filter is OFF return + if( !m_compFilterOn) + { + return; + } + + // kind name should not be empty + if( pKind.IsEmpty()) { ASSERT(0); return; } + + ClearDisabledComps(); // reset all to original state (enabled) + + if( m_compsOfKind.find( pKind) != m_compsOfKind.end()) // if it has an entry + { + ONE_COMP_LIST &my_comps = m_compsOfKind[ pKind]; // this key already existed + for( ONE_COMP_LIST::const_iterator it = my_comps.begin(); it != my_comps.end(); ++it) + { + DisableComp( *it, true); // disable comps which are registered for this kind + } + } // if this kind has no assigned [excluded] component set: NOP [every component is enabled] +} + +void CGMEApp::SetCompFiltering( bool pOn) +{ + m_compFilterOn = pOn; + if( !m_compFilterOn) // if turned OFF + { + ClearDisabledComps(); // reset all to original state (enabled) + } + else // turned ON + { + // find the current view + bool found = false; + CMDIChildWnd *pChild = CMainFrame::theInstance->MDIGetActive(); + if( pChild) + { +#if !defined (ACTIVEXGMEVIEW) + CGMEView *view = (CGMEView*)pChild->GetActiveView(); + if( view && view->guiMeta) + { + found = true; + this->UpdateCompList4CurrentKind( view->guiMeta->name); + } +#endif + } + + if( !found) + this->UpdateCompList4CurrentKind( CGMEApp::m_no_model_open_string); + } +} + +bool CGMEApp::GetCompFiltering() +{ + return m_compFilterOn; +} + +bool CGMEApp::SetWorkingDirectory( LPCTSTR pPath) +{ + return SetCurrentDirectory( pPath) == TRUE; + //int sc = _chdir( pPath); + //return sc == 0; +} + +void CGMEApp::UpdateMainTitle(bool retrievePath) +{ + if (CMainFrame::theInstance) + UpdateMainFrameTitle(projectName, retrievePath); +} + +bool CGMEApp::IsUndoPossible(void) const +{ + if(!mgaProject) + return false; + + if (guiMetaProject != NULL) { + short undoSize; + short redoSize; + mgaProject->UndoRedoSize(&undoSize,&redoSize); + return undoSize > 0; + } + + return false; +} + +void CGMEApp::OnFocusBrowser() +{ + if( !mgaProject) return; + + CComObjPtr terry; + COMTHROW(mgaProject->CreateTerritory(NULL, PutOut(terry), NULL) ); + + LPUNKNOWN objs = CGMEObjectInspector::theInstance->GetObjects(); + CComQIPtr one_obj_coll( objs); + long len = 0; + if( one_obj_coll) COMTHROW( one_obj_coll->get_Count( &len)); + if( len >= 1) + { + MSGTRY + { + CComPtr one_obj, one_obj2; + long status = OBJECT_ZOMBIE; + CComBSTR id; + COMTHROW( one_obj_coll->get_Item( 1, &one_obj)); + COMTHROW( mgaProject->BeginTransaction(terry,TRANSACTION_READ_ONLY)); + + if( one_obj) COMTHROW( terry->OpenObj( one_obj, &one_obj2)); + if( one_obj2) { + COMTHROW( one_obj2->get_Status( &status)); + COMTHROW( one_obj2->get_ID( &id)); + } + + COMTHROW( mgaProject->CommitTransaction()); + + if( id.Length() > 0 && status == OBJECT_EXISTS) + { + CGMEBrowser::theInstance->FocusItem( id); + return; + } + } + MSGCATCH(_T("Error getting project rootfolder"), mgaProject->AbortTransaction()) + } + + MSGTRY + { + CComBSTR id; + CComPtr rf; + COMTHROW(mgaProject->BeginTransaction(terry,TRANSACTION_READ_ONLY)); + COMTHROW(mgaProject->get_RootFolder( &rf)); + if( rf) COMTHROW(rf->get_ID(&id)); + COMTHROW(mgaProject->CommitTransaction()); + + if( id.Length() > 0) + CGMEBrowser::theInstance->FocusItem( id); + } + MSGCATCH(_T("Error getting project rootfolder"), mgaProject->AbortTransaction()) +} + +void CGMEApp::OnFocusInspector() +{ + HWND hwnd = CGMEObjectInspector::theInstance->GetSafeHwnd(); + if( hwnd) ::SetFocus( hwnd); +} + +void CGMEApp::consoleMessage( const CString& p_msg, short p_type) +{ + if( CMainFrame::theInstance) // 99.99% of cases + CMainFrame::theInstance->m_console.Message( p_msg, p_type); + else + AfxMessageBox( p_msg); +} + +#ifdef _DEBUG +extern "C" FILE * __cdecl __iob_func(void) +{ + terminate(); + return NULL; +} + +// https://msdn.microsoft.com/en-us/library/bb531344.aspx#BK_CRT "Visual C++ 2015 Conformance Changes C Runtime Library(CRT)" +#pragma comment(lib, "legacy_stdio_definitions.lib") +#endif diff --git a/GME/Gme/GMEApp.h b/GME/Gme/GMEApp.h index b1341029..8dec6dfd 100644 --- a/GME/Gme/GMEApp.h +++ b/GME/Gme/GMEApp.h @@ -1,286 +1,291 @@ -// GMEApp.h : main header file for the GME application -// - -#if !defined(AFX_GME_H__BD235B4A_BD3F_11D3_91E2_00104B98EAD9__INCLUDED_) -#define AFX_GME_H__BD235B4A_BD3F_11D3_91E2_00104B98EAD9__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - -#ifndef __AFXWIN_H__ - #error include 'stdafx.h' before including this file for PCH -#endif - -#include "resource.h" // main symbols -#include -#include -#include "GMELib.h" - -#define ID_FILE_PLUGINMENU 40000 - - -#include "RecentConnStrList.h" - -///////////////////////////////////////////////////////////////////////////// -// CGMEApp: -// See GMEApp.cpp for the implementation of this class -// - -extern LONG GetRegKey(HKEY key, LPCTSTR subkey, LPTSTR retdata); -extern HINSTANCE GotoURL(LPCTSTR url, int showcmd); - - -struct IMgaProject; -struct IMgaMetaProject; -class CGuiMetaProject; -class CGuiPreferenceManager; - -class CGMEApp : public CWinAppEx -{ - friend class CGMEOLEApp; -public: - virtual BOOL PreTranslateMessage(MSG* pMsg); - CGMEApp(); - virtual ~CGMEApp(); - - CMultiDocTemplate* pDocTemplate; - CComPtr mgaProject; - CComPtr mgaClient; - CComPtr mgaMetaProject; -// dynamic menus - CStringArray plugins, interpreters, addons; - CStringArray pluginTooltips, interpreterTooltips, addonToolTips; - bool dynmenus_need_refresh; - - // Application look - UINT m_nAppLook; - CMFCToolBarImages m_userImages; - CComPtr mgaConstMgr; - CGuiMetaProject *guiMetaProject; - CString projectName; - CString bitmapPath, projectDir, paradigmDir; - bool multipleView; - bool useAutoRouting; - bool labelAvoidance; - - HACCEL m_GMEView_hAccel; - CRecentConnStrList m_RecentProjectList; - bool bNoProtect; // do not catch application errors - inline bool isMultiUserProj() const { return proj_type_is_xmlbackend; } - inline bool isMgaProj() const { return proj_type_is_mga; } - inline CString connString() const { return currentConnection; } - - void getMgaPaths(CString& filename, CString& dirname) { - ASSERT(isMgaProj()); - ASSERT(mgaProject); - CString conn = connString(); - const TCHAR* zsConn = conn; - zsConn += 4; // skip MGA= - GetFullPathName(zsConn, filename, dirname); - } - - BOOL OpenCommandLineProject(); - BOOL ShowWelcomeWindow(); - -private: - virtual int Run(); - void EmergencySave(); - bool proj_type_is_mga; - bool proj_type_is_xmlbackend; - bool abort_on_close; - CString currentConnection; - - bool autosaveEnabled; - bool autosaveUseDir; - CString autosaveDir; - int autosaveFreq; - CString defZoomLev; - bool mouseOverNotify; - CString realFmtStr; - bool maintainHistory; - - // - // component filter related fields - // - - // the state of component filtering (not preserved through GME sessions) - bool m_compFilterOn; - - // will store those command ids, which are disabled by the user - // through the ActivateComponent - typedef std::set ONE_ID_LIST; - ONE_ID_LIST m_vecDisabledPlugIns; - ONE_ID_LIST m_vecDisabledComps; - - typedef std::set ONE_COMP_LIST; - typedef std::map ONE_COMP_MAP; - // map of kind as key, and components registered for it - ONE_COMP_MAP m_compsOfKind; - - // - // component filter related private methods - // - void ClearDisabledComps(); - - // Updates the plugins and addons on the component toolbar - void CGMEApp::UpdateComponentToolbar(); - - // - // component filter related public methods - // -public: - // called from CGMEOLEApp: - void SetCompFiltering( bool pOn); - bool GetCompFiltering(); - void DisableComp(const CString& pCompToFind, bool pbHide); - void DisableCompForKinds( const CString& pComp, const CString& pKindSeq); - // called from CGMEView: - void UpdateCompList4CurrentKind( const CString& kind); - - static const TCHAR * m_no_model_open_string; - - // called from CGMEOLEAPP: - bool SetWorkingDirectory( LPCTSTR pPath); - -public: - void ImportDroppedFile(const CString& fname); - void RegisterDroppedFile( const CString& fname, bool userReg = true); - bool SafeCloseProject(); - void CloseProject(bool updateStatusBar = true, bool force_abort=false); - void OpenProject(const CString &conn); - void Importxml(CString fullPath, CString fname, CString ftitle); - void SaveProject(const CString &conn); - void CreateProject(const CString &metaname, const CString &dataconn); - void UpdateProjectName(bool retrievePath = false); - void UpdateMainFrameTitle(const CString& projName, bool retrievePath = false); - void AfterOpenOrCreateProject(const CString &conn); - void UpdateComponentLists(bool restart_addons = false); - void UpdateDynMenus(CMenu *filemenu); - void FindConstraintManager(); - void RunComponent(const CString &progid); - void exit() { OnAppExit(); } - void consoleMessage( const CString& p_msg, short type); - - void Autosave(); - CString getDefZoomLev() { return defZoomLev; } - inline bool isMouseOverNotifyEnabled() { return mouseOverNotify; } - inline bool isHistoryEnabled() { return maintainHistory; } - inline CString getRealFmtStr() { return realFmtStr; } - - // Both empty: reset on close, only one empty: no change to that name. - void ChangedProjectConnStrings(); - void GetSettings(); - - void UpdateMainTitle(bool retrievePath = false); - bool IsUndoPossible(void) const; - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CGMEApp) - public: - virtual BOOL InitInstance(); - virtual int ExitInstance(); - virtual void OnAppExit(); - virtual BOOL SaveAllModified(); - //}}AFX_VIRTUAL - - virtual LRESULT ProcessWndProcException(CException* e, const MSG* pMsg) - { - // TODO send with CrashRpt (if we didn't send it with CGMEView::OnWndMsg - // but the stack is gone, so a report here is much less useful - return __super::ProcessWndProcException(e, pMsg); - } - - void OnUniquePrintSetup(); -// Implementation - // Server object for document creation - //{{AFX_MSG(CGMEApp) - afx_msg void OnAppAbout(); - afx_msg void OnFileOpen(); - afx_msg void OnFileNew(); - afx_msg void OnUpdateRecentProjectMenu(CCmdUI* pCmdUI); - afx_msg BOOL OnOpenRecentProject(UINT nID); - afx_msg void OnUpdateFileCloseproject(CCmdUI* pCmdUI); - afx_msg void OnFileCloseproject(); - afx_msg void OnUpdateFileNew(CCmdUI* pCmdUI); - afx_msg void OnUpdateFileOpen(CCmdUI* pCmdUI); - afx_msg void OnEditUndo(); - afx_msg void OnEditRedo(); - afx_msg void OnUpdateEditRedo(CCmdUI* pCmdUI); - afx_msg void OnUpdateFileExportxml(CCmdUI* pCmdUI); - afx_msg void OnFileExportxml(); - afx_msg void OnFileImportxml(); - afx_msg void OnUpdateEditProjectproperties(CCmdUI* pCmdUI); - afx_msg void OnEditProjectproperties(); - afx_msg void OnFileSettings(); - afx_msg void OnFileClearLocks(); - afx_msg void OnEditClearUndo(); - afx_msg void OnUpdateEditClearUndo(CCmdUI* pCmdUI); - afx_msg void OnHelpContents(); - afx_msg void OnFileCheckall(); - afx_msg void OnUpdateFileCheckall(CCmdUI* pCmdUI); - afx_msg void OnUpdateFileSave(CCmdUI* pCmdUI); - afx_msg void OnUpdateFileSaveAs(CCmdUI* pCmdUI); - afx_msg void OnFileSaveAs(); - afx_msg void OnFileSave(); - afx_msg void OnFileAbortProject(); - afx_msg void OnUpdateFileAbortProject(CCmdUI* pCmdUI); - afx_msg void OnFileRegcomponents(); - afx_msg void OnFileRegparadigms(); - afx_msg void OnUpdateFileRegcomponents(CCmdUI* pCmdUI); - afx_msg void OnUpdateFileXMLUpdate(CCmdUI* pCmdUI); - afx_msg void OnFileXMLUpdate(); - afx_msg void OnRunPlugin(UINT nID); - afx_msg void OnRunInterpreter(UINT nID); - afx_msg void OnUpdateFilePluginX(CCmdUI* pCmdUI); - afx_msg void OnUpdateFileInterpretX(CCmdUI* pCmdUI); - afx_msg void OnFileDisplayConstraints(); - afx_msg void OnUpdateFileDisplayConstraints(CCmdUI* pCmdUI); - afx_msg void OnUpdateEditUndo(CCmdUI* pCmdUI); - afx_msg void OnFocusBrowser(); - afx_msg void OnFocusInspector(); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -extern CGMEApp theApp; - -///////////////////////////////////////////////////////////////////////////// - -///////////////////////////////////////////////////////////////////////////// -// CDLLInfoDlg dialog - -class CDLLInfoDlg : public CDialog -{ -// Construction -public: - CDLLInfoDlg(CWnd* pParent = NULL); // standard constructor - -// Dialog Data - //{{AFX_DATA(CDLLInfoDlg) - enum { IDD = IDD_DLL_DIALOG }; - CListCtrl m_DLLList; - //}}AFX_DATA - - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CDLLInfoDlg) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - - // Generated message map functions - //{{AFX_MSG(CDLLInfoDlg) - virtual BOOL OnInitDialog(); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_GME_H__BD235B4A_BD3F_11D3_91E2_00104B98EAD9__INCLUDED_) +// GMEApp.h : main header file for the GME application +// + +#if !defined(AFX_GME_H__BD235B4A_BD3F_11D3_91E2_00104B98EAD9__INCLUDED_) +#define AFX_GME_H__BD235B4A_BD3F_11D3_91E2_00104B98EAD9__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols +#include +#include +#include "GMELib.h" + +#define ID_FILE_PLUGINMENU 40000 + + +#include "RecentConnStrList.h" + +///////////////////////////////////////////////////////////////////////////// +// CGMEApp: +// See GMEApp.cpp for the implementation of this class +// + +extern LONG GetRegKey(HKEY key, LPCTSTR subkey, LPTSTR retdata); +extern HINSTANCE GotoURL(LPCTSTR url, int showcmd); + + +struct IMgaProject; +struct IMgaMetaProject; +class CGuiMetaProject; +class CGuiPreferenceManager; + +class CGMEApp : public CWinAppEx +{ + friend class CGMEOLEApp; +public: + virtual BOOL PreTranslateMessage(MSG* pMsg); + CGMEApp(); + virtual ~CGMEApp(); + + CMultiDocTemplate* pDocTemplate; + CComPtr mgaProject; + CComPtr mgaClient; + CComPtr mgaMetaProject; +// dynamic menus + CStringArray plugins, interpreters, addons; + CStringArray pluginTooltips, interpreterTooltips, addonToolTips; + CStringArray pluginOnlineHelp, interpreterOnlineHelp, addonOnlineHelp; + CStringArray pluginOfflineHelp, interpreterOfflineHelp, addonOfflineHelp; + CString paradigmOnlineHelp, paradigmOfflineHelp; + bool dynmenus_need_refresh; + + // Application look + UINT m_nAppLook; + CMFCToolBarImages m_userImages; + CComPtr mgaConstMgr; + CGuiMetaProject *guiMetaProject; + CString projectName; + CString bitmapPath, projectDir, paradigmDir; + bool multipleView; + bool useAutoRouting; + bool labelAvoidance; + + HACCEL m_GMEView_hAccel; + CRecentConnStrList m_RecentProjectList; + bool bNoProtect; // do not catch application errors + inline bool isMultiUserProj() const { return proj_type_is_xmlbackend; } + inline bool isMgaProj() const { return proj_type_is_mga; } + inline CString connString() const { return currentConnection; } + + void getMgaPaths(CString& filename, CString& dirname) { + ASSERT(isMgaProj()); + ASSERT(mgaProject); + CString conn = connString(); + const TCHAR* zsConn = conn; + zsConn += 4; // skip MGA= + GetFullPathName(zsConn, filename, dirname); + } + + BOOL OpenCommandLineProject(); + BOOL ShowWelcomeWindow(); + +private: + virtual int Run(); + void EmergencySave(); + bool proj_type_is_mga; + bool proj_type_is_xmlbackend; + bool abort_on_close; + CString currentConnection; + + bool autosaveEnabled; + bool autosaveUseDir; + CString autosaveDir; + int autosaveFreq; + CString defZoomLev; + bool mouseOverNotify; + CString realFmtStr; + bool maintainHistory; + + // + // component filter related fields + // + + // the state of component filtering (not preserved through GME sessions) + bool m_compFilterOn; + + // will store those command ids, which are disabled by the user + // through the ActivateComponent + typedef std::set ONE_ID_LIST; + ONE_ID_LIST m_vecDisabledPlugIns; + ONE_ID_LIST m_vecDisabledComps; + + typedef std::set ONE_COMP_LIST; + typedef std::map ONE_COMP_MAP; + // map of kind as key, and components registered for it + ONE_COMP_MAP m_compsOfKind; + + // + // component filter related private methods + // + void ClearDisabledComps(); + + // Updates the plugins and addons on the component toolbar + void CGMEApp::UpdateComponentToolbar(); + + // + // component filter related public methods + // +public: + // called from CGMEOLEApp: + void SetCompFiltering( bool pOn); + bool GetCompFiltering(); + void DisableComp(const CString& pCompToFind, bool pbHide); + void DisableCompForKinds( const CString& pComp, const CString& pKindSeq); + // called from CGMEView: + void UpdateCompList4CurrentKind( const CString& kind); + + static const TCHAR * m_no_model_open_string; + + // called from CGMEOLEAPP: + bool SetWorkingDirectory( LPCTSTR pPath); + +public: + void ImportDroppedFile(const CString& fname); + void RegisterDroppedFile( const CString& fname, bool userReg = true); + bool SafeCloseProject(); + void CloseProject(bool updateStatusBar = true, bool force_abort=false); + void OpenProject(const CString &conn); + void Importxml(CString fullPath, CString fname, CString ftitle); + void SaveProject(const CString &conn); + void CreateProject(const CString &metaname, const CString &dataconn); + void UpdateProjectName(bool retrievePath = false); + void UpdateMainFrameTitle(const CString& projName, bool retrievePath = false); + void AfterOpenOrCreateProject(const CString &conn); + void UpdateComponentLists(bool restart_addons = false); + void UpdateDynMenus(CMenu *filemenu); + void FindConstraintManager(); + void RunComponent(const CString &progid); + void exit() { OnAppExit(); } + void consoleMessage( const CString& p_msg, short type); + + void Autosave(); + CString getDefZoomLev() { return defZoomLev; } + inline bool isMouseOverNotifyEnabled() { return mouseOverNotify; } + inline bool isHistoryEnabled() { return maintainHistory; } + inline CString getRealFmtStr() { return realFmtStr; } + + // Both empty: reset on close, only one empty: no change to that name. + void ChangedProjectConnStrings(); + void GetSettings(); + + void UpdateMainTitle(bool retrievePath = false); + bool IsUndoPossible(void) const; + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CGMEApp) + public: + virtual BOOL InitInstance(); + virtual int ExitInstance(); + virtual void OnAppExit(); + virtual BOOL SaveAllModified(); + //}}AFX_VIRTUAL + + virtual LRESULT ProcessWndProcException(CException* e, const MSG* pMsg) + { + // TODO send with CrashRpt (if we didn't send it with CGMEView::OnWndMsg + // but the stack is gone, so a report here is much less useful + return __super::ProcessWndProcException(e, pMsg); + } + + void OnUniquePrintSetup(); +// Implementation + // Server object for document creation + //{{AFX_MSG(CGMEApp) + afx_msg void OnAppAbout(); + afx_msg void OnFileOpen(); + afx_msg void OnFileNew(); + afx_msg void OnUpdateRecentProjectMenu(CCmdUI* pCmdUI); + afx_msg BOOL OnOpenRecentProject(UINT nID); + afx_msg void OnUpdateFileCloseproject(CCmdUI* pCmdUI); + afx_msg void OnFileCloseproject(); + afx_msg void OnUpdateFileNew(CCmdUI* pCmdUI); + afx_msg void OnUpdateFileOpen(CCmdUI* pCmdUI); + afx_msg void OnEditUndo(); + afx_msg void OnEditRedo(); + afx_msg void OnUpdateEditRedo(CCmdUI* pCmdUI); + afx_msg void OnUpdateFileExportxml(CCmdUI* pCmdUI); + afx_msg void OnFileExportxml(); + afx_msg void OnFileImportxml(); + afx_msg void OnUpdateEditProjectproperties(CCmdUI* pCmdUI); + afx_msg void OnEditProjectproperties(); + afx_msg void OnFileSettings(); + afx_msg void OnFileClearLocks(); + afx_msg void OnEditClearUndo(); + afx_msg void OnUpdateEditClearUndo(CCmdUI* pCmdUI); + afx_msg void OnHelpContents(); + afx_msg void OnFileCheckall(); + afx_msg void OnUpdateFileCheckall(CCmdUI* pCmdUI); + afx_msg void OnUpdateFileSave(CCmdUI* pCmdUI); + afx_msg void OnUpdateFileSaveAs(CCmdUI* pCmdUI); + afx_msg void OnFileSaveAs(); + afx_msg void OnFileSave(); + afx_msg void OnFileAbortProject(); + afx_msg void OnUpdateFileAbortProject(CCmdUI* pCmdUI); + afx_msg void OnFileRegcomponents(); + afx_msg void OnFileRegparadigms(); + afx_msg void OnUpdateFileRegcomponents(CCmdUI* pCmdUI); + afx_msg void OnUpdateFileXMLUpdate(CCmdUI* pCmdUI); + afx_msg void OnFileXMLUpdate(); + afx_msg void OnRunPlugin(UINT nID); + afx_msg void OnRunInterpreter(UINT nID); + afx_msg void OnRunComponentHelp(UINT nID); + afx_msg void OnRunParadigmHelp(UINT nID); + afx_msg void OnUpdateFilePluginX(CCmdUI* pCmdUI); + afx_msg void OnUpdateFileInterpretX(CCmdUI* pCmdUI); + afx_msg void OnFileDisplayConstraints(); + afx_msg void OnUpdateFileDisplayConstraints(CCmdUI* pCmdUI); + afx_msg void OnUpdateEditUndo(CCmdUI* pCmdUI); + afx_msg void OnFocusBrowser(); + afx_msg void OnFocusInspector(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +extern CGMEApp theApp; + +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// CDLLInfoDlg dialog + +class CDLLInfoDlg : public CDialog +{ +// Construction +public: + CDLLInfoDlg(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CDLLInfoDlg) + enum { IDD = IDD_DLL_DIALOG }; + CListCtrl m_DLLList; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CDLLInfoDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CDLLInfoDlg) + virtual BOOL OnInitDialog(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_GME_H__BD235B4A_BD3F_11D3_91E2_00104B98EAD9__INCLUDED_) diff --git a/GME/Gme/GuiMeta.cpp b/GME/Gme/GuiMeta.cpp index 573dba67..c9c9dc9e 100644 --- a/GME/Gme/GuiMeta.cpp +++ b/GME/Gme/GuiMeta.cpp @@ -5,6 +5,7 @@ #include "GuiMeta.h" #include "GuiObject.h" +CComBSTR StringFromGUID2(const CComVariant& guid); // helper functions @@ -66,6 +67,11 @@ CGuiMetaProject::CGuiMetaProject(CComPtr &mgaPt) COMTHROW(mgaMeta->get_DisplayedName(&bstr)); CopyTo(bstr,displayedName); } + { + CComVariant pguid; + COMTHROW(mgaMeta->get_GUID(&pguid)); + guid = StringFromGUID2(pguid); + } CComPtr mmFolder; COMTHROW(mgaMeta->get_RootFolder(&mmFolder)); diff --git a/GME/Gme/GuiMeta.h b/GME/Gme/GuiMeta.h index 3549bafc..a08cddde 100644 --- a/GME/Gme/GuiMeta.h +++ b/GME/Gme/GuiMeta.h @@ -15,6 +15,7 @@ class CGuiMetaProject ~CGuiMetaProject(); public: CString name; + CString guid; CString displayedName; CGuiMetaFolder *rootFolder; CGuiMetaBaseTable metaTable; diff --git a/GME/Gme/MainFrm.cpp b/GME/Gme/MainFrm.cpp index 605d692d..b9c18e98 100644 --- a/GME/Gme/MainFrm.cpp +++ b/GME/Gme/MainFrm.cpp @@ -94,6 +94,7 @@ BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWndEx) ON_UPDATE_COMMAND_UI(ID_MULTIUSER_ACTIVEUSERS, OnUpdateViewMultiUserActiveUsers) ON_COMMAND(ID_VIEW_CLEARCONSOLE, OnViewClearConsole) ON_UPDATE_COMMAND_UI(ID_VIEW_CLEARCONSOLE, OnUpdateViewClearConsole) + ON_UPDATE_COMMAND_UI(ID_HELP_CONTENTS, OnUpdateFileSettings) #define MSG_MAP_VIEW_PANE(ID, class_, member) \ ON_COMMAND(ID, (&CMainFrame::OnViewPane)) \ @@ -457,7 +458,7 @@ int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) mdiTabParams.m_tabLocation = CMFCTabCtrl::LOCATION_TOP; // Specifies that the tabs labels are located at the top of the page EnableMDITabbedGroups(TRUE, mdiTabParams); - CMFCToolBar::EnableQuickCustomization(); + CMFCToolBar::EnableQuickCustomization(); // Set the visual manager and style based on persisted value OnApplicationLook(theApp.m_nAppLook); @@ -1268,6 +1269,13 @@ void CMainFrame::OnUpdateViewClearConsole(CCmdUI* pCmdUI) pCmdUI->Enable(); } +void CMainFrame::OnUpdateFileSettings(CCmdUI* pCmdUI) +{ + // This is an update message for Tools/Options menu + // This triggers the refresh of plugins/interpreters menus + theApp.UpdateDynMenus(pCmdUI->m_pMenu); +} + void CMainFrame::OnDropFiles(HDROP p_hDropInfo) { CGMEEventLogger::LogGMEEvent(_T("MainFrame:OnDropFiles\r\n")); diff --git a/GME/Gme/MainFrm.h b/GME/Gme/MainFrm.h index c46fc663..00d84633 100644 --- a/GME/Gme/MainFrm.h +++ b/GME/Gme/MainFrm.h @@ -165,6 +165,7 @@ class CMainFrame : public CMDIFrameWndEx afx_msg void OnUpdateViewMultiUserSubversion(CCmdUI* pCmdUI); afx_msg void OnViewClearConsole(); afx_msg void OnUpdateViewClearConsole( CCmdUI* pCmdUI); + afx_msg void OnUpdateFileSettings(CCmdUI* pCmdUI); template afx_msg void OnViewPane() { diff --git a/GME/Gme/resource.h b/GME/Gme/resource.h index f0233717..4f556c28 100644 --- a/GME/Gme/resource.h +++ b/GME/Gme/resource.h @@ -520,16 +520,22 @@ #define ID_CONNCNTX_REVERSE 33270 #define ID_VIEW_SHOWCONNECTEDPORTSONLY 33271 #define ID_PORTCNTX_DELETE 33272 +#pragma region Help IDs +#define ID_HELP_PARADIGMHELP 0x9000 +#define ID_HELP_PARADIGMHELP_FIRST 0x9001 +#define ID_HELP_PARADIGMHELP_LAST 0x900F +#define ID_HELP_COMPONENTHELP 0x9010 +#define ID_HELP_COMPONENTHELP_FIRST 0x9011 +#define ID_HELP_COMPONENTHELP_LAST 0x908F +#pragma endregion #define IDW_TOOLBAR_MAIN 0xE820 #define IDW_TOOLBAR_WINS 0xE821 #define IDW_TOOLBAR_COMPONENT 0xE822 #define IDW_TOOLBAR_MODE 0xE823 #define IDW_TOOLBAR_NAVIG 0xE824 #define IDW_TOOLBAR_MODELING 0xE825 - - -#define ID_FILE_INTERPRET_LAST ID_FILE_INTERPRET49 #define ID_FILE_RUNPLUGIN_LAST ID_FILE_RUNPLUGIN8 +#define ID_FILE_INTERPRET_LAST ID_FILE_INTERPRET49 // Next default values for new objects // diff --git a/GME/Interfaces/MgaUtil.idl b/GME/Interfaces/MgaUtil.idl index 0817f533..948e323c 100644 --- a/GME/Interfaces/MgaUtil.idl +++ b/GME/Interfaces/MgaUtil.idl @@ -517,6 +517,28 @@ interface IMgaRegistrar : IDispatch HRESULT UnregisterComponentLibrary([in] BSTR path, [in] regaccessmode_enum mode); }; +[ + object, + uuid(0E3C2752-6173-4050-BD47-AE54DA1C373A), + dual, + helpstring("IMgaRegistrar2 Interface"), + pointer_default(unique) +] +interface IMgaRegistrar2 : IMgaRegistrar +{ + [propput, helpstring("property ParadigmExtraInfo")] + HRESULT ParadigmExtraInfo([in] regaccessmode_enum mode, [in] BSTR ParadigmName, [in] BSTR ParadigmVersionGUID, [in] BSTR name, [in] BSTR newVal); + + [propget, helpstring("property ParadigmExtraInfo")] + HRESULT ParadigmExtraInfo([in] regaccessmode_enum mode, [in] BSTR ParadigmName, [in] BSTR ParadigmVersionGUID, [in] BSTR name, [out, retval] BSTR *pVal); + + [helpstring("setter for property ParadigmExtraInfo")] + HRESULT SetParadigmExtraInfoDisp([in] BSTR ParadigmName, [in] BSTR ParadigmVersionGUID, [in] BSTR name, [in] BSTR newVal, [in, defaultvalue(REGACCESS_SYSTEM)] regaccessmode_enum mode); + + [helpstring("getter for property ParadigmExtraInfo")] + HRESULT GetParadigmExtraInfoDisp([in] BSTR ParadigmName, [in] BSTR ParadigmVersionGUID, [in] BSTR name, [out, retval] BSTR *pVal); +}; + typedef enum metadlg_enum { METADLG_NONE = 0x0000, diff --git a/GME/MgaUtil/MgaRegistrar.cpp b/GME/MgaUtil/MgaRegistrar.cpp index a525b35c..2fda2216 100644 --- a/GME/MgaUtil/MgaRegistrar.cpp +++ b/GME/MgaUtil/MgaRegistrar.cpp @@ -1,2456 +1,2531 @@ -#include "stdafx.h" -#include "MgaRegistrar.h" -#include "atlconv.h" -#include "CommonComponent.h" -#include "Parser.h" - -#import "mscorlib.tlb" -#import "libid:5f45c5d6-4e11-42fc-a558-cfa0b6c7bea6" // MgaDotNetServices - -#include "atlsafe.h" - -#ifdef _DEBUG -void ERRTHROW(LONG err) -{ - VERIFYTHROW( err == ERROR_SUCCESS ); -} -#else -#define ERRTHROW(FUNC) \ -{ \ - VERIFYTHROW( (FUNC) == ERROR_SUCCESS ); \ -} -#endif - -void WIN32THROW(LONG err) -{ - if (err != ERROR_SUCCESS) - HR_THROW(HRESULT_FROM_WIN32(err)); -} - -const CString rootreg(_T("SOFTWARE\\GME")); - - -CString QueryValue(CRegKey &key, const TCHAR *name) -{ - CString buffer; - TCHAR *bufp = buffer.GetBuffer(4096); - ULONG buflen = 4095; - LONG err = key.QueryStringValue( name, bufp, &buflen); - if( err != ERROR_SUCCESS ) { - buflen = 0; - if(err != ERROR_FILE_NOT_FOUND) ERRTHROW(err); - } - ASSERT( 0 <= buflen && buflen < 4096 ); - bufp[buflen] = _T('\0'); - buffer.ReleaseBuffer(); - - return buffer; -} - -// --------------------------- CMgaRegistrar - -#define RM_USER 1 -#define RM_SYS 2 -#define RM_SYS2 4 -#define RM_BOTH 3 -#define RM_TEST 8 -#define RM_PRIO (RM_SYS2 | RM_USER) -#define RM_SYSDOREAD (RM_SYS2 | RM_SYS) - -// For read operations: USER, SYS, PRIO -// For multi-return read operations: USER, SYS, BOTH, PRIO -// For write operations: USER, SYS, BOTH, TEST - -void REVOKE_SYS2(regaccessmode_enum &mode) { *(int *)&mode &= ~RM_SYS2; } - -enum Tristate_t { - Tristate_Enabled, - Tristate_Disabled, - Tristate_Not_Specified, -}; - -bool Combine_Tristate(Tristate_t user, Tristate_t system, bool default_ = false) { - if (user != Tristate_Not_Specified) { - return user == Tristate_Enabled; - } - if (system != Tristate_Not_Specified) { - return system == Tristate_Enabled; - } - return default_; -} - -Tristate_t IsAssociated_hive(const CString& progidstr, const CString& paradigmstr, HKEY hive) { - CRegKey acomp; - - if (acomp.Open(hive, rootreg + _T("\\Components\\") + progidstr + _T("\\Associated"), KEY_READ) != ERROR_SUCCESS) { - return Tristate_Not_Specified; - } - ULONG count = 0; - DWORD res = acomp.QueryValue(paradigmstr, NULL, NULL, &count); - if (res != ERROR_SUCCESS) { - return Tristate_Not_Specified; - } - CString val; - if (acomp.QueryStringValue(paradigmstr, val.GetBufferSetLength(count), &count) == ERROR_SUCCESS) { - val.ReleaseBuffer(); - if (val == _T("Disabled")) { - return Tristate_Disabled; - } - } - return Tristate_Enabled; -} - -bool IsAssociated_regaccess(const CString& progidstr, const CString& paradigmstr, regaccessmode_enum mode) { - if (mode & REGACCESS_BOTH) { - return Combine_Tristate( - IsAssociated_hive(progidstr, paradigmstr, HKEY_CURRENT_USER), - IsAssociated_hive(progidstr, paradigmstr, HKEY_LOCAL_MACHINE)); - } else if (mode & REGACCESS_USER) { - return IsAssociated_hive(progidstr, paradigmstr, HKEY_CURRENT_USER) == Tristate_Enabled; - } else if (mode & REGACCESS_SYSTEM) { - return IsAssociated_hive(progidstr, paradigmstr, HKEY_LOCAL_MACHINE) == Tristate_Enabled; - } - return false; -} - -STDMETHODIMP CMgaRegistrar::get_IconPath(regaccessmode_enum mode, BSTR *path) -{ - CHECK_OUT(path); - - COMTRY - { - LONG res; - CString str; - if(mode & RM_USER) { - CRegKey mga; - res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("IconPath")); - str.TrimRight(_T(" ;,\t")); - if(!str.IsEmpty()) REVOKE_SYS2(mode); - } - } - if(mode & (RM_SYSDOREAD)) { - CRegKey mga; - res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - CString str2; - if(res == ERROR_SUCCESS) { - str2 = QueryValue(mga, _T("IconPath")); - } - if (str2 == "") { - str2 = "$PARADIGMDIR\\icons;$PROJECTDIR\\icons"; - } - str2.TrimLeft(_T(" ;,\t")); - if(!str.IsEmpty() && !str2.IsEmpty()) - { - str += _T(";"); - str += str2; - } - else - str = str2; - } - CopyTo(str, path); - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::put_IconPath(regaccessmode_enum mode, BSTR path) -{ - COMTRY - { - CString str = path; - if(mode & RM_USER) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); - ERRTHROW( mga.SetStringValue( _T("IconPath"), str )); - } - if(mode & (RM_SYS | RM_TEST)) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); - if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("IconPath"), str)); - } - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::get_ShowMultipleView(regaccessmode_enum mode, VARIANT_BOOL *enabled) -{ - COMTRY - { - LONG res; - CString str; - if(mode & RM_USER) { - CRegKey mga; - res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("ShowMultipleView")); - if(!str.IsEmpty()) { - REVOKE_SYS2(mode); - } - } - } - if(mode & (RM_SYSDOREAD)) { - CRegKey mga; - res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("ShowMultipleView")); - } - } - *enabled = (str == _T("1")) ? VARIANT_TRUE : VARIANT_FALSE; // Default value: false - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::put_ShowMultipleView(regaccessmode_enum mode, VARIANT_BOOL enabled) -{ - COMTRY - { - CString str = (enabled == VARIANT_FALSE) ? _T("0") : _T("1"); - if(mode & RM_USER) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); - ERRTHROW( mga.SetStringValue( _T("ShowMultipleView"), str)); - } - if(mode & (RM_SYS | RM_TEST)) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); - if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("ShowMultipleView"), str)); - } - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::get_EventLoggingEnabled(regaccessmode_enum mode, VARIANT_BOOL *enabled) -{ - COMTRY - { - LONG res; - CString str; - if(mode & RM_USER) { - CRegKey mga; - res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("EventLoggingEnabled")); - if(!str.IsEmpty()) { - REVOKE_SYS2(mode); - } - } - } - if(mode & (RM_SYSDOREAD)) { - CRegKey mga; - res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("EventLoggingEnabled")); - } - } - *enabled = (str == _T("1")) ? VARIANT_TRUE : VARIANT_FALSE; // Default value: false - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::put_EventLoggingEnabled(regaccessmode_enum mode, VARIANT_BOOL enabled) -{ - COMTRY - { - CString str = (enabled == VARIANT_FALSE) ? _T("0") : _T("1"); - if(mode & RM_USER) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); - ERRTHROW( mga.SetStringValue( _T("EventLoggingEnabled"), str)); - } - if(mode & (RM_SYS | RM_TEST)) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); - if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("EventLoggingEnabled"), str)); - } - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::get_AutosaveEnabled(regaccessmode_enum mode, VARIANT_BOOL *enabled) -{ - COMTRY - { - LONG res; - CString str; - if(mode & RM_USER) { - CRegKey mga; - res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("AutosaveEnabled")); - if(!str.IsEmpty()) { - REVOKE_SYS2(mode); - } - } - } - if(mode & (RM_SYSDOREAD)) { - CRegKey mga; - res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("AutosaveEnabled")); - } - } - *enabled = (str == _T("1")) ? VARIANT_TRUE : VARIANT_FALSE; // Default value: false - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::put_AutosaveEnabled(regaccessmode_enum mode, VARIANT_BOOL enabled) -{ - COMTRY - { - CString str = (enabled == VARIANT_FALSE) ? _T("0") : _T("1"); - if(mode & RM_USER) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); - ERRTHROW( mga.SetStringValue( _T("AutosaveEnabled"), str)); - } - if(mode & (RM_SYS | RM_TEST)) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); - if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("AutosaveEnabled"), str)); - } - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::get_AutosaveFreq(regaccessmode_enum mode, long *secs) -{ - COMTRY - { - LONG res; - CString str; - if(mode & RM_USER) { - CRegKey mga; - res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("AutosaveFreq")); - if(!str.IsEmpty()) { - REVOKE_SYS2(mode); - } - } - } - if(mode & (RM_SYSDOREAD)) { - CRegKey mga; - res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("AutosaveFreq")); - } - } - if (_stscanf((LPCTSTR)str, _T("%ld"), secs) != 1) { - *secs = 60; // Default value: 1 minute - } - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::put_AutosaveFreq(regaccessmode_enum mode, long secs) -{ - COMTRY - { - CString str; - str.Format(_T("%ld"), secs); - if(mode & RM_USER) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); - ERRTHROW( mga.SetStringValue( _T("AutosaveFreq"), str)); - } - if(mode & (RM_SYS | RM_TEST)) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); - if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("AutosaveFreq"), str)); - } - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::get_AutosaveUseDir(regaccessmode_enum mode, VARIANT_BOOL *enabled) -{ - COMTRY - { - LONG res; - CString str; - if(mode & RM_USER) { - CRegKey mga; - res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("AutosaveUseDir")); - if(!str.IsEmpty()) { - REVOKE_SYS2(mode); - } - } - } - if(mode & (RM_SYSDOREAD)) { - CRegKey mga; - res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("AutosaveUseDir")); - } - } - *enabled = (str == _T("1")) ? VARIANT_TRUE : VARIANT_FALSE; // Default value: false - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::put_AutosaveUseDir(regaccessmode_enum mode, VARIANT_BOOL enabled) -{ - COMTRY - { - CString str = (enabled == VARIANT_FALSE) ? _T("0") : _T("1"); - if(mode & RM_USER) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); - ERRTHROW( mga.SetStringValue( _T("AutosaveUseDir"), str)); - } - if(mode & (RM_SYS | RM_TEST)) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); - if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("AutosaveUseDir"), str)); - } - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::get_AutosaveDir(regaccessmode_enum mode, BSTR *dir) -{ - CHECK_OUT(dir); - - COMTRY - { - LONG res; - CString str; - if(mode & RM_USER) { - CRegKey mga; - res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("AutosaveDir")); - } - } - if(mode & (RM_SYSDOREAD)) { - CRegKey mga; - res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("AutosaveDir")); - } - } - CopyTo(str, dir); - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::put_AutosaveDir(regaccessmode_enum mode, BSTR dir) -{ - COMTRY - { - CString str = dir; - if(mode & RM_USER) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); - ERRTHROW( mga.SetStringValue( _T("AutosaveDir"), str)); - } - if(mode & (RM_SYS | RM_TEST)) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); - if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("AutosaveDir"), str)); - } - } - COMCATCH(;) -} - - -STDMETHODIMP CMgaRegistrar::get_ExternalEditorEnabled(regaccessmode_enum mode, VARIANT_BOOL *enabled) -{ - COMTRY - { - LONG res; - CString str; - if(mode & RM_USER) { - CRegKey mga; - res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("ExternalEditorEnabled")); - if(!str.IsEmpty()) { - REVOKE_SYS2(mode); - } - } - } - if(mode & (RM_SYSDOREAD)) { - CRegKey mga; - res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("ExternalEditorEnabled")); - } - } - *enabled = (str == _T("1")) ? VARIANT_TRUE : VARIANT_FALSE; // Default value: false - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::put_ExternalEditorEnabled(regaccessmode_enum mode, VARIANT_BOOL enabled) -{ - COMTRY - { - CString str = (enabled == VARIANT_FALSE) ? _T("0") : _T("1"); - if(mode & RM_USER) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); - ERRTHROW( mga.SetStringValue( _T("ExternalEditorEnabled"), str)); - } - if(mode & (RM_SYS | RM_TEST)) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); - if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("ExternalEditorEnabled"), str)); - } - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::get_ExternalEditor(regaccessmode_enum mode, BSTR *path) -{ - CHECK_OUT(path); - - COMTRY - { - LONG res; - CString str; - if(mode & RM_USER) { - CRegKey mga; - res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("ExternalEditor")); - } - } - if(mode & (RM_SYSDOREAD)) { - CRegKey mga; - res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("ExternalEditor")); - } - } - CopyTo(str, path); - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::put_ExternalEditor(regaccessmode_enum mode, BSTR path) -{ - COMTRY - { - CString str = path; - if(mode & RM_USER) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); - ERRTHROW( mga.SetStringValue( _T("ExternalEditor"), str)); - } - if(mode & (RM_SYS | RM_TEST)) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); - if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("ExternalEditor"), str)); - } - } - COMCATCH(;) -} - - -STDMETHODIMP CMgaRegistrar::get_UseAutoRouting(regaccessmode_enum mode, VARIANT_BOOL *enabled) -{ - COMTRY - { - LONG res; - CString str; - if(mode & RM_USER) { - CRegKey mga; - res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("UseAutoRouting")); - if(!str.IsEmpty()) { - REVOKE_SYS2(mode); - } - } - } - if(mode & (RM_SYSDOREAD)) { - CRegKey mga; - res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("UseAutoRouting")); - } - } - *enabled = (str == _T("0")) ? VARIANT_FALSE : VARIANT_TRUE; // Default value: true - } - COMCATCH(;) -} - - -STDMETHODIMP CMgaRegistrar::put_UseAutoRouting(regaccessmode_enum mode, VARIANT_BOOL enabled) -{ - COMTRY - { - CString str = (enabled == VARIANT_FALSE) ? _T("0") : _T("1"); - if(mode & RM_USER) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); - ERRTHROW( mga.SetStringValue( _T("UseAutoRouting"), str)); - } - if(mode & (RM_SYS | RM_TEST)) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); - if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("UseAutoRouting"), str)); - } - } - COMCATCH(;) -} - - -STDMETHODIMP CMgaRegistrar::get_LabelAvoidance(regaccessmode_enum mode, VARIANT_BOOL *enabled) -{ - COMTRY - { - LONG res; - CString str; - if(mode & RM_USER) { - CRegKey mga; - res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("LabelAvoidance")); - if(!str.IsEmpty()) { - REVOKE_SYS2(mode); - } - } - } - if(mode & (RM_SYSDOREAD)) { - CRegKey mga; - res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("LabelAvoidance")); - } - } - *enabled = (str == _T("1")) ? VARIANT_TRUE : VARIANT_FALSE; // Default value: false - } - COMCATCH(;) -} - - -STDMETHODIMP CMgaRegistrar::put_LabelAvoidance(regaccessmode_enum mode, VARIANT_BOOL enabled) -{ - COMTRY - { - CString str = (enabled == VARIANT_FALSE) ? _T("0") : _T("1"); - if(mode & RM_USER) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); - ERRTHROW( mga.SetStringValue( _T("LabelAvoidance"), str)); - } - if(mode & (RM_SYS | RM_TEST)) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); - if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("LabelAvoidance"), str)); - } - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::get_ScriptEngine(regaccessmode_enum mode, BSTR *path) { - CHECK_OUT(path); - - COMTRY - { - LONG res; - CString str; - if(mode & RM_USER) { - CRegKey mga; - res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("ScriptEngine")); - str.TrimRight(_T(" ;,\t")); - if(!str.IsEmpty()) REVOKE_SYS2(mode); - } - } - if(mode & (RM_SYSDOREAD)) { - CRegKey mga; - res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - CString str2 = QueryValue(mga, _T("ScriptEngine")); - str2.TrimLeft(_T(" ;,\t")); - if(!str.IsEmpty() && !str2.IsEmpty()) str += _T(";"); - str += str2; - } - } - CopyTo(str, path); - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::put_ScriptEngine(regaccessmode_enum mode, BSTR path) { - COMTRY - { - CString str = path; - if(mode & RM_USER) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); - ERRTHROW( mga.SetStringValue(_T("ScriptEngine"), str) );//z7 - } - if(mode & (RM_SYS | RM_TEST)) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); - if(mode & RM_SYS) ERRTHROW( mga.SetStringValue(_T("ScriptEngine"), str) );//z7 - } - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::GetDefZoomLevel(regaccessmode_enum p_mode, BSTR *p_zlev) -{ - CHECK_OUT(p_zlev); - COMTRY - { - LONG res; - CString str; - if(p_mode & RM_USER) { - CRegKey mga; - res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("DefaultZoomLevel")); - if(!str.IsEmpty()) REVOKE_SYS2(p_mode); - } - } - if(p_mode & (RM_SYSDOREAD)) { - CRegKey mga; - res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("DefaultZoomLevel")); - } - } - CopyTo(str, p_zlev); - } - COMCATCH(;) - -} - -STDMETHODIMP CMgaRegistrar::SetDefZoomLevel(regaccessmode_enum p_mode, BSTR p_zlev) -{ - COMTRY - { - CString str = p_zlev; - if(p_mode & RM_USER) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); - ERRTHROW( mga.SetStringValue( _T("DefaultZoomLevel"), str)); - } - if(p_mode & (RM_SYS | RM_TEST)) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); - if(p_mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("DefaultZoomLevel"), str)); - } - } - COMCATCH(;) -} - - -STDMETHODIMP CMgaRegistrar::GetMouseOverNotify(regaccessmode_enum mode, VARIANT_BOOL *enabled) -{ - COMTRY - { - LONG res; - CString str; - if(mode & RM_USER) { - CRegKey mga; - res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("MouseOverNotify")); - if(!str.IsEmpty()) { - REVOKE_SYS2(mode); - } - } - } - if(mode & (RM_SYSDOREAD)) { - CRegKey mga; - res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("MouseOverNotify")); - } - } - *enabled = (str == _T("1")) ? VARIANT_TRUE : VARIANT_FALSE; // Default value: false - } - COMCATCH(;) -} - - -STDMETHODIMP CMgaRegistrar::SetMouseOverNotify(regaccessmode_enum mode, VARIANT_BOOL enabled) -{ - COMTRY - { - CString str = (enabled == VARIANT_FALSE) ? _T("0") : _T("1"); - if(mode & RM_USER) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); - ERRTHROW( mga.SetStringValue( _T("MouseOverNotify"), str)); - } - if(mode & (RM_SYS | RM_TEST)) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); - if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("MouseOverNotify"), str)); - } - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::GetRealNmbFmtStr(regaccessmode_enum p_mode, BSTR *p_fmtStr) -{ - CHECK_OUT(p_fmtStr); - COMTRY - { - LONG res; - CString str; - if(p_mode & RM_USER) { - CRegKey mga; - res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("RealNmbFmtStr")); - if(!str.IsEmpty()) REVOKE_SYS2(p_mode); - } - } - if(p_mode & (RM_SYSDOREAD)) { - CRegKey mga; - res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("RealNmbFmtStr")); - } - } - CopyTo(str, p_fmtStr); - } - COMCATCH(;) - -} - -STDMETHODIMP CMgaRegistrar::SetRealNmbFmtStr(regaccessmode_enum p_mode, BSTR p_fmtStr) -{ - COMTRY - { - CString str = p_fmtStr; - if(p_mode & RM_USER) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); - ERRTHROW( mga.SetStringValue( _T("RealNmbFmtStr"), str)); - } - if(p_mode & (RM_SYS | RM_TEST)) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); - if(p_mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("RealNmbFmtStr"), str)); - } - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::GetTimeStamping(regaccessmode_enum p_mode, VARIANT_BOOL *p_enabled) -{ - COMTRY - { - LONG res; - CString str; - if(p_mode & RM_USER) { - CRegKey mga; - res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("TimeStamping")); - if(!str.IsEmpty()) { - REVOKE_SYS2(p_mode); - } - } - } - if(p_mode & (RM_SYSDOREAD)) { - CRegKey mga; - res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("TimeStamping")); - } - } - *p_enabled = (str == _T("1")) ? VARIANT_TRUE : VARIANT_FALSE; // Default value: false - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::SetTimeStamping(regaccessmode_enum p_mode, VARIANT_BOOL p_enabled) -{ - COMTRY - { - CString str = (p_enabled == VARIANT_FALSE) ? _T("0") : _T("1"); - if(p_mode & RM_USER) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); - ERRTHROW( mga.SetStringValue( _T("TimeStamping"), str)); - } - if(p_mode & (RM_SYS | RM_TEST)) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); - if(p_mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("TimeStamping"), str)); - } - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::GetNavigation(regaccessmode_enum p_mode, VARIANT_BOOL *p_enabled) -{ - COMTRY - { - LONG res; - CString str; - if(p_mode & RM_USER) { - CRegKey mga; - res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("Navigation")); - if(!str.IsEmpty()) { - REVOKE_SYS2(p_mode); - } - } - } - if(p_mode & (RM_SYSDOREAD)) { - CRegKey mga; - res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("Navigation")); - } - } - *p_enabled = (str == _T("0")) ? VARIANT_FALSE : VARIANT_TRUE; // Default value: true - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::SetNavigation(regaccessmode_enum p_mode, VARIANT_BOOL p_enabled) -{ - COMTRY - { - CString str = (p_enabled == VARIANT_FALSE) ? _T("0") : _T("1"); - if(p_mode & RM_USER) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); - ERRTHROW( mga.SetStringValue( _T("Navigation"), str)); - } - if(p_mode & (RM_SYS | RM_TEST)) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); - if(p_mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("Navigation"), str)); - } - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::GetUndoQueueSize(regaccessmode_enum p_mode, BSTR *p_qusz) -{ - CHECK_OUT(p_qusz); - COMTRY - { - LONG res; - CString str; - if(p_mode & RM_USER) { - CRegKey mga; - res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("UndoQueueSize")); - if(!str.IsEmpty()) REVOKE_SYS2(p_mode); - } - } - if(p_mode & (RM_SYSDOREAD)) { - CRegKey mga; - res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("UndoQueueSize")); - } - } - CopyTo(str, p_qusz); - } - COMCATCH(;) - -} - -STDMETHODIMP CMgaRegistrar::SetUndoQueueSize(regaccessmode_enum p_mode, BSTR p_qusz) -{ - COMTRY - { - CString str = p_qusz; - if(p_mode & RM_USER) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); - ERRTHROW( mga.SetStringValue( _T("UndoQueueSize"), str)); - } - if(p_mode & (RM_SYS | RM_TEST)) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); - if(p_mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("UndoQueueSize"), str)); - } - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::get_EdgeSmoothMode(regaccessmode_enum mode, edgesmoothmode_enum* smoothMode) -{ - COMTRY - { - LONG res; - CString str; - if(mode & RM_USER) { - CRegKey mga; - res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("EdgeSmoothMode")); - if(!str.IsEmpty()) { - REVOKE_SYS2(mode); - } - } - } - if(mode & (RM_SYSDOREAD)) { - CRegKey mga; - res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("EdgeSmoothMode")); - } - } - *smoothMode = (edgesmoothmode_enum)(str.IsEmpty() ? 2 : _tcstol(str, NULL, 10)); - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::put_EdgeSmoothMode(regaccessmode_enum mode, edgesmoothmode_enum smoothMode) -{ - COMTRY - { - CString str; - str.Format(_T("%d"), smoothMode); - if(mode & RM_USER) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); - ERRTHROW( mga.SetStringValue( _T("EdgeSmoothMode"), str)); - } - if(mode & (RM_SYS | RM_TEST)) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); - if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("EdgeSmoothMode"), str)); - } - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::get_FontSmoothMode(regaccessmode_enum mode, fontsmoothmode_enum* smoothMode) -{ - COMTRY - { - LONG res; - CString str; - if(mode & RM_USER) { - CRegKey mga; - res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("FontSmoothMode")); - if(!str.IsEmpty()) { - REVOKE_SYS2(mode); - } - } - } - if(mode & (RM_SYSDOREAD)) { - CRegKey mga; - res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - str = QueryValue(mga, _T("FontSmoothMode")); - } - } - *smoothMode = (fontsmoothmode_enum)(str.IsEmpty() ? 4 : _tcstol(str, NULL, 10)); - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::put_FontSmoothMode(regaccessmode_enum mode, fontsmoothmode_enum smoothMode) -{ - COMTRY - { - CString str; - str.Format(_T("%d"), smoothMode); - if(mode & RM_USER) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); - ERRTHROW( mga.SetStringValue( _T("FontSmoothMode"), str)); - } - if(mode & (RM_SYS | RM_TEST)) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); - if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("FontSmoothMode"), str)); - } - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::get_Paradigms(regaccessmode_enum mode, VARIANT *names) -{ - CHECK_OUT(names); - - COMTRY - { - CStringArray ret; - if(mode & RM_USER) { - CRegKey pars; - LONG res = pars.Open(HKEY_CURRENT_USER, rootreg+_T("\\Paradigms"), KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - for(int index = 0;; ++index) { - TCHAR name[1024]; - LONG err = RegEnumKey(pars, index, name, 1024); - if( err == ERROR_NO_MORE_ITEMS ) - break; - ERRTHROW( err ); - - REVOKE_SYS2(mode); - ret.Add(name); - } - - } - } - int retlen = ret.GetSize(); - - if(mode & RM_SYSDOREAD) { - CRegKey pars; - LONG res = pars.Open(HKEY_LOCAL_MACHINE, rootreg+_T("\\Paradigms"), KEY_READ | KEY_WOW64_32KEY); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - for(int index = 0;; ++index) { - TCHAR name[1024]; - LONG err = RegEnumKey(pars, index, name, 1024); - if( err == ERROR_NO_MORE_ITEMS ) - break; - ERRTHROW( err ); - int j; - for(j = 0; j < retlen; j++) { // Make sure, name is not present already, if yes, system copy is ignored - if(!ret[j].CompareNoCase(name)) break; - } - if(j != retlen) continue; - ret.Add(name); - } - - } - } - - - CopyTo(ret, names); - } - COMCATCH(;) -} - - -HRESULT GetMtaInfo(BSTR conn, BSTR *parname, BSTR *version, VARIANT *guid) { - COMTRY { - CComObjPtr paradigm; - COMTHROW( paradigm.CoCreateInstance(OLESTR("MGA.MgaMetaProject")) ); - ASSERT( paradigm != NULL ); - - COMTHROW( paradigm->Open(conn) ); - - COMTHROW( paradigm->get_Name(parname) ); - - COMTHROW( paradigm->get_Version(version) ); - - COMTHROW( paradigm->get_GUID(guid) ); - - COMTHROW( paradigm->Close() ); - } COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::RegisterParadigmFromDataDisp(BSTR connstr, regaccessmode_enum mode, BSTR *newname) -{ - return RegisterParadigmFromData( connstr, newname, mode); -} - -STDMETHODIMP CMgaRegistrar::RegisterParadigmFromData(BSTR connstr, BSTR *newname, regaccessmode_enum mode) -{ - CHECK_IN(connstr); - if(newname) CHECK_OUT(newname); - COMTRY { - CString conn = connstr; - CString connrecent; - // we have to parse it - if( conn.Left(4) == _T("XML=") ) - { - CString file = conn.Mid(4); - - conn = _T("MGA="); - conn += file; - - if( conn.Right(4).CompareNoCase(_T(".xml")) == 0 || - conn.Right(4).CompareNoCase(_T(".xmp")) == 0 ) { - conn.Delete(conn.GetLength() - 4, 4); - } - conn += _T(".mta"); -#define FILEPART(x) (((LPCTSTR)x)+4) - DWORD info = GetFileAttributes(FILEPART(conn)); - if(info != 0xFFFFFFFF ) { // save old version of paradigm under another name - if(info & FILE_ATTRIBUTE_DIRECTORY) COMTHROW(E_FILEOPEN); - try { - CComBstrObj name; // Format: name- - CComVariant prevguid; - CComBstrObj prevversion; - COMTHROW(GetMtaInfo(PutInBstr(conn), PutOut(name), PutOut(prevversion), PutOut(prevguid))); - CComBstrObj conn1; - if(QueryParadigm(name, PutOut(conn1), &prevguid, REGACCESS_PRIORITY) == S_OK && - conn1 == CComBSTR(conn)) { // if it was correctly registered under the previous nonextended name - GUID gg; - CopyTo(prevguid,gg); - CComBstrObj guidstr; - CopyTo(gg, guidstr); - connrecent = conn.Left(conn.GetLength()-4)+_T("-")+CString(PutInCString(guidstr))+_T(".mta"); - - bool sysmove = false, usermove = false; - conn1.Empty(); - if(QueryParadigm(name, PutOut(conn1), &prevguid, REGACCESS_SYSTEM) == S_OK && - conn1 == CComBSTR(conn)) { // if it was correctly registered in system - if(RegisterParadigm(name, PutInBstr(connrecent), prevversion, prevguid, REGACCESS_TEST) != S_OK) { - AfxMessageBox(_T("Cannot register this paradigm file\n") - _T("an existing '.mta' file with the same name\n") - _T("is registered in the system registry\n") - _T("which you are not permitted to change.\n") - _T("You need to change the name or location\n") - _T("of the new paradigm file")); - return E_INVALID_USAGE; - } - sysmove = true;; - } - conn1.Empty(); - if(QueryParadigm(name, PutOut(conn1), &prevguid, REGACCESS_USER) == S_OK && - conn1 == CComBSTR(conn)) { // if it was correctly registered in user - usermove = true; - } - - if(!MoveFileEx(FILEPART(conn), FILEPART(connrecent), MOVEFILE_REPLACE_EXISTING)) { - // n.b. can't do this because clients expect ParadigmName.mta - // conn = conn.Left(conn.GetLength() - 4) + _T("-") + CTime::GetCurrentTime().Format("%Y%m%d_%H%M%S") + _T(".mta"); - COMTHROW(E_FILEOPEN); - } - else { - if (sysmove) { - COMTHROW(RegisterParadigm(name, PutInBstr(connrecent), prevversion, prevguid, REGACCESS_SYSTEM)); - } - if (usermove) { - COMTHROW(RegisterParadigm(name, PutInBstr(connrecent), prevversion, prevguid, REGACCESS_USER)); - } - } - } - } catch(hresult_exception(&e)) { - AfxMessageBox(CString(_T("Failure saving previous version of paradigm\n")) + - e.what() + - (e.hr == E_BINFILE?_T(" [Binary paradigm file (.mta) incompatibility]\nPossible reason: GME version 6 changed the binary format of paradigms."):_T("")) + - _T("\nOld version will be overwritten")); - connrecent.Empty(); - } - } - - IMgaMetaParserPtr parser; - COMTHROW(parser.CreateInstance(L"MGA.MgaMetaParser")); - parser->__Parse(_bstr_t(file), _bstr_t(conn)); - } - - CComBstrObj name; - CComVariant guid; - CComBstrObj version; - COMTHROW(GetMtaInfo(PutInBstr(conn), PutOut(name), PutOut(version), PutOut(guid))); - if(!connrecent.IsEmpty()) { - CComBstrObj namer; - CComVariant guidr; - CComBstrObj versionr; - COMTHROW(GetMtaInfo(PutInBstr(connrecent), PutOut(namer), PutOut(versionr), PutOut(guidr))); - // We should change existing registration only here, if the new GUID != the old - } - - COMTHROW(RegisterParadigm( name, PutInBstr(conn), PutInBstr(version), guid, mode) ); - if(newname) MoveTo(name, newname); - } COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::RegisterParadigm(BSTR name, BSTR connstr, BSTR version, VARIANT guid, regaccessmode_enum mode) -{ - CString cver(version); - - COMTRY - { - GUID guid2; - if (guid.vt == (VT_UI1 | VT_ARRAY) && GetArrayLength(guid) == sizeof(GUID)) - { - CopyTo(guid, guid2); - } - else if (guid.vt == VT_BSTR) - { - CopyTo(guid.bstrVal, guid2); - } - else - COMTHROW(E_INVALIDARG); - - CComBstrObj guid3; - CopyTo(guid2, guid3); - - if(mode & RM_USER) { - CRegKey mga; - ERRTHROW(mga.Create(HKEY_CURRENT_USER, rootreg) ); - - CRegKey pars; - ERRTHROW( pars.Create(mga, _T("Paradigms")) ); - - CRegKey par; - ERRTHROW( par.Create(pars, CString(name)) ); - - - ERRTHROW( par.SetStringValue( _T("CurrentVersion"), PutInCString(guid3))); - if (!cver.IsEmpty()) { - ERRTHROW( par.SetStringValue( cver, PutInCString(guid3))); - } - CRegKey parg; - ERRTHROW( parg.Create(par, PutInCString(guid3)) ); - - ERRTHROW( parg.SetStringValue( _T("ConnStr"), CString(connstr))); - } - if(mode & (RM_SYS | RM_TEST)) { - CRegKey mga; - WIN32THROW(mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); - - CRegKey pars; - WIN32THROW( pars.Create(mga, _T("Paradigms"), 0, 0, KEY_READ | KEY_WRITE | KEY_WOW64_32KEY) ); - - CRegKey par; - - if (mode & RM_SYS) { - WIN32THROW( par.Create(pars, CString(name)) ); - CString gg = QueryValue(par, _T("GUID")); - CString gc = QueryValue(par, _T("ConnStr")); - par.DeleteValue(_T("GUID")); - par.DeleteValue(_T("ConnStr")); - if(!gc.IsEmpty() && !gg.IsEmpty()) { - CRegKey parg2; - WIN32THROW( parg2.Create(par, gg) ); - WIN32THROW( parg2.SetStringValue( _T("ConnStr"), gc) ); - } - - WIN32THROW( par.SetStringValue( _T("CurrentVersion"), PutInCString(guid3))); - if (!cver.IsEmpty()) { - WIN32THROW( par.SetStringValue( cver, PutInCString(guid3))); - } - CRegKey parg; - WIN32THROW( parg.Create(par, PutInCString(guid3)) ); - - WIN32THROW( parg.SetStringValue( _T("ConnStr"), CString(connstr))); - } else { - LONG res = par.Open(pars, CString(name)); - if(res != ERROR_SUCCESS && res != ERROR_FILE_NOT_FOUND) WIN32THROW(res); - } - } - if ((!(mode & RM_USER) || IsAssociated_hive(L"Mga.AddOn.ConstraintManager", name, HKEY_CURRENT_USER) != Tristate_Disabled) && - (!(mode & RM_SYS) || IsAssociated_hive(L"Mga.AddOn.ConstraintManager", name, HKEY_LOCAL_MACHINE) != Tristate_Disabled)) { - Associate(CComBSTR(L"Mga.AddOn.ConstraintManager"), name, mode); // no error checking - } - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::QueryParadigmAllGUIDs(BSTR parname, VARIANT *guidstrs, regaccessmode_enum mode) { - CHECK_OUT(guidstrs); - COLE2CT parname2(parname); - CString pname(parname2); - - COMTRY - { - CStringArray ret; - if(mode & RM_USER) { - CRegKey par; - LONG res = par.Open(HKEY_CURRENT_USER, rootreg+_T("\\Paradigms\\") + pname, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - for(int index = 0;; ++index) { - TCHAR name[1024]; - LONG err = RegEnumKey(par, index, name, 1024); - if( err == ERROR_NO_MORE_ITEMS ) - break; - ERRTHROW( err ); - - REVOKE_SYS2(mode); - ret.Add(name); - } - - } - } - int retlen = ret.GetSize(); - - if(mode & RM_SYSDOREAD) { - CRegKey par; - LONG res = par.Open(HKEY_LOCAL_MACHINE, rootreg+_T("\\Paradigms\\") + pname, KEY_READ | KEY_WOW64_32KEY); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - CString cur = QueryValue(par, _T("CurrentVersion")); - if(!cur.IsEmpty()) { // New style: Connection strings are stored under GUID subkeys - for(int index = 0;; ++index) { - TCHAR name[1024]; - LONG err = RegEnumKey(par, index, name, 1024); - if( err == ERROR_NO_MORE_ITEMS ) - break; - ERRTHROW( err ); - int j; - for(j = 0; j < retlen; j++) { // Make sure, name is not present already, if yes system copy is ignored - if(!ret[j].CompareNoCase(name)) break; - } - if(j != retlen) continue; - ret.Add(name); - } - } - else { - CString name = QueryValue(par, _T("GUID")); - int j; - for(j = 0; j < retlen; j++) { // Make sure, name is not present already, if yes system copy is ignored - if(!ret[j].CompareNoCase(name)) break; - } - if(j == retlen) ret.Add(name); - } - } - } - - - CopyTo(ret, guidstrs); - } - COMCATCH(;) -} - - -STDMETHODIMP CMgaRegistrar::QueryParadigm(BSTR parname, BSTR *connstr, VARIANT *guid, regaccessmode_enum mode) -{ - CHECK_OUT(connstr); -// CHECK_OUT(guid); - - COMTRY - { - CString pname = parname; - - CRegKey subk; - CString guidact; - - CComBstrObj inguidstr; - if(guid->vt != VT_EMPTY && guid->vt != VT_NULL) { - GUID g; - CopyTo(*guid, g); - CopyTo(g, inguidstr); -// if(inguidstr == L"{00000000-0000-0000-0000-000000000000}") inguidstr = NULL; - } - - LONG res; - - if(mode & RM_USER) { - CRegKey par; - res = par.Open(HKEY_CURRENT_USER, rootreg + _T("\\Paradigms\\") + pname, KEY_READ); - if(res == ERROR_SUCCESS) { - if(inguidstr == NULL) { - guidact = QueryValue(par, _T("CurrentVersion")); - if(guidact.IsEmpty()) res = ERROR_FILE_NOT_FOUND; - } - else - guidact = inguidstr; - } - if(res == ERROR_SUCCESS) res = subk.Open(par, guidact, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) mode = REGACCESS_USER; - } - - if(mode & RM_SYSDOREAD) { - CRegKey par; - res = par.Open(HKEY_LOCAL_MACHINE, rootreg + _T("\\Paradigms\\") + pname, KEY_READ | KEY_WOW64_32KEY); - if(res == ERROR_SUCCESS) { - CString cur = QueryValue(par, _T("CurrentVersion")); - if (cur.IsEmpty() && inguidstr == NULL) { - guidact = QueryValue(par, _T("GUID")); - if (inguidstr != NULL && inguidstr != CComBSTR(guidact)) - COMTHROW(E_NOTFOUND); - subk.Attach(par.Detach()); - } - else { - if (inguidstr == NULL) - guidact = cur; - else - guidact = inguidstr; - res = subk.Open(par, guidact, KEY_READ); - if (res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) - ERRTHROW(res); - } - } - } - if (subk == NULL) - { - CString error; - if (inguidstr) - error.Format(L"Paradigm '%s' with GUID '%s' is not registered.", static_cast(pname), - static_cast(inguidstr)); - else - error.Format(L"Paradigm '%s' is not registered.", static_cast(pname)); - SetErrorInfo(error); - return E_NOTFOUND; - } - - - CopyTo(QueryValue(subk, _T("ConnStr")), connstr); - - if(inguidstr == NULL) { - GUID g; - CopyTo(CComBSTR(guidact),g); - CopyTo(g, guid); - } - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::get_ParadigmGUIDString(regaccessmode_enum mode, BSTR parname, BSTR *guidstr) -{ - CHECK_OUT(guidstr); - COMTRY - { - CComBSTR connstr; - CComVariant guid; - HRESULT hr = QueryParadigm(parname, &connstr, &guid, mode); - if (FAILED(hr)) - return hr; - GUID g; - CopyTo(guid, g); - CopyTo(g, guidstr); - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::VersionFromGUID(BSTR name, VARIANT guid, BSTR *ver, regaccessmode_enum mode) -{ - CHECK_OUT(ver); - - bool found = false; - COMTRY - { - GUID gg; - CopyTo(guid,gg); - CComBstrObj guidbstr; - CopyTo(gg, guidbstr); - - LONG res; - - if(mode & RM_USER) { - CRegKey par; - res = par.Open(HKEY_CURRENT_USER, rootreg + _T("\\Paradigms\\")+name, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - mode = REGACCESS_USER; - for(int index = 0;; ++index) { - TCHAR name[512]; - DWORD namesize = sizeof(name) / sizeof(name[0]); - TCHAR value[512]; - DWORD valuesize = sizeof(value); - DWORD valtype; - - LONG err = RegEnumValue(par, index, name, &namesize, NULL, &valtype, (LPBYTE)value, &valuesize); - if( err == ERROR_NO_MORE_ITEMS ) - break; - ERRTHROW( err ); - if (valtype == REG_SZ) { - CString cver(value); - if (cver.Compare(PutInCString(guidbstr)) == 0) { - CString namestr(name); - if (namestr.CompareNoCase(_T("CurrentVersion")) != 0) { - found = true; - CopyTo(namestr, ver); - } - } - } - } - } - } - if(mode & (RM_SYSDOREAD)) { - CRegKey par; - res = par.Open(HKEY_LOCAL_MACHINE, rootreg + _T("\\Paradigms\\")+name, KEY_READ | KEY_WOW64_32KEY); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - for(int index = 0;; ++index) { - TCHAR name[512]; - DWORD namesize = sizeof(name) / sizeof(name[0]); - TCHAR value[512]; - DWORD valuesize = sizeof(value); - DWORD valtype; - - LONG err = RegEnumValue(par, index, name, &namesize, NULL, &valtype, (BYTE*)value, &valuesize); - if( err == ERROR_NO_MORE_ITEMS ) - break; - ERRTHROW( err ); - if (valtype == REG_SZ) { - CString cver(value); - if (cver.Compare(PutInCString(guidbstr)) == 0) { - CString namestr(name); - if (namestr.CompareNoCase(_T("CurrentVersion")) != 0) { - found = true; - CopyTo(namestr, ver); - } - } - } - } - } - } - if (!found) - { - SetErrorInfo(E_NOTFOUND); - return(E_NOTFOUND); - } - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::GUIDFromVersion(BSTR name, BSTR ver, VARIANT* guid, regaccessmode_enum mode) -{ - CHECK_OUT(guid); - - CString verstr = ver; - CString gstr; - - COMTRY - { - LONG res; - - if(mode & RM_USER) { - CRegKey par; - res = par.Open(HKEY_CURRENT_USER, rootreg + _T("\\Paradigms\\")+name, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - gstr = QueryValue(par, verstr); - if (!gstr.IsEmpty()) { - mode = REGACCESS_USER; - } - } - } - if(mode & (RM_SYSDOREAD)) { - CRegKey par; - res = par.Open(HKEY_LOCAL_MACHINE, rootreg + _T("\\Paradigms\\")+name, KEY_READ | KEY_WOW64_32KEY); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - gstr = QueryValue(par, verstr); - } - } - - if (gstr.IsEmpty()) { - CString error; - if (SysStringLen(ver)) - error.Format(L"Paradigm '%s' with version '%s' is not registered.", name, ver); - else - error.Format(L"Paradigm '%s' is not registered.", name); - SetErrorInfo(error); - return E_NOTFOUND; - } - - GUID g; - CopyTo(CComBSTR(gstr),g); - CopyTo(g, guid); - } - COMCATCH(;) -} - - -STDMETHODIMP CMgaRegistrar::UnregisterParadigmGUID(BSTR name, VARIANT v, regaccessmode_enum mode) -{ // it cannot be unregistered if it is the current version - COMTRY - { - GUID gg; - CopyTo(v,gg); - CComBstrObj guidbstr; - CopyTo(gg, guidbstr); - - if(mode & RM_USER) { - CRegKey par; - ERRTHROW( par.Open(HKEY_CURRENT_USER, rootreg + _T("\\Paradigms\\")+name) ); - CString cur = QueryValue(par, _T("CurrentVersion")); - if(cur.Compare(PutInCString(guidbstr)) == 0) { - COMTHROW(E_INVALID_USAGE); - } - - for(int index = 0;; ++index) { - TCHAR name[512]; - DWORD namesize = sizeof(name) / sizeof(name[0]); - TCHAR value[512]; - DWORD valuesize = sizeof(value); - DWORD valtype; - - LONG err = RegEnumValue(par, index, name, &namesize, NULL, &valtype, (BYTE*)value, &valuesize); - if( err == ERROR_NO_MORE_ITEMS ) - break; - ERRTHROW( err ); - if (valtype == REG_SZ) { - CString cver(value); - if (cver.Compare(PutInCString(guidbstr)) == 0) { - RegDeleteValue(par, name); - } - } - } - - ERRTHROW( par.RecurseDeleteKey(PutInCString(guidbstr)) ); - } - if(mode & (RM_SYS | RM_TEST)) { - CRegKey par; - ERRTHROW( par.Open(HKEY_LOCAL_MACHINE, rootreg + _T("\\Paradigms\\")+name, KEY_READ | KEY_WRITE | KEY_WOW64_32KEY) ); - CString cur = QueryValue(par, _T("CurrentVersion")); - if(cur.Compare(PutInCString(guidbstr)) == 0) { - COMTHROW(E_INVALID_USAGE); - } - if(mode & RM_SYS) { - ERRTHROW( par.RecurseDeleteKey(PutInCString(guidbstr)) ); - for(int index = 0;; ++index) { - TCHAR name[512]; - DWORD namesize = sizeof(name) / sizeof(name[0]); - TCHAR value[512]; - DWORD valuesize = sizeof(value); - DWORD valtype; - - LONG err = RegEnumValue(par, index, name, &namesize, NULL, &valtype, (BYTE*)value, &valuesize); - if( err == ERROR_NO_MORE_ITEMS ) - break; - ERRTHROW( err ); - if (valtype == REG_SZ) { - CString cver(value); - if (cver.Compare(PutInCString(guidbstr)) == 0) { - RegDeleteValue(par, name); - } - } - } - } - if(mode & RM_TEST) ERRTHROW( par.Open(par, PutInCString(guidbstr)) ); - } - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::UnregisterParadigm(BSTR name, regaccessmode_enum mode) -{ - COMTRY - { - if(mode & RM_USER) { - CRegKey pars; - LONG res = pars.Open(HKEY_CURRENT_USER, rootreg + _T("\\Paradigms")); - if(!res) res = pars.RecurseDeleteKey(CString(name)); - if(res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; - ERRTHROW(res); - } - if(mode & (RM_SYS | RM_TEST)) { - CRegKey pars; - LONG res = pars.Open(HKEY_LOCAL_MACHINE, rootreg + _T("\\Paradigms"), KEY_READ | KEY_WRITE | KEY_WOW64_32KEY); - if(!res) { - if(mode & RM_SYS) res = pars.RecurseDeleteKey(PutInCString(name)); - if(mode & RM_TEST) res = pars.Open(pars, PutInCString(name)); - } - if(res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; - ERRTHROW(res); - } - } - COMCATCH(;) -} - -// throws hresult_exception -void GetComponents_(HKEY hive, CStringArray& ret) { - CRegKey comps; - LONG res = comps.Open(hive, rootreg + _T("\\Components"), KEY_READ); - if (res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) - COMTHROW(HRESULT_FROM_WIN32(res)); - if (res == ERROR_SUCCESS) { - for (int index = 0;; ++index) { - TCHAR name[1024]; - LONG err = RegEnumKey(comps, index, name, 1024); - if (err == ERROR_NO_MORE_ITEMS) - break; - ERRTHROW(err); - - CRegKey comp; - err = comp.Open(comps, name, KEY_READ); - DWORD type2; - if (err == ERROR_SUCCESS) - err = comp.QueryDWORDValue(_T("Type"), type2); - if (err != ERROR_SUCCESS) - continue; - if((type2 & COMPONENTTYPE_SYSREGREF) != 0) { - continue; - } - // Make sure name is not present already - int j; - for (j = 0; j < ret.GetSize(); j++) { - if (!ret[j].CompareNoCase(name)) - break; - } - if (j != ret.GetSize()) - continue; - ret.Add(name); - } - } -} - -STDMETHODIMP CMgaRegistrar::get_Components(regaccessmode_enum mode, VARIANT *progids) -{ - CHECK_OUT(progids); - - COMTRY - { - CStringArray ret; - if (mode & REGACCESS_USER) - GetComponents_(HKEY_CURRENT_USER, ret); - if (mode & REGACCESS_SYSTEM) - GetComponents_(HKEY_LOCAL_MACHINE, ret); - CopyTo(ret, progids); - } - COMCATCH(;) -} - -template -void TokenizeParadigmString(const CString& paradigms, Functor& x) { - CStringList ret; - int curPos = 0; - CString token = paradigms.Tokenize(_T(" ;,\n\t"), curPos); - while (token != _T("")) { - x(token); - token = paradigms.Tokenize(_T(" ;,\n\t"), curPos); - } -} - -STDMETHODIMP CMgaRegistrar::RegisterComponent(BSTR progid, componenttype_enum type, BSTR desc, regaccessmode_enum mode) -{ - COMTRY - { - CComBstrObj paradigms(OLESTR("*")); - if(!(type & COMPONENTTYPE_PARADIGM_INDEPENDENT)) { - paradigms.Empty(); - CComPtr comp; - HRESULT hr = CreateMgaComponent(comp, progid); - if(!comp) - { - _bstr_t error; - GetErrorInfo(hr, error.GetAddress()); - if (!static_cast(error)) - error = L"Unknown error"; - throw_com_error(E_MGA_COMPONENT_ERROR, _bstr_t(L"Could not create: ") + progid + L": " + error); - } - COMTHROW(comp->get_Paradigm(PutOut(paradigms))); - } - if(mode & RM_USER) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); - CRegKey comps; - ERRTHROW( comps.Create(mga, _T("Components")) ); - CRegKey comp; - ERRTHROW( comp.Create(comps, PutInCString(progid)) ); - - ERRTHROW( comp.SetDWORDValue( _T("Type"), (DWORD)type)); - - ERRTHROW( comp.SetStringValue( _T("Description"), PutInCString(desc))); - if(paradigms.Length()) { - TokenizeParadigmString(PutInCString(paradigms), [&comp](const CString& par) { - ERRTHROW(comp.SetStringValue(_T("Paradigm"), par)); - }); - } - } - if(mode & (RM_SYS | RM_TEST)) { - CRegKey mga; - ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); - CRegKey comps; - ERRTHROW( comps.Create(mga, _T("Components")) ); - if(mode & RM_SYS) { - CRegKey comp; - ERRTHROW( comp.Create(comps, PutInCString(progid)) ); - - ERRTHROW( comp.SetDWORDValue( _T("Type"), (DWORD)type)); - - ERRTHROW( comp.SetStringValue( _T("Description"), PutInCString(desc))); - TokenizeParadigmString(PutInCString(paradigms), [&comp](const CString& par) { - ERRTHROW(comp.SetStringValue(_T("Paradigm"), par)); - }); - } - else { - CRegKey comp; - LONG res = comp.Open(comps, PutInCString(progid)); - if(res != ERROR_SUCCESS && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - } - } - } - COMCATCH(;) -} - -// FIXME: mode is ignored. It should be removed next interface-breaking change -STDMETHODIMP CMgaRegistrar::QueryComponent(BSTR progid, componenttype_enum *type, BSTR *desc, regaccessmode_enum mode) -{ - CHECK_OUT(type); - if(desc) CHECK_OUT(desc); - CString progidstr = PutInCString(progid); - - COMTRY - { - DWORD dwType = -1; - CString strDesc; - HKEY hives[] = { HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE }; - for (int i = 0; i < 2; i++) { - CRegKey comp; - LONG res = comp.Open(hives[i], rootreg+_T("\\Components\\")+progidstr, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - comp.QueryDWORDValue(_T("Type"), dwType); - ULONG count = 0; - res = comp.QueryStringValue(_T("Description"), NULL, &count); - if (strDesc == _T("") && res == ERROR_SUCCESS) { - CString ret; - if (comp.QueryStringValue(_T("Description"), ret.GetBufferSetLength(count), &count) == ERROR_SUCCESS) { - ret.ReleaseBuffer(); - strDesc = ret; - } - } - } - } - if (dwType == -1 || !(dwType & COMPONENTTYPE_ALL)) - COMTHROW(E_NOTFOUND); - - if (type) - *type = (componenttype_enum)dwType; - if (desc && strDesc != _T("")) - CopyTo(strDesc, desc); - return S_OK; - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::UnregisterComponent(BSTR progid, regaccessmode_enum mode) -{ - COMTRY - { -// if(mode & RM_USER) { - if(mode & (RM_USER | RM_SYS) ){ - CRegKey comps; - LONG res = comps.Open(HKEY_CURRENT_USER, rootreg + _T("\\Components")); - - DWORD type2 = 0; - if(!res) { - CRegKey comp; - res = comp.Open(comps, PutInCString(progid), KEY_READ); - if(!res) comp.QueryDWORDValue( _T("Type"), type2); - } - - if((mode & RM_USER) || (type2 & COMPONENTTYPE_SYSREGREF) != 0 ) { - if (!res) - res = comps.RecurseDeleteKey(PutInCString(progid)); - if (res == ERROR_FILE_NOT_FOUND) - res = ERROR_SUCCESS; - if (res != ERROR_SUCCESS) - WIN32THROW(res); - } - } - if(mode & (RM_SYS | RM_TEST)) { - CRegKey comps; - LONG res = comps.Open(HKEY_LOCAL_MACHINE, rootreg + _T("\\Components")); - if(!res) { - if(mode & RM_SYS) res = comps.RecurseDeleteKey(PutInCString(progid)); - if(mode & RM_TEST) res = comps.Open(comps, PutInCString(progid)); - } - if(res == ERROR_FILE_NOT_FOUND) - res = ERROR_SUCCESS; - if (res != ERROR_SUCCESS) - WIN32THROW(res); - } - } - COMCATCH(;) -} - - -STDMETHODIMP CMgaRegistrar::put_ComponentExtraInfo(regaccessmode_enum mode, - BSTR progid, BSTR name, BSTR newVal) { - CString progidstr = PutInCString(progid); - - COMTRY - { - if(mode & RM_USER) { - CRegKey comp; - LONG res = comp.Open(HKEY_CURRENT_USER, rootreg+_T("\\Components\\")+progidstr); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - DWORD type2; - ERRTHROW( comp.QueryDWORDValue( _T("Type"), type2)); - - if((type2 & COMPONENTTYPE_ALL)) { - if(!newVal) { ERRTHROW( comp.DeleteValue(PutInCString(name)) ); } - else { ERRTHROW( comp.SetStringValue( PutInCString(name), PutInCString(newVal))); } - } - } - } - if(mode & (RM_SYS | RM_TEST)) { - CRegKey comp; - LONG res = comp.Open(HKEY_LOCAL_MACHINE, rootreg+_T("\\Components\\")+progidstr); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - DWORD type2; - ERRTHROW( comp.QueryDWORDValue( _T("Type"), type2)); - - if((mode & RM_SYS) && (type2 & COMPONENTTYPE_ALL)) { - if(!newVal) { ERRTHROW( comp.DeleteValue(PutInCString(name)) ); } - else { ERRTHROW( comp.SetStringValue( PutInCString(name), PutInCString(newVal))); } - } - } - } - - } COMCATCH(;) -} - -// FIXME: mode is ignored. It should be removed next interface-breaking change -STDMETHODIMP CMgaRegistrar::get_ComponentExtraInfo(regaccessmode_enum mode, - BSTR progid, BSTR name, BSTR* pVal) { - CHECK_OUT(pVal); - CString progidstr = PutInCString(progid); - - COMTRY - { - HKEY hives[] = { HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE }; - for (int i = 0; i < 2; i++) { - CRegKey comp; - LONG res = comp.Open(hives[i], rootreg+_T("\\Components\\")+progidstr, KEY_READ); - if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - if(res == ERROR_SUCCESS) { - ULONG count = 0; - res = comp.QueryStringValue(PutInCString(name), NULL, &count); - if (res == ERROR_SUCCESS) { - CString ret; - if (comp.QueryStringValue(PutInCString(name), ret.GetBufferSetLength(count), &count) == ERROR_SUCCESS) { - ret.ReleaseBuffer(); - CopyTo(ret, pVal); - return S_OK; - } - } - } - } - return E_NOTFOUND; - } - COMCATCH(;) -} - - -STDMETHODIMP CMgaRegistrar::get_LocalDllPath(BSTR progid, BSTR* pVal) { - CHECK_OUT(pVal); - COMTRY - { - CString m_strProgId = PutInCString(progid); - CRegKey comp; - CString m_strClassId; - for(int i = 0; i < 10; i++) { - LONG res = comp.Open(HKEY_CLASSES_ROOT, m_strProgId + _T("\\CLSID"), KEY_READ); - if(res == ERROR_SUCCESS) { - m_strClassId = QueryValue(comp,_T("") ); - break; - } - else { - res = comp.Open(HKEY_CLASSES_ROOT, m_strProgId + _T("\\CurVer"), KEY_READ); - if(res != ERROR_SUCCESS) COMTHROW(E_NOTFOUND); - m_strProgId = QueryValue(comp, _T("") ); - comp.Close(); - } - } - if(m_strClassId.IsEmpty()) COMTHROW(E_NOTFOUND); - - LONG res = comp.Open(HKEY_CLASSES_ROOT, _T("CLSID\\") + m_strClassId + _T("\\InprocServer32"), KEY_READ); - CString m_strPath; - if(res == ERROR_SUCCESS) { - m_strPath = QueryValue(comp, _T("") ); - if (m_strPath == _T("mscoree.dll")) { - CString data; - ULONG count = 1024; - if (comp.QueryStringValue(_T("CodeBase"), data.GetBufferSetLength(count), &count) == ERROR_SUCCESS) { - data.ReleaseBuffer(); - m_strPath = data; - m_strPath = m_strPath.Right(m_strPath.GetLength() - 8); - m_strPath.Replace('/', '\\'); - } else { - count = 1024; - if (comp.QueryStringValue(_T("Assembly"), data.GetBufferSetLength(count), &count) == ERROR_SUCCESS) { - data.ReleaseBuffer(); - m_strPath = _T("GAC: "); - m_strPath += data; - } - } - } else { - // VS2012 puts quotes around the dll path - if (m_strPath[0] == L'\"') { - m_strPath = m_strPath.Right(m_strPath.GetLength() - 1); - } - if (m_strPath[m_strPath.GetLength() - 1] == L'\"') { - m_strPath = m_strPath.Left(m_strPath.GetLength() - 1); - } - } - } - CopyTo(m_strPath, pVal); - - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::get_AssociatedComponents(BSTR paradigm, - componenttype_enum type, regaccessmode_enum mode, VARIANT *progids) -{ - CHECK_OUT(progids); - type = (componenttype_enum)(type & COMPONENTTYPE_ALL); - - COMTRY - { - CStringArray ret; - - CString paradigmstr = paradigm; - - CStringArray components; - if (mode & REGACCESS_USER) - GetComponents_(HKEY_CURRENT_USER, components); - if (mode & REGACCESS_SYSTEM) - GetComponents_(HKEY_LOCAL_MACHINE, components); - for (int i = 0; i < components.GetSize(); i++) { - componenttype_enum comptype = COMPONENTTYPE_NONE; - PutInBstr progid(components.GetAt(i)); - CComBSTR desc; - COMTHROW(QueryComponent(progid, &comptype, &desc, REGACCESS_BOTH)); - if ((comptype & type) && IsAssociated_regaccess(components.GetAt(i), paradigmstr, mode)) { - ret.Add(components.GetAt(i)); - } - } - CopyTo(ret, progids); - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::get_AssociatedParadigms(BSTR progid, regaccessmode_enum mode, VARIANT *paradigms) -{ - CHECK_OUT(paradigms); - - COMTRY - { - - CStringArray ret; - CString progidstr = PutInCString(progid); - - VARIANT all_paradigms_; - VariantInit(&all_paradigms_); - COMTHROW(get_Paradigms(REGACCESS_BOTH, &all_paradigms_)); - ATL::CComSafeArray all_paradigms; - all_paradigms.Attach(all_paradigms_.parray); - ASSERT(all_paradigms.GetDimensions() == 1); - for (LONG i = all_paradigms.GetLowerBound(); i <= all_paradigms.GetUpperBound(); i++) { - BSTR paradigm = all_paradigms.GetAt(i); - if (IsAssociated_regaccess(progidstr, PutInCString(paradigm), mode)) { - ret.Add(static_cast(PutInCString(paradigm))); - } - } - - CopyTo(ret, paradigms); - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::Associate(BSTR progid, BSTR paradigm, regaccessmode_enum mode) -{ - COLE2CT progid2(progid); - CString pname(progid2); - COMTRY - { - bool somethingdone = false; - if(mode & RM_USER) { - CRegKey comp; - LONG res = comp.Open(HKEY_CURRENT_USER, rootreg + _T("\\Components\\") + pname); - CRegKey assocs; - if(res == ERROR_FILE_NOT_FOUND) { // try to create a shadow registry - CRegKey comp1, mga; - res = comp1.Open(HKEY_LOCAL_MACHINE, rootreg + _T("\\Components\\") + pname, KEY_READ); - if(!res) res = mga.Create(HKEY_CURRENT_USER, rootreg); - CRegKey comps; - if(!res) res = ( comps.Create(mga, _T("Components")) ); - if(!res) res = ( comp.Create(comps, pname) ); - } - if(res == ERROR_SUCCESS) res = assocs.Create(comp, _T("Associated")); - if(!res) assocs.SetStringValue( PutInCString(paradigm), _T("")); - if(!res) somethingdone = true; - if(res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; - ERRTHROW(res); - } - if(mode & (RM_SYS | RM_TEST)) { - CRegKey comp; - LONG res = comp.Open(HKEY_LOCAL_MACHINE, rootreg + _T("\\Components\\") + pname); - if(mode & RM_SYS) { - CRegKey assocs; - if(!res) res = assocs.Create(comp, _T("Associated")); - if(!res) res = assocs.SetStringValue( PutInCString(paradigm), _T("")); - } - else { - CRegKey assocs; - LONG res = assocs.Open(comp, _T("Associated")); - if(res != ERROR_SUCCESS && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); - } - if(!res) somethingdone = true; - } - if(!somethingdone) COMTHROW(E_NOTFOUND); - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::Disassociate(BSTR progid, BSTR paradigm, regaccessmode_enum mode) -{ - COLE2CT progid2(progid); - CString pname(progid2); - COMTRY - { - if(mode & RM_USER) { - CRegKey comp; - LONG res = comp.Open(HKEY_CURRENT_USER, rootreg + _T("\\Components\\") + pname); - if (res == ERROR_FILE_NOT_FOUND) { - CRegKey comp1, mga; - res = comp1.Open(HKEY_LOCAL_MACHINE, rootreg + _T("\\Components\\") + pname, KEY_READ); - if(!res) res = mga.Create(HKEY_CURRENT_USER, rootreg); - CRegKey comps; - if(!res) res = ( comps.Create(mga, _T("Components")) ); - if(!res) res = ( comp.Create(comps, pname) ); - } - CRegKey assocs; - if(!res) res = assocs.Open(comp, _T("Associated")); - if (res == ERROR_FILE_NOT_FOUND) - res = assocs.Create(comp, _T("Associated")); - if (!res) - res = assocs.SetStringValue(PutInCString(paradigm), _T("Disabled")); - if(res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; - ERRTHROW(res); - } - if(mode & (RM_SYS | RM_TEST)) { - CRegKey comp; - LONG res = comp.Open(HKEY_LOCAL_MACHINE, rootreg + _T("\\Components\\") + pname); - CRegKey assocs; - if(!res) res = assocs.Open(comp, _T("Associated")); - if(mode & RM_SYS) { - if(!res) res = assocs.DeleteValue(PutInCString(paradigm)); - } - if(res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; - ERRTHROW(res); - } - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::IsAssociated(BSTR progid, BSTR paradigm, - VARIANT_BOOL *is_ass, VARIANT_BOOL *can_ass, regaccessmode_enum mode){ - CHECK_IN(progid); - CHECK_OUT(paradigm); - CString progidstr = PutInCString(progid); - CString parc = PutInCString(paradigm); - - COMTRY - { - componenttype_enum type; - - COMTHROW(QueryComponent(progid, &type, NULL, REGACCESS_PRIORITY)); - - if (is_ass) *is_ass = IsAssociated_regaccess(progidstr, parc, mode) ? VARIANT_TRUE : VARIANT_FALSE; - - if (can_ass) *can_ass = VARIANT_FALSE; - VARIANT_BOOL can = VARIANT_FALSE; - CComBSTR pars; - get_ComponentExtraInfo(mode,progid,CComBSTR(L"Paradigm"), &pars); - if(!pars && !(type & COMPONENTTYPE_SCRIPT)) { - CComPtr comp; - CreateMgaComponent(comp, progid); - if(!comp) COMTHROW(E_NOTFOUND); - COMTHROW(comp->get_Paradigm(&pars)); - put_ComponentExtraInfo(REGACCESS_BOTH, progid, CComBSTR(L"Paradigm"), pars); // just try - } - if(!pars) { - can = type & COMPONENTTYPE_PARADIGM_INDEPENDENT ? VARIANT_TRUE : VARIANT_FALSE; - } - else if(!wcscmp(pars, L"*")) { - can = VARIANT_TRUE; - } - else { - can = VARIANT_FALSE; - TokenizeParadigmString(PutInCString(pars), [¶digm, &can](const CString& paradigm2) { - if (static_cast(PutInCString(paradigm)) == paradigm2) - can = VARIANT_TRUE; - }); - } - if(can_ass) *can_ass = can; - - } - COMCATCH(;) -} - - -// --- Actions -typedef HRESULT (STDAPICALLTYPE *CTLREGPROC)(); - -STDMETHODIMP CMgaRegistrar::RegisterComponentLibrary(BSTR path, regaccessmode_enum mode) -{ - COMTRY - { - HMODULE hModule = LoadLibrary(CString(path)); - if( hModule == 0 ) { - HR_THROW(HRESULT_FROM_WIN32(GetLastError())); - } - - CTLREGPROC DLLRegisterServer = - (CTLREGPROC)::GetProcAddress(hModule, "DllRegisterServer"); - - if( DLLRegisterServer == NULL ) - { - FreeLibrary(hModule); - using namespace MgaDotNetServices; - _RegistrarPtr reg; - COMTHROW(reg.CreateInstance(L"MGA.DotNetRegistrar")); - //COMTHROW(reg.CreateInstance(L"{0BB0C371-6835-4F09-A156-0BD8E3DF8216}", NULL, CLSCTX_INPROC)); - reg->Register(_bstr_t(path)); - - return S_OK; - } - else - { - //c++ dll: - COMTHROW( DLLRegisterServer() ); - FreeLibrary(hModule); - } - - - CComObjPtr typelib; - COMTHROW( LoadTypeLibEx(path, REGKIND_REGISTER, PutOut(typelib)) ); - - UINT index = typelib->GetTypeInfoCount(); - while( index-- > 0 ) - { - CComObjPtr typeinfo; - COMTHROW( typelib->GetTypeInfo(index, PutOut(typeinfo)) ); - - TYPEATTR *typeattr = NULL; - COMTHROW( typeinfo->GetTypeAttr(&typeattr) ); - ASSERT( typeattr != NULL ); - - try - { - if( typeattr->typekind == TKIND_COCLASS ) - { - CComPtr component; - // if( SUCCEEDED(typeinfo->CreateInstance(NULL, - // __uuidof(IMgaComponent), (void**)PutOut(component))) ) - if (SUCCEEDED(CreateMgaComponent(component, typeattr->guid))) - { - CComBstrObj desc; - COMTHROW( component->get_ComponentName(PutOut(desc)) ); - - componenttype_enum type; - COMTHROW( component->get_ComponentType(&type) ); - - LPOLESTR olestr; - COMTHROW( ProgIDFromCLSID(typeattr->guid, &olestr) ); - CComBstrObj progid(olestr); - { - LPOLESTR pp = olestr + wcslen(olestr) - 2; - if(wcslen(olestr) > 2 && - pp[0] == '.' && - isdigit(pp[1]) ) { - pp[0] = 0; - CLSID tempGUID; - HRESULT hr = CLSIDFromProgID(olestr, &tempGUID); - if(hr == S_OK && tempGUID == typeattr->guid) { - progid = CComBstrObj(olestr); - } - } - } - - COMTHROW( RegisterComponent(progid, type, desc, mode) ); - CoTaskMemFree(olestr); - - CString paradigms; - COMTHROW( component->get_Paradigm(PutOut(paradigms)) ); - - TokenizeParadigmString(paradigms, [this,&mode,&progid](const CString& par){ - COMTHROW(Associate(progid, PutInBstr(par), mode)); - }); - } - } - - typeinfo->ReleaseTypeAttr(typeattr); - } - catch(hresult_exception &) - { - typeinfo->ReleaseTypeAttr(typeattr); - throw; - } - } - } - COMCATCH(;) -} - -STDMETHODIMP CMgaRegistrar::UnregisterComponentLibrary(BSTR path, regaccessmode_enum mode) -{ - COMTRY - { - CComObjPtr typelib; - COMTHROW( LoadTypeLibEx(path, REGKIND_NONE, PutOut(typelib)) ); - - UINT index = typelib->GetTypeInfoCount(); - while( index) //WAS: while( --index >= 0 ) // was an infinite loop with UINT - { - --index; - CComObjPtr typeinfo; - COMTHROW( typelib->GetTypeInfo(index, PutOut(typeinfo)) );// index parameter with the range of 0 to GetTypeInfoCount() –1. - - TYPEATTR *typeattr = NULL; - COMTHROW( typeinfo->GetTypeAttr(&typeattr) ); - ASSERT( typeattr != NULL ); - - try - { - if( typeattr->typekind == TKIND_COCLASS ) - { - LPOLESTR olestr; - if( SUCCEEDED(ProgIDFromCLSID(typeattr->guid, &olestr)) ) - { - CComBstrObj progid(olestr); - COMTHROW( UnregisterComponent(progid, mode) ); - } - } - - typeinfo->ReleaseTypeAttr(typeattr); - } - catch(hresult_exception &) - { - typeinfo->ReleaseTypeAttr(typeattr); - throw; - } - } - - // TODO: unregister the type library - } - COMCATCH(;) -} +#include "stdafx.h" +#include "MgaRegistrar.h" +#include "atlconv.h" +#include "CommonComponent.h" +#include "Parser.h" + +#import "mscorlib.tlb" +#import "libid:5f45c5d6-4e11-42fc-a558-cfa0b6c7bea6" // MgaDotNetServices + +#include "atlsafe.h" + +#ifdef _DEBUG +void ERRTHROW(LONG err) +{ + VERIFYTHROW( err == ERROR_SUCCESS ); +} +#else +#define ERRTHROW(FUNC) \ +{ \ + VERIFYTHROW( (FUNC) == ERROR_SUCCESS ); \ +} +#endif + +void WIN32THROW(LONG err) +{ + if (err != ERROR_SUCCESS) + HR_THROW(HRESULT_FROM_WIN32(err)); +} + +const CString rootreg(_T("SOFTWARE\\GME")); + + +CString QueryValue(CRegKey &key, const TCHAR *name) +{ + CString buffer; + TCHAR *bufp = buffer.GetBuffer(4096); + ULONG buflen = 4095; + LONG err = key.QueryStringValue( name, bufp, &buflen); + if( err != ERROR_SUCCESS ) { + buflen = 0; + if(err != ERROR_FILE_NOT_FOUND) ERRTHROW(err); + } + ASSERT( 0 <= buflen && buflen < 4096 ); + bufp[buflen] = _T('\0'); + buffer.ReleaseBuffer(); + + return buffer; +} + +// --------------------------- CMgaRegistrar + +#define RM_USER 1 +#define RM_SYS 2 +#define RM_SYS2 4 +#define RM_BOTH 3 +#define RM_TEST 8 +#define RM_PRIO (RM_SYS2 | RM_USER) +#define RM_SYSDOREAD (RM_SYS2 | RM_SYS) + +// For read operations: USER, SYS, PRIO +// For multi-return read operations: USER, SYS, BOTH, PRIO +// For write operations: USER, SYS, BOTH, TEST + +void REVOKE_SYS2(regaccessmode_enum &mode) { *(int *)&mode &= ~RM_SYS2; } + +enum Tristate_t { + Tristate_Enabled, + Tristate_Disabled, + Tristate_Not_Specified, +}; + +bool Combine_Tristate(Tristate_t user, Tristate_t system, bool default_ = false) { + if (user != Tristate_Not_Specified) { + return user == Tristate_Enabled; + } + if (system != Tristate_Not_Specified) { + return system == Tristate_Enabled; + } + return default_; +} + +Tristate_t IsAssociated_hive(const CString& progidstr, const CString& paradigmstr, HKEY hive) { + CRegKey acomp; + + if (acomp.Open(hive, rootreg + _T("\\Components\\") + progidstr + _T("\\Associated"), KEY_READ) != ERROR_SUCCESS) { + return Tristate_Not_Specified; + } + ULONG count = 0; + DWORD res = acomp.QueryValue(paradigmstr, NULL, NULL, &count); + if (res != ERROR_SUCCESS) { + return Tristate_Not_Specified; + } + CString val; + if (acomp.QueryStringValue(paradigmstr, val.GetBufferSetLength(count), &count) == ERROR_SUCCESS) { + val.ReleaseBuffer(); + if (val == _T("Disabled")) { + return Tristate_Disabled; + } + } + return Tristate_Enabled; +} + +bool IsAssociated_regaccess(const CString& progidstr, const CString& paradigmstr, regaccessmode_enum mode) { + if (mode & REGACCESS_BOTH) { + return Combine_Tristate( + IsAssociated_hive(progidstr, paradigmstr, HKEY_CURRENT_USER), + IsAssociated_hive(progidstr, paradigmstr, HKEY_LOCAL_MACHINE)); + } else if (mode & REGACCESS_USER) { + return IsAssociated_hive(progidstr, paradigmstr, HKEY_CURRENT_USER) == Tristate_Enabled; + } else if (mode & REGACCESS_SYSTEM) { + return IsAssociated_hive(progidstr, paradigmstr, HKEY_LOCAL_MACHINE) == Tristate_Enabled; + } + return false; +} + +STDMETHODIMP CMgaRegistrar::get_IconPath(regaccessmode_enum mode, BSTR *path) +{ + CHECK_OUT(path); + + COMTRY + { + LONG res; + CString str; + if(mode & RM_USER) { + CRegKey mga; + res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("IconPath")); + str.TrimRight(_T(" ;,\t")); + if(!str.IsEmpty()) REVOKE_SYS2(mode); + } + } + if(mode & (RM_SYSDOREAD)) { + CRegKey mga; + res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + CString str2; + if(res == ERROR_SUCCESS) { + str2 = QueryValue(mga, _T("IconPath")); + } + if (str2 == "") { + str2 = "$PARADIGMDIR\\icons;$PROJECTDIR\\icons"; + } + str2.TrimLeft(_T(" ;,\t")); + if(!str.IsEmpty() && !str2.IsEmpty()) + { + str += _T(";"); + str += str2; + } + else + str = str2; + } + CopyTo(str, path); + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::put_IconPath(regaccessmode_enum mode, BSTR path) +{ + COMTRY + { + CString str = path; + if(mode & RM_USER) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); + ERRTHROW( mga.SetStringValue( _T("IconPath"), str )); + } + if(mode & (RM_SYS | RM_TEST)) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); + if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("IconPath"), str)); + } + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::get_ShowMultipleView(regaccessmode_enum mode, VARIANT_BOOL *enabled) +{ + COMTRY + { + LONG res; + CString str; + if(mode & RM_USER) { + CRegKey mga; + res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("ShowMultipleView")); + if(!str.IsEmpty()) { + REVOKE_SYS2(mode); + } + } + } + if(mode & (RM_SYSDOREAD)) { + CRegKey mga; + res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("ShowMultipleView")); + } + } + *enabled = (str == _T("1")) ? VARIANT_TRUE : VARIANT_FALSE; // Default value: false + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::put_ShowMultipleView(regaccessmode_enum mode, VARIANT_BOOL enabled) +{ + COMTRY + { + CString str = (enabled == VARIANT_FALSE) ? _T("0") : _T("1"); + if(mode & RM_USER) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); + ERRTHROW( mga.SetStringValue( _T("ShowMultipleView"), str)); + } + if(mode & (RM_SYS | RM_TEST)) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); + if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("ShowMultipleView"), str)); + } + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::get_EventLoggingEnabled(regaccessmode_enum mode, VARIANT_BOOL *enabled) +{ + COMTRY + { + LONG res; + CString str; + if(mode & RM_USER) { + CRegKey mga; + res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("EventLoggingEnabled")); + if(!str.IsEmpty()) { + REVOKE_SYS2(mode); + } + } + } + if(mode & (RM_SYSDOREAD)) { + CRegKey mga; + res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("EventLoggingEnabled")); + } + } + *enabled = (str == _T("1")) ? VARIANT_TRUE : VARIANT_FALSE; // Default value: false + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::put_EventLoggingEnabled(regaccessmode_enum mode, VARIANT_BOOL enabled) +{ + COMTRY + { + CString str = (enabled == VARIANT_FALSE) ? _T("0") : _T("1"); + if(mode & RM_USER) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); + ERRTHROW( mga.SetStringValue( _T("EventLoggingEnabled"), str)); + } + if(mode & (RM_SYS | RM_TEST)) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); + if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("EventLoggingEnabled"), str)); + } + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::get_AutosaveEnabled(regaccessmode_enum mode, VARIANT_BOOL *enabled) +{ + COMTRY + { + LONG res; + CString str; + if(mode & RM_USER) { + CRegKey mga; + res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("AutosaveEnabled")); + if(!str.IsEmpty()) { + REVOKE_SYS2(mode); + } + } + } + if(mode & (RM_SYSDOREAD)) { + CRegKey mga; + res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("AutosaveEnabled")); + } + } + *enabled = (str == _T("1")) ? VARIANT_TRUE : VARIANT_FALSE; // Default value: false + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::put_AutosaveEnabled(regaccessmode_enum mode, VARIANT_BOOL enabled) +{ + COMTRY + { + CString str = (enabled == VARIANT_FALSE) ? _T("0") : _T("1"); + if(mode & RM_USER) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); + ERRTHROW( mga.SetStringValue( _T("AutosaveEnabled"), str)); + } + if(mode & (RM_SYS | RM_TEST)) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); + if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("AutosaveEnabled"), str)); + } + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::get_AutosaveFreq(regaccessmode_enum mode, long *secs) +{ + COMTRY + { + LONG res; + CString str; + if(mode & RM_USER) { + CRegKey mga; + res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("AutosaveFreq")); + if(!str.IsEmpty()) { + REVOKE_SYS2(mode); + } + } + } + if(mode & (RM_SYSDOREAD)) { + CRegKey mga; + res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("AutosaveFreq")); + } + } + if (_stscanf((LPCTSTR)str, _T("%ld"), secs) != 1) { + *secs = 60; // Default value: 1 minute + } + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::put_AutosaveFreq(regaccessmode_enum mode, long secs) +{ + COMTRY + { + CString str; + str.Format(_T("%ld"), secs); + if(mode & RM_USER) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); + ERRTHROW( mga.SetStringValue( _T("AutosaveFreq"), str)); + } + if(mode & (RM_SYS | RM_TEST)) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); + if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("AutosaveFreq"), str)); + } + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::get_AutosaveUseDir(regaccessmode_enum mode, VARIANT_BOOL *enabled) +{ + COMTRY + { + LONG res; + CString str; + if(mode & RM_USER) { + CRegKey mga; + res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("AutosaveUseDir")); + if(!str.IsEmpty()) { + REVOKE_SYS2(mode); + } + } + } + if(mode & (RM_SYSDOREAD)) { + CRegKey mga; + res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("AutosaveUseDir")); + } + } + *enabled = (str == _T("1")) ? VARIANT_TRUE : VARIANT_FALSE; // Default value: false + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::put_AutosaveUseDir(regaccessmode_enum mode, VARIANT_BOOL enabled) +{ + COMTRY + { + CString str = (enabled == VARIANT_FALSE) ? _T("0") : _T("1"); + if(mode & RM_USER) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); + ERRTHROW( mga.SetStringValue( _T("AutosaveUseDir"), str)); + } + if(mode & (RM_SYS | RM_TEST)) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); + if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("AutosaveUseDir"), str)); + } + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::get_AutosaveDir(regaccessmode_enum mode, BSTR *dir) +{ + CHECK_OUT(dir); + + COMTRY + { + LONG res; + CString str; + if(mode & RM_USER) { + CRegKey mga; + res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("AutosaveDir")); + } + } + if(mode & (RM_SYSDOREAD)) { + CRegKey mga; + res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("AutosaveDir")); + } + } + CopyTo(str, dir); + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::put_AutosaveDir(regaccessmode_enum mode, BSTR dir) +{ + COMTRY + { + CString str = dir; + if(mode & RM_USER) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); + ERRTHROW( mga.SetStringValue( _T("AutosaveDir"), str)); + } + if(mode & (RM_SYS | RM_TEST)) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); + if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("AutosaveDir"), str)); + } + } + COMCATCH(;) +} + + +STDMETHODIMP CMgaRegistrar::get_ExternalEditorEnabled(regaccessmode_enum mode, VARIANT_BOOL *enabled) +{ + COMTRY + { + LONG res; + CString str; + if(mode & RM_USER) { + CRegKey mga; + res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("ExternalEditorEnabled")); + if(!str.IsEmpty()) { + REVOKE_SYS2(mode); + } + } + } + if(mode & (RM_SYSDOREAD)) { + CRegKey mga; + res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("ExternalEditorEnabled")); + } + } + *enabled = (str == _T("1")) ? VARIANT_TRUE : VARIANT_FALSE; // Default value: false + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::put_ExternalEditorEnabled(regaccessmode_enum mode, VARIANT_BOOL enabled) +{ + COMTRY + { + CString str = (enabled == VARIANT_FALSE) ? _T("0") : _T("1"); + if(mode & RM_USER) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); + ERRTHROW( mga.SetStringValue( _T("ExternalEditorEnabled"), str)); + } + if(mode & (RM_SYS | RM_TEST)) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); + if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("ExternalEditorEnabled"), str)); + } + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::get_ExternalEditor(regaccessmode_enum mode, BSTR *path) +{ + CHECK_OUT(path); + + COMTRY + { + LONG res; + CString str; + if(mode & RM_USER) { + CRegKey mga; + res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("ExternalEditor")); + } + } + if(mode & (RM_SYSDOREAD)) { + CRegKey mga; + res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("ExternalEditor")); + } + } + CopyTo(str, path); + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::put_ExternalEditor(regaccessmode_enum mode, BSTR path) +{ + COMTRY + { + CString str = path; + if(mode & RM_USER) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); + ERRTHROW( mga.SetStringValue( _T("ExternalEditor"), str)); + } + if(mode & (RM_SYS | RM_TEST)) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); + if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("ExternalEditor"), str)); + } + } + COMCATCH(;) +} + + +STDMETHODIMP CMgaRegistrar::get_UseAutoRouting(regaccessmode_enum mode, VARIANT_BOOL *enabled) +{ + COMTRY + { + LONG res; + CString str; + if(mode & RM_USER) { + CRegKey mga; + res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("UseAutoRouting")); + if(!str.IsEmpty()) { + REVOKE_SYS2(mode); + } + } + } + if(mode & (RM_SYSDOREAD)) { + CRegKey mga; + res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("UseAutoRouting")); + } + } + *enabled = (str == _T("0")) ? VARIANT_FALSE : VARIANT_TRUE; // Default value: true + } + COMCATCH(;) +} + + +STDMETHODIMP CMgaRegistrar::put_UseAutoRouting(regaccessmode_enum mode, VARIANT_BOOL enabled) +{ + COMTRY + { + CString str = (enabled == VARIANT_FALSE) ? _T("0") : _T("1"); + if(mode & RM_USER) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); + ERRTHROW( mga.SetStringValue( _T("UseAutoRouting"), str)); + } + if(mode & (RM_SYS | RM_TEST)) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); + if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("UseAutoRouting"), str)); + } + } + COMCATCH(;) +} + + +STDMETHODIMP CMgaRegistrar::get_LabelAvoidance(regaccessmode_enum mode, VARIANT_BOOL *enabled) +{ + COMTRY + { + LONG res; + CString str; + if(mode & RM_USER) { + CRegKey mga; + res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("LabelAvoidance")); + if(!str.IsEmpty()) { + REVOKE_SYS2(mode); + } + } + } + if(mode & (RM_SYSDOREAD)) { + CRegKey mga; + res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("LabelAvoidance")); + } + } + *enabled = (str == _T("1")) ? VARIANT_TRUE : VARIANT_FALSE; // Default value: false + } + COMCATCH(;) +} + + +STDMETHODIMP CMgaRegistrar::put_LabelAvoidance(regaccessmode_enum mode, VARIANT_BOOL enabled) +{ + COMTRY + { + CString str = (enabled == VARIANT_FALSE) ? _T("0") : _T("1"); + if(mode & RM_USER) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); + ERRTHROW( mga.SetStringValue( _T("LabelAvoidance"), str)); + } + if(mode & (RM_SYS | RM_TEST)) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); + if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("LabelAvoidance"), str)); + } + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::get_ScriptEngine(regaccessmode_enum mode, BSTR *path) { + CHECK_OUT(path); + + COMTRY + { + LONG res; + CString str; + if(mode & RM_USER) { + CRegKey mga; + res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("ScriptEngine")); + str.TrimRight(_T(" ;,\t")); + if(!str.IsEmpty()) REVOKE_SYS2(mode); + } + } + if(mode & (RM_SYSDOREAD)) { + CRegKey mga; + res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + CString str2 = QueryValue(mga, _T("ScriptEngine")); + str2.TrimLeft(_T(" ;,\t")); + if(!str.IsEmpty() && !str2.IsEmpty()) str += _T(";"); + str += str2; + } + } + CopyTo(str, path); + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::put_ScriptEngine(regaccessmode_enum mode, BSTR path) { + COMTRY + { + CString str = path; + if(mode & RM_USER) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); + ERRTHROW( mga.SetStringValue(_T("ScriptEngine"), str) );//z7 + } + if(mode & (RM_SYS | RM_TEST)) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); + if(mode & RM_SYS) ERRTHROW( mga.SetStringValue(_T("ScriptEngine"), str) );//z7 + } + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::GetDefZoomLevel(regaccessmode_enum p_mode, BSTR *p_zlev) +{ + CHECK_OUT(p_zlev); + COMTRY + { + LONG res; + CString str; + if(p_mode & RM_USER) { + CRegKey mga; + res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("DefaultZoomLevel")); + if(!str.IsEmpty()) REVOKE_SYS2(p_mode); + } + } + if(p_mode & (RM_SYSDOREAD)) { + CRegKey mga; + res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("DefaultZoomLevel")); + } + } + CopyTo(str, p_zlev); + } + COMCATCH(;) + +} + +STDMETHODIMP CMgaRegistrar::SetDefZoomLevel(regaccessmode_enum p_mode, BSTR p_zlev) +{ + COMTRY + { + CString str = p_zlev; + if(p_mode & RM_USER) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); + ERRTHROW( mga.SetStringValue( _T("DefaultZoomLevel"), str)); + } + if(p_mode & (RM_SYS | RM_TEST)) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); + if(p_mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("DefaultZoomLevel"), str)); + } + } + COMCATCH(;) +} + + +STDMETHODIMP CMgaRegistrar::GetMouseOverNotify(regaccessmode_enum mode, VARIANT_BOOL *enabled) +{ + COMTRY + { + LONG res; + CString str; + if(mode & RM_USER) { + CRegKey mga; + res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("MouseOverNotify")); + if(!str.IsEmpty()) { + REVOKE_SYS2(mode); + } + } + } + if(mode & (RM_SYSDOREAD)) { + CRegKey mga; + res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("MouseOverNotify")); + } + } + *enabled = (str == _T("1")) ? VARIANT_TRUE : VARIANT_FALSE; // Default value: false + } + COMCATCH(;) +} + + +STDMETHODIMP CMgaRegistrar::SetMouseOverNotify(regaccessmode_enum mode, VARIANT_BOOL enabled) +{ + COMTRY + { + CString str = (enabled == VARIANT_FALSE) ? _T("0") : _T("1"); + if(mode & RM_USER) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); + ERRTHROW( mga.SetStringValue( _T("MouseOverNotify"), str)); + } + if(mode & (RM_SYS | RM_TEST)) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); + if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("MouseOverNotify"), str)); + } + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::GetRealNmbFmtStr(regaccessmode_enum p_mode, BSTR *p_fmtStr) +{ + CHECK_OUT(p_fmtStr); + COMTRY + { + LONG res; + CString str; + if(p_mode & RM_USER) { + CRegKey mga; + res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("RealNmbFmtStr")); + if(!str.IsEmpty()) REVOKE_SYS2(p_mode); + } + } + if(p_mode & (RM_SYSDOREAD)) { + CRegKey mga; + res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("RealNmbFmtStr")); + } + } + CopyTo(str, p_fmtStr); + } + COMCATCH(;) + +} + +STDMETHODIMP CMgaRegistrar::SetRealNmbFmtStr(regaccessmode_enum p_mode, BSTR p_fmtStr) +{ + COMTRY + { + CString str = p_fmtStr; + if(p_mode & RM_USER) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); + ERRTHROW( mga.SetStringValue( _T("RealNmbFmtStr"), str)); + } + if(p_mode & (RM_SYS | RM_TEST)) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); + if(p_mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("RealNmbFmtStr"), str)); + } + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::GetTimeStamping(regaccessmode_enum p_mode, VARIANT_BOOL *p_enabled) +{ + COMTRY + { + LONG res; + CString str; + if(p_mode & RM_USER) { + CRegKey mga; + res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("TimeStamping")); + if(!str.IsEmpty()) { + REVOKE_SYS2(p_mode); + } + } + } + if(p_mode & (RM_SYSDOREAD)) { + CRegKey mga; + res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("TimeStamping")); + } + } + *p_enabled = (str == _T("1")) ? VARIANT_TRUE : VARIANT_FALSE; // Default value: false + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::SetTimeStamping(regaccessmode_enum p_mode, VARIANT_BOOL p_enabled) +{ + COMTRY + { + CString str = (p_enabled == VARIANT_FALSE) ? _T("0") : _T("1"); + if(p_mode & RM_USER) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); + ERRTHROW( mga.SetStringValue( _T("TimeStamping"), str)); + } + if(p_mode & (RM_SYS | RM_TEST)) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); + if(p_mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("TimeStamping"), str)); + } + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::GetNavigation(regaccessmode_enum p_mode, VARIANT_BOOL *p_enabled) +{ + COMTRY + { + LONG res; + CString str; + if(p_mode & RM_USER) { + CRegKey mga; + res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("Navigation")); + if(!str.IsEmpty()) { + REVOKE_SYS2(p_mode); + } + } + } + if(p_mode & (RM_SYSDOREAD)) { + CRegKey mga; + res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("Navigation")); + } + } + *p_enabled = (str == _T("0")) ? VARIANT_FALSE : VARIANT_TRUE; // Default value: true + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::SetNavigation(regaccessmode_enum p_mode, VARIANT_BOOL p_enabled) +{ + COMTRY + { + CString str = (p_enabled == VARIANT_FALSE) ? _T("0") : _T("1"); + if(p_mode & RM_USER) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); + ERRTHROW( mga.SetStringValue( _T("Navigation"), str)); + } + if(p_mode & (RM_SYS | RM_TEST)) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); + if(p_mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("Navigation"), str)); + } + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::GetUndoQueueSize(regaccessmode_enum p_mode, BSTR *p_qusz) +{ + CHECK_OUT(p_qusz); + COMTRY + { + LONG res; + CString str; + if(p_mode & RM_USER) { + CRegKey mga; + res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("UndoQueueSize")); + if(!str.IsEmpty()) REVOKE_SYS2(p_mode); + } + } + if(p_mode & (RM_SYSDOREAD)) { + CRegKey mga; + res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("UndoQueueSize")); + } + } + CopyTo(str, p_qusz); + } + COMCATCH(;) + +} + +STDMETHODIMP CMgaRegistrar::SetUndoQueueSize(regaccessmode_enum p_mode, BSTR p_qusz) +{ + COMTRY + { + CString str = p_qusz; + if(p_mode & RM_USER) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); + ERRTHROW( mga.SetStringValue( _T("UndoQueueSize"), str)); + } + if(p_mode & (RM_SYS | RM_TEST)) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); + if(p_mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("UndoQueueSize"), str)); + } + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::get_EdgeSmoothMode(regaccessmode_enum mode, edgesmoothmode_enum* smoothMode) +{ + COMTRY + { + LONG res; + CString str; + if(mode & RM_USER) { + CRegKey mga; + res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("EdgeSmoothMode")); + if(!str.IsEmpty()) { + REVOKE_SYS2(mode); + } + } + } + if(mode & (RM_SYSDOREAD)) { + CRegKey mga; + res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("EdgeSmoothMode")); + } + } + *smoothMode = (edgesmoothmode_enum)(str.IsEmpty() ? 2 : _tcstol(str, NULL, 10)); + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::put_EdgeSmoothMode(regaccessmode_enum mode, edgesmoothmode_enum smoothMode) +{ + COMTRY + { + CString str; + str.Format(_T("%d"), smoothMode); + if(mode & RM_USER) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); + ERRTHROW( mga.SetStringValue( _T("EdgeSmoothMode"), str)); + } + if(mode & (RM_SYS | RM_TEST)) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); + if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("EdgeSmoothMode"), str)); + } + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::get_FontSmoothMode(regaccessmode_enum mode, fontsmoothmode_enum* smoothMode) +{ + COMTRY + { + LONG res; + CString str; + if(mode & RM_USER) { + CRegKey mga; + res = mga.Open(HKEY_CURRENT_USER, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("FontSmoothMode")); + if(!str.IsEmpty()) { + REVOKE_SYS2(mode); + } + } + } + if(mode & (RM_SYSDOREAD)) { + CRegKey mga; + res = mga.Open(HKEY_LOCAL_MACHINE, rootreg, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + str = QueryValue(mga, _T("FontSmoothMode")); + } + } + *smoothMode = (fontsmoothmode_enum)(str.IsEmpty() ? 4 : _tcstol(str, NULL, 10)); + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::put_FontSmoothMode(regaccessmode_enum mode, fontsmoothmode_enum smoothMode) +{ + COMTRY + { + CString str; + str.Format(_T("%d"), smoothMode); + if(mode & RM_USER) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); + ERRTHROW( mga.SetStringValue( _T("FontSmoothMode"), str)); + } + if(mode & (RM_SYS | RM_TEST)) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); + if(mode & RM_SYS) ERRTHROW( mga.SetStringValue( _T("FontSmoothMode"), str)); + } + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::get_Paradigms(regaccessmode_enum mode, VARIANT *names) +{ + CHECK_OUT(names); + + COMTRY + { + CStringArray ret; + if(mode & RM_USER) { + CRegKey pars; + LONG res = pars.Open(HKEY_CURRENT_USER, rootreg+_T("\\Paradigms"), KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + for(int index = 0;; ++index) { + TCHAR name[1024]; + LONG err = RegEnumKey(pars, index, name, 1024); + if( err == ERROR_NO_MORE_ITEMS ) + break; + ERRTHROW( err ); + + REVOKE_SYS2(mode); + ret.Add(name); + } + + } + } + int retlen = ret.GetSize(); + + if(mode & RM_SYSDOREAD) { + CRegKey pars; + LONG res = pars.Open(HKEY_LOCAL_MACHINE, rootreg+_T("\\Paradigms"), KEY_READ | KEY_WOW64_32KEY); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + for(int index = 0;; ++index) { + TCHAR name[1024]; + LONG err = RegEnumKey(pars, index, name, 1024); + if( err == ERROR_NO_MORE_ITEMS ) + break; + ERRTHROW( err ); + int j; + for(j = 0; j < retlen; j++) { // Make sure, name is not present already, if yes, system copy is ignored + if(!ret[j].CompareNoCase(name)) break; + } + if(j != retlen) continue; + ret.Add(name); + } + + } + } + + + CopyTo(ret, names); + } + COMCATCH(;) +} + + +HRESULT GetMtaInfo(BSTR conn, BSTR *parname, BSTR *version, VARIANT *guid) { + COMTRY { + CComObjPtr paradigm; + COMTHROW( paradigm.CoCreateInstance(OLESTR("MGA.MgaMetaProject")) ); + ASSERT( paradigm != NULL ); + + COMTHROW( paradigm->Open(conn) ); + + COMTHROW( paradigm->get_Name(parname) ); + + COMTHROW( paradigm->get_Version(version) ); + + COMTHROW( paradigm->get_GUID(guid) ); + + COMTHROW( paradigm->Close() ); + } COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::RegisterParadigmFromDataDisp(BSTR connstr, regaccessmode_enum mode, BSTR *newname) +{ + return RegisterParadigmFromData( connstr, newname, mode); +} + +STDMETHODIMP CMgaRegistrar::RegisterParadigmFromData(BSTR connstr, BSTR *newname, regaccessmode_enum mode) +{ + CHECK_IN(connstr); + if(newname) CHECK_OUT(newname); + COMTRY { + CString conn = connstr; + CString connrecent; + // we have to parse it + if( conn.Left(4) == _T("XML=") ) + { + CString file = conn.Mid(4); + + conn = _T("MGA="); + conn += file; + + if( conn.Right(4).CompareNoCase(_T(".xml")) == 0 || + conn.Right(4).CompareNoCase(_T(".xmp")) == 0 ) { + conn.Delete(conn.GetLength() - 4, 4); + } + conn += _T(".mta"); +#define FILEPART(x) (((LPCTSTR)x)+4) + DWORD info = GetFileAttributes(FILEPART(conn)); + if(info != 0xFFFFFFFF ) { // save old version of paradigm under another name + if(info & FILE_ATTRIBUTE_DIRECTORY) COMTHROW(E_FILEOPEN); + try { + CComBstrObj name; // Format: name- + CComVariant prevguid; + CComBstrObj prevversion; + COMTHROW(GetMtaInfo(PutInBstr(conn), PutOut(name), PutOut(prevversion), PutOut(prevguid))); + CComBstrObj conn1; + if(QueryParadigm(name, PutOut(conn1), &prevguid, REGACCESS_PRIORITY) == S_OK && + conn1 == CComBSTR(conn)) { // if it was correctly registered under the previous nonextended name + GUID gg; + CopyTo(prevguid,gg); + CComBstrObj guidstr; + CopyTo(gg, guidstr); + connrecent = conn.Left(conn.GetLength()-4)+_T("-")+CString(PutInCString(guidstr))+_T(".mta"); + + bool sysmove = false, usermove = false; + conn1.Empty(); + if(QueryParadigm(name, PutOut(conn1), &prevguid, REGACCESS_SYSTEM) == S_OK && + conn1 == CComBSTR(conn)) { // if it was correctly registered in system + if(RegisterParadigm(name, PutInBstr(connrecent), prevversion, prevguid, REGACCESS_TEST) != S_OK) { + AfxMessageBox(_T("Cannot register this paradigm file\n") + _T("an existing '.mta' file with the same name\n") + _T("is registered in the system registry\n") + _T("which you are not permitted to change.\n") + _T("You need to change the name or location\n") + _T("of the new paradigm file")); + return E_INVALID_USAGE; + } + sysmove = true;; + } + conn1.Empty(); + if(QueryParadigm(name, PutOut(conn1), &prevguid, REGACCESS_USER) == S_OK && + conn1 == CComBSTR(conn)) { // if it was correctly registered in user + usermove = true; + } + + if(!MoveFileEx(FILEPART(conn), FILEPART(connrecent), MOVEFILE_REPLACE_EXISTING)) { + // n.b. can't do this because clients expect ParadigmName.mta + // conn = conn.Left(conn.GetLength() - 4) + _T("-") + CTime::GetCurrentTime().Format("%Y%m%d_%H%M%S") + _T(".mta"); + COMTHROW(E_FILEOPEN); + } + else { + if (sysmove) { + COMTHROW(RegisterParadigm(name, PutInBstr(connrecent), prevversion, prevguid, REGACCESS_SYSTEM)); + } + if (usermove) { + COMTHROW(RegisterParadigm(name, PutInBstr(connrecent), prevversion, prevguid, REGACCESS_USER)); + } + } + } + } catch(hresult_exception(&e)) { + AfxMessageBox(CString(_T("Failure saving previous version of paradigm\n")) + + e.what() + + (e.hr == E_BINFILE?_T(" [Binary paradigm file (.mta) incompatibility]\nPossible reason: GME version 6 changed the binary format of paradigms."):_T("")) + + _T("\nOld version will be overwritten")); + connrecent.Empty(); + } + } + + IMgaMetaParserPtr parser; + COMTHROW(parser.CreateInstance(L"MGA.MgaMetaParser")); + parser->__Parse(_bstr_t(file), _bstr_t(conn)); + } + + CComBstrObj name; + CComVariant guid; + CComBstrObj version; + COMTHROW(GetMtaInfo(PutInBstr(conn), PutOut(name), PutOut(version), PutOut(guid))); + if(!connrecent.IsEmpty()) { + CComBstrObj namer; + CComVariant guidr; + CComBstrObj versionr; + COMTHROW(GetMtaInfo(PutInBstr(connrecent), PutOut(namer), PutOut(versionr), PutOut(guidr))); + // We should change existing registration only here, if the new GUID != the old + } + + COMTHROW(RegisterParadigm( name, PutInBstr(conn), PutInBstr(version), guid, mode) ); + if(newname) MoveTo(name, newname); + } COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::RegisterParadigm(BSTR name, BSTR connstr, BSTR version, VARIANT guid, regaccessmode_enum mode) +{ + CString cver(version); + + COMTRY + { + GUID guid2; + if (guid.vt == (VT_UI1 | VT_ARRAY) && GetArrayLength(guid) == sizeof(GUID)) + { + CopyTo(guid, guid2); + } + else if (guid.vt == VT_BSTR) + { + CopyTo(guid.bstrVal, guid2); + } + else + COMTHROW(E_INVALIDARG); + + CComBstrObj guid3; + CopyTo(guid2, guid3); + + if(mode & RM_USER) { + CRegKey mga; + ERRTHROW(mga.Create(HKEY_CURRENT_USER, rootreg) ); + + CRegKey pars; + ERRTHROW( pars.Create(mga, _T("Paradigms")) ); + + CRegKey par; + ERRTHROW( par.Create(pars, CString(name)) ); + + + ERRTHROW( par.SetStringValue( _T("CurrentVersion"), PutInCString(guid3))); + if (!cver.IsEmpty()) { + ERRTHROW( par.SetStringValue( cver, PutInCString(guid3))); + } + CRegKey parg; + ERRTHROW( parg.Create(par, PutInCString(guid3)) ); + + ERRTHROW( parg.SetStringValue( _T("ConnStr"), CString(connstr))); + } + if(mode & (RM_SYS | RM_TEST)) { + CRegKey mga; + WIN32THROW(mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); + + CRegKey pars; + WIN32THROW( pars.Create(mga, _T("Paradigms"), 0, 0, KEY_READ | KEY_WRITE | KEY_WOW64_32KEY) ); + + CRegKey par; + + if (mode & RM_SYS) { + WIN32THROW( par.Create(pars, CString(name)) ); + CString gg = QueryValue(par, _T("GUID")); + CString gc = QueryValue(par, _T("ConnStr")); + par.DeleteValue(_T("GUID")); + par.DeleteValue(_T("ConnStr")); + if(!gc.IsEmpty() && !gg.IsEmpty()) { + CRegKey parg2; + WIN32THROW( parg2.Create(par, gg) ); + WIN32THROW( parg2.SetStringValue( _T("ConnStr"), gc) ); + } + + WIN32THROW( par.SetStringValue( _T("CurrentVersion"), PutInCString(guid3))); + if (!cver.IsEmpty()) { + WIN32THROW( par.SetStringValue( cver, PutInCString(guid3))); + } + CRegKey parg; + WIN32THROW( parg.Create(par, PutInCString(guid3)) ); + + WIN32THROW( parg.SetStringValue( _T("ConnStr"), CString(connstr))); + } else { + LONG res = par.Open(pars, CString(name)); + if(res != ERROR_SUCCESS && res != ERROR_FILE_NOT_FOUND) WIN32THROW(res); + } + } + if ((!(mode & RM_USER) || IsAssociated_hive(L"Mga.AddOn.ConstraintManager", name, HKEY_CURRENT_USER) != Tristate_Disabled) && + (!(mode & RM_SYS) || IsAssociated_hive(L"Mga.AddOn.ConstraintManager", name, HKEY_LOCAL_MACHINE) != Tristate_Disabled)) { + Associate(CComBSTR(L"Mga.AddOn.ConstraintManager"), name, mode); // no error checking + } + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::QueryParadigmAllGUIDs(BSTR parname, VARIANT *guidstrs, regaccessmode_enum mode) { + CHECK_OUT(guidstrs); + COLE2CT parname2(parname); + CString pname(parname2); + + COMTRY + { + CStringArray ret; + if(mode & RM_USER) { + CRegKey par; + LONG res = par.Open(HKEY_CURRENT_USER, rootreg+_T("\\Paradigms\\") + pname, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + for(int index = 0;; ++index) { + TCHAR name[1024]; + LONG err = RegEnumKey(par, index, name, 1024); + if( err == ERROR_NO_MORE_ITEMS ) + break; + ERRTHROW( err ); + + REVOKE_SYS2(mode); + ret.Add(name); + } + + } + } + int retlen = ret.GetSize(); + + if(mode & RM_SYSDOREAD) { + CRegKey par; + LONG res = par.Open(HKEY_LOCAL_MACHINE, rootreg+_T("\\Paradigms\\") + pname, KEY_READ | KEY_WOW64_32KEY); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + CString cur = QueryValue(par, _T("CurrentVersion")); + if(!cur.IsEmpty()) { // New style: Connection strings are stored under GUID subkeys + for(int index = 0;; ++index) { + TCHAR name[1024]; + LONG err = RegEnumKey(par, index, name, 1024); + if( err == ERROR_NO_MORE_ITEMS ) + break; + ERRTHROW( err ); + int j; + for(j = 0; j < retlen; j++) { // Make sure, name is not present already, if yes system copy is ignored + if(!ret[j].CompareNoCase(name)) break; + } + if(j != retlen) continue; + ret.Add(name); + } + } + else { + CString name = QueryValue(par, _T("GUID")); + int j; + for(j = 0; j < retlen; j++) { // Make sure, name is not present already, if yes system copy is ignored + if(!ret[j].CompareNoCase(name)) break; + } + if(j == retlen) ret.Add(name); + } + } + } + + + CopyTo(ret, guidstrs); + } + COMCATCH(;) +} + + +STDMETHODIMP CMgaRegistrar::QueryParadigm(BSTR parname, BSTR *connstr, VARIANT *guid, regaccessmode_enum mode) +{ + CHECK_OUT(connstr); +// CHECK_OUT(guid); + + COMTRY + { + CString pname = parname; + + CRegKey subk; + CString guidact; + + CComBstrObj inguidstr; + if(guid->vt != VT_EMPTY && guid->vt != VT_NULL) { + GUID g; + CopyTo(*guid, g); + CopyTo(g, inguidstr); +// if(inguidstr == L"{00000000-0000-0000-0000-000000000000}") inguidstr = NULL; + } + + LONG res; + + if(mode & RM_USER) { + CRegKey par; + res = par.Open(HKEY_CURRENT_USER, rootreg + _T("\\Paradigms\\") + pname, KEY_READ); + if(res == ERROR_SUCCESS) { + if(inguidstr == NULL) { + guidact = QueryValue(par, _T("CurrentVersion")); + if(guidact.IsEmpty()) res = ERROR_FILE_NOT_FOUND; + } + else + guidact = inguidstr; + } + if(res == ERROR_SUCCESS) res = subk.Open(par, guidact, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) mode = REGACCESS_USER; + } + + if(mode & RM_SYSDOREAD) { + CRegKey par; + res = par.Open(HKEY_LOCAL_MACHINE, rootreg + _T("\\Paradigms\\") + pname, KEY_READ | KEY_WOW64_32KEY); + if(res == ERROR_SUCCESS) { + CString cur = QueryValue(par, _T("CurrentVersion")); + if (cur.IsEmpty() && inguidstr == NULL) { + guidact = QueryValue(par, _T("GUID")); + if (inguidstr != NULL && inguidstr != CComBSTR(guidact)) + COMTHROW(E_NOTFOUND); + subk.Attach(par.Detach()); + } + else { + if (inguidstr == NULL) + guidact = cur; + else + guidact = inguidstr; + res = subk.Open(par, guidact, KEY_READ); + if (res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) + ERRTHROW(res); + } + } + } + if (subk == NULL) + { + CString error; + if (inguidstr) + error.Format(L"Paradigm '%s' with GUID '%s' is not registered.", static_cast(pname), + static_cast(inguidstr)); + else + error.Format(L"Paradigm '%s' is not registered.", static_cast(pname)); + SetErrorInfo(error); + return E_NOTFOUND; + } + + + CopyTo(QueryValue(subk, _T("ConnStr")), connstr); + + if(inguidstr == NULL) { + GUID g; + CopyTo(CComBSTR(guidact),g); + CopyTo(g, guid); + } + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::get_ParadigmGUIDString(regaccessmode_enum mode, BSTR parname, BSTR *guidstr) +{ + CHECK_OUT(guidstr); + COMTRY + { + CComBSTR connstr; + CComVariant guid; + HRESULT hr = QueryParadigm(parname, &connstr, &guid, mode); + if (FAILED(hr)) + return hr; + GUID g; + CopyTo(guid, g); + CopyTo(g, guidstr); + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::VersionFromGUID(BSTR name, VARIANT guid, BSTR *ver, regaccessmode_enum mode) +{ + CHECK_OUT(ver); + + bool found = false; + COMTRY + { + GUID gg; + CopyTo(guid,gg); + CComBstrObj guidbstr; + CopyTo(gg, guidbstr); + + LONG res; + + if(mode & RM_USER) { + CRegKey par; + res = par.Open(HKEY_CURRENT_USER, rootreg + _T("\\Paradigms\\")+name, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + mode = REGACCESS_USER; + for(int index = 0;; ++index) { + TCHAR name[512]; + DWORD namesize = sizeof(name) / sizeof(name[0]); + TCHAR value[512]; + DWORD valuesize = sizeof(value); + DWORD valtype; + + LONG err = RegEnumValue(par, index, name, &namesize, NULL, &valtype, (LPBYTE)value, &valuesize); + if( err == ERROR_NO_MORE_ITEMS ) + break; + ERRTHROW( err ); + if (valtype == REG_SZ) { + CString cver(value); + if (cver.Compare(PutInCString(guidbstr)) == 0) { + CString namestr(name); + if (namestr.CompareNoCase(_T("CurrentVersion")) != 0) { + found = true; + CopyTo(namestr, ver); + } + } + } + } + } + } + if(mode & (RM_SYSDOREAD)) { + CRegKey par; + res = par.Open(HKEY_LOCAL_MACHINE, rootreg + _T("\\Paradigms\\")+name, KEY_READ | KEY_WOW64_32KEY); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + for(int index = 0;; ++index) { + TCHAR name[512]; + DWORD namesize = sizeof(name) / sizeof(name[0]); + TCHAR value[512]; + DWORD valuesize = sizeof(value); + DWORD valtype; + + LONG err = RegEnumValue(par, index, name, &namesize, NULL, &valtype, (BYTE*)value, &valuesize); + if( err == ERROR_NO_MORE_ITEMS ) + break; + ERRTHROW( err ); + if (valtype == REG_SZ) { + CString cver(value); + if (cver.Compare(PutInCString(guidbstr)) == 0) { + CString namestr(name); + if (namestr.CompareNoCase(_T("CurrentVersion")) != 0) { + found = true; + CopyTo(namestr, ver); + } + } + } + } + } + } + if (!found) + { + SetErrorInfo(E_NOTFOUND); + return(E_NOTFOUND); + } + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::GUIDFromVersion(BSTR name, BSTR ver, VARIANT* guid, regaccessmode_enum mode) +{ + CHECK_OUT(guid); + + CString verstr = ver; + CString gstr; + + COMTRY + { + LONG res; + + if(mode & RM_USER) { + CRegKey par; + res = par.Open(HKEY_CURRENT_USER, rootreg + _T("\\Paradigms\\")+name, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + gstr = QueryValue(par, verstr); + if (!gstr.IsEmpty()) { + mode = REGACCESS_USER; + } + } + } + if(mode & (RM_SYSDOREAD)) { + CRegKey par; + res = par.Open(HKEY_LOCAL_MACHINE, rootreg + _T("\\Paradigms\\")+name, KEY_READ | KEY_WOW64_32KEY); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + gstr = QueryValue(par, verstr); + } + } + + if (gstr.IsEmpty()) { + CString error; + if (SysStringLen(ver)) + error.Format(L"Paradigm '%s' with version '%s' is not registered.", name, ver); + else + error.Format(L"Paradigm '%s' is not registered.", name); + SetErrorInfo(error); + return E_NOTFOUND; + } + + GUID g; + CopyTo(CComBSTR(gstr),g); + CopyTo(g, guid); + } + COMCATCH(;) +} + + +STDMETHODIMP CMgaRegistrar::UnregisterParadigmGUID(BSTR name, VARIANT v, regaccessmode_enum mode) +{ // it cannot be unregistered if it is the current version + COMTRY + { + GUID gg; + CopyTo(v,gg); + CComBstrObj guidbstr; + CopyTo(gg, guidbstr); + + if(mode & RM_USER) { + CRegKey par; + ERRTHROW( par.Open(HKEY_CURRENT_USER, rootreg + _T("\\Paradigms\\")+name) ); + CString cur = QueryValue(par, _T("CurrentVersion")); + if(cur.Compare(PutInCString(guidbstr)) == 0) { + COMTHROW(E_INVALID_USAGE); + } + + for(int index = 0;; ++index) { + TCHAR name[512]; + DWORD namesize = sizeof(name) / sizeof(name[0]); + TCHAR value[512]; + DWORD valuesize = sizeof(value); + DWORD valtype; + + LONG err = RegEnumValue(par, index, name, &namesize, NULL, &valtype, (BYTE*)value, &valuesize); + if( err == ERROR_NO_MORE_ITEMS ) + break; + ERRTHROW( err ); + if (valtype == REG_SZ) { + CString cver(value); + if (cver.Compare(PutInCString(guidbstr)) == 0) { + RegDeleteValue(par, name); + } + } + } + + ERRTHROW( par.RecurseDeleteKey(PutInCString(guidbstr)) ); + } + if(mode & (RM_SYS | RM_TEST)) { + CRegKey par; + ERRTHROW( par.Open(HKEY_LOCAL_MACHINE, rootreg + _T("\\Paradigms\\")+name, KEY_READ | KEY_WRITE | KEY_WOW64_32KEY) ); + CString cur = QueryValue(par, _T("CurrentVersion")); + if(cur.Compare(PutInCString(guidbstr)) == 0) { + COMTHROW(E_INVALID_USAGE); + } + if(mode & RM_SYS) { + ERRTHROW( par.RecurseDeleteKey(PutInCString(guidbstr)) ); + for(int index = 0;; ++index) { + TCHAR name[512]; + DWORD namesize = sizeof(name) / sizeof(name[0]); + TCHAR value[512]; + DWORD valuesize = sizeof(value); + DWORD valtype; + + LONG err = RegEnumValue(par, index, name, &namesize, NULL, &valtype, (BYTE*)value, &valuesize); + if( err == ERROR_NO_MORE_ITEMS ) + break; + ERRTHROW( err ); + if (valtype == REG_SZ) { + CString cver(value); + if (cver.Compare(PutInCString(guidbstr)) == 0) { + RegDeleteValue(par, name); + } + } + } + } + if(mode & RM_TEST) ERRTHROW( par.Open(par, PutInCString(guidbstr)) ); + } + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::UnregisterParadigm(BSTR name, regaccessmode_enum mode) +{ + COMTRY + { + if(mode & RM_USER) { + CRegKey pars; + LONG res = pars.Open(HKEY_CURRENT_USER, rootreg + _T("\\Paradigms")); + if(!res) res = pars.RecurseDeleteKey(CString(name)); + if(res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; + ERRTHROW(res); + } + if(mode & (RM_SYS | RM_TEST)) { + CRegKey pars; + LONG res = pars.Open(HKEY_LOCAL_MACHINE, rootreg + _T("\\Paradigms"), KEY_READ | KEY_WRITE | KEY_WOW64_32KEY); + if(!res) { + if(mode & RM_SYS) res = pars.RecurseDeleteKey(PutInCString(name)); + if(mode & RM_TEST) res = pars.Open(pars, PutInCString(name)); + } + if(res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; + ERRTHROW(res); + } + } + COMCATCH(;) +} + +// throws hresult_exception +void GetComponents_(HKEY hive, CStringArray& ret) { + CRegKey comps; + LONG res = comps.Open(hive, rootreg + _T("\\Components"), KEY_READ); + if (res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) + COMTHROW(HRESULT_FROM_WIN32(res)); + if (res == ERROR_SUCCESS) { + for (int index = 0;; ++index) { + TCHAR name[1024]; + LONG err = RegEnumKey(comps, index, name, 1024); + if (err == ERROR_NO_MORE_ITEMS) + break; + ERRTHROW(err); + + CRegKey comp; + err = comp.Open(comps, name, KEY_READ); + DWORD type2; + if (err == ERROR_SUCCESS) + err = comp.QueryDWORDValue(_T("Type"), type2); + if (err != ERROR_SUCCESS) + continue; + if((type2 & COMPONENTTYPE_SYSREGREF) != 0) { + continue; + } + // Make sure name is not present already + int j; + for (j = 0; j < ret.GetSize(); j++) { + if (!ret[j].CompareNoCase(name)) + break; + } + if (j != ret.GetSize()) + continue; + ret.Add(name); + } + } +} + +STDMETHODIMP CMgaRegistrar::get_Components(regaccessmode_enum mode, VARIANT *progids) +{ + CHECK_OUT(progids); + + COMTRY + { + CStringArray ret; + if (mode & REGACCESS_USER) + GetComponents_(HKEY_CURRENT_USER, ret); + if (mode & REGACCESS_SYSTEM) + GetComponents_(HKEY_LOCAL_MACHINE, ret); + CopyTo(ret, progids); + } + COMCATCH(;) +} + +template +void TokenizeParadigmString(const CString& paradigms, Functor& x) { + CStringList ret; + int curPos = 0; + CString token = paradigms.Tokenize(_T(" ;,\n\t"), curPos); + while (token != _T("")) { + x(token); + token = paradigms.Tokenize(_T(" ;,\n\t"), curPos); + } +} + +STDMETHODIMP CMgaRegistrar::RegisterComponent(BSTR progid, componenttype_enum type, BSTR desc, regaccessmode_enum mode) +{ + COMTRY + { + CComBstrObj paradigms(OLESTR("*")); + if(!(type & COMPONENTTYPE_PARADIGM_INDEPENDENT)) { + paradigms.Empty(); + CComPtr comp; + HRESULT hr = CreateMgaComponent(comp, progid); + if(!comp) + { + _bstr_t error; + GetErrorInfo(hr, error.GetAddress()); + if (!static_cast(error)) + error = L"Unknown error"; + throw_com_error(E_MGA_COMPONENT_ERROR, _bstr_t(L"Could not create: ") + progid + L": " + error); + } + COMTHROW(comp->get_Paradigm(PutOut(paradigms))); + } + if(mode & RM_USER) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_CURRENT_USER, rootreg) ); + CRegKey comps; + ERRTHROW( comps.Create(mga, _T("Components")) ); + CRegKey comp; + ERRTHROW( comp.Create(comps, PutInCString(progid)) ); + + ERRTHROW( comp.SetDWORDValue( _T("Type"), (DWORD)type)); + + ERRTHROW( comp.SetStringValue( _T("Description"), PutInCString(desc))); + if(paradigms.Length()) { + TokenizeParadigmString(PutInCString(paradigms), [&comp](const CString& par) { + ERRTHROW(comp.SetStringValue(_T("Paradigm"), par)); + }); + } + } + if(mode & (RM_SYS | RM_TEST)) { + CRegKey mga; + ERRTHROW( mga.Create(HKEY_LOCAL_MACHINE, rootreg) ); + CRegKey comps; + ERRTHROW( comps.Create(mga, _T("Components")) ); + if(mode & RM_SYS) { + CRegKey comp; + ERRTHROW( comp.Create(comps, PutInCString(progid)) ); + + ERRTHROW( comp.SetDWORDValue( _T("Type"), (DWORD)type)); + + ERRTHROW( comp.SetStringValue( _T("Description"), PutInCString(desc))); + TokenizeParadigmString(PutInCString(paradigms), [&comp](const CString& par) { + ERRTHROW(comp.SetStringValue(_T("Paradigm"), par)); + }); + } + else { + CRegKey comp; + LONG res = comp.Open(comps, PutInCString(progid)); + if(res != ERROR_SUCCESS && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + } + } + } + COMCATCH(;) +} + +// FIXME: mode is ignored. It should be removed next interface-breaking change +STDMETHODIMP CMgaRegistrar::QueryComponent(BSTR progid, componenttype_enum *type, BSTR *desc, regaccessmode_enum mode) +{ + CHECK_OUT(type); + if(desc) CHECK_OUT(desc); + CString progidstr = PutInCString(progid); + + COMTRY + { + DWORD dwType = -1; + CString strDesc; + HKEY hives[] = { HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE }; + for (int i = 0; i < 2; i++) { + CRegKey comp; + LONG res = comp.Open(hives[i], rootreg+_T("\\Components\\")+progidstr, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + comp.QueryDWORDValue(_T("Type"), dwType); + ULONG count = 0; + res = comp.QueryStringValue(_T("Description"), NULL, &count); + if (strDesc == _T("") && res == ERROR_SUCCESS) { + CString ret; + if (comp.QueryStringValue(_T("Description"), ret.GetBufferSetLength(count), &count) == ERROR_SUCCESS) { + ret.ReleaseBuffer(); + strDesc = ret; + } + } + } + } + if (dwType == -1 || !(dwType & COMPONENTTYPE_ALL)) + COMTHROW(E_NOTFOUND); + + if (type) + *type = (componenttype_enum)dwType; + if (desc && strDesc != _T("")) + CopyTo(strDesc, desc); + return S_OK; + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::UnregisterComponent(BSTR progid, regaccessmode_enum mode) +{ + COMTRY + { +// if(mode & RM_USER) { + if(mode & (RM_USER | RM_SYS) ){ + CRegKey comps; + LONG res = comps.Open(HKEY_CURRENT_USER, rootreg + _T("\\Components")); + + DWORD type2 = 0; + if(!res) { + CRegKey comp; + res = comp.Open(comps, PutInCString(progid), KEY_READ); + if(!res) comp.QueryDWORDValue( _T("Type"), type2); + } + + if((mode & RM_USER) || (type2 & COMPONENTTYPE_SYSREGREF) != 0 ) { + if (!res) + res = comps.RecurseDeleteKey(PutInCString(progid)); + if (res == ERROR_FILE_NOT_FOUND) + res = ERROR_SUCCESS; + if (res != ERROR_SUCCESS) + WIN32THROW(res); + } + } + if(mode & (RM_SYS | RM_TEST)) { + CRegKey comps; + LONG res = comps.Open(HKEY_LOCAL_MACHINE, rootreg + _T("\\Components")); + if(!res) { + if(mode & RM_SYS) res = comps.RecurseDeleteKey(PutInCString(progid)); + if(mode & RM_TEST) res = comps.Open(comps, PutInCString(progid)); + } + if(res == ERROR_FILE_NOT_FOUND) + res = ERROR_SUCCESS; + if (res != ERROR_SUCCESS) + WIN32THROW(res); + } + } + COMCATCH(;) +} + + +STDMETHODIMP CMgaRegistrar::put_ComponentExtraInfo(regaccessmode_enum mode, + BSTR progid, BSTR name, BSTR newVal) { + CString progidstr = PutInCString(progid); + + COMTRY + { + if(mode & RM_USER) { + CRegKey comp; + LONG res = comp.Open(HKEY_CURRENT_USER, rootreg+_T("\\Components\\")+progidstr); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + DWORD type2; + ERRTHROW( comp.QueryDWORDValue( _T("Type"), type2)); + + if((type2 & COMPONENTTYPE_ALL)) { + if(!newVal) { ERRTHROW( comp.DeleteValue(PutInCString(name)) ); } + else { ERRTHROW( comp.SetStringValue( PutInCString(name), PutInCString(newVal))); } + } + } + } + if(mode & (RM_SYS | RM_TEST)) { + CRegKey comp; + LONG res = comp.Open(HKEY_LOCAL_MACHINE, rootreg+_T("\\Components\\")+progidstr); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + DWORD type2; + ERRTHROW( comp.QueryDWORDValue( _T("Type"), type2)); + + if((mode & RM_SYS) && (type2 & COMPONENTTYPE_ALL)) { + if(!newVal) { ERRTHROW( comp.DeleteValue(PutInCString(name)) ); } + else { ERRTHROW( comp.SetStringValue( PutInCString(name), PutInCString(newVal))); } + } + } + } + + } COMCATCH(;) +} + +// FIXME: mode is ignored. It should be removed next interface-breaking change +STDMETHODIMP CMgaRegistrar::get_ComponentExtraInfo(regaccessmode_enum mode, + BSTR progid, BSTR name, BSTR* pVal) { + CHECK_OUT(pVal); + CString progidstr = PutInCString(progid); + + COMTRY + { + HKEY hives[] = { HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE }; + for (int i = 0; i < 2; i++) { + CRegKey comp; + LONG res = comp.Open(hives[i], rootreg+_T("\\Components\\")+progidstr, KEY_READ); + if(res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if(res == ERROR_SUCCESS) { + ULONG count = 0; + res = comp.QueryStringValue(PutInCString(name), NULL, &count); + if (res == ERROR_SUCCESS) { + CString ret; + if (comp.QueryStringValue(PutInCString(name), ret.GetBufferSetLength(count), &count) == ERROR_SUCCESS) { + ret.ReleaseBuffer(); + CopyTo(ret, pVal); + return S_OK; + } + } + } + } + return E_NOTFOUND; + } + COMCATCH(;) +} + + +STDMETHODIMP CMgaRegistrar::get_LocalDllPath(BSTR progid, BSTR* pVal) { + CHECK_OUT(pVal); + COMTRY + { + CString m_strProgId = PutInCString(progid); + CRegKey comp; + CString m_strClassId; + for(int i = 0; i < 10; i++) { + LONG res = comp.Open(HKEY_CLASSES_ROOT, m_strProgId + _T("\\CLSID"), KEY_READ); + if(res == ERROR_SUCCESS) { + m_strClassId = QueryValue(comp,_T("") ); + break; + } + else { + res = comp.Open(HKEY_CLASSES_ROOT, m_strProgId + _T("\\CurVer"), KEY_READ); + if(res != ERROR_SUCCESS) COMTHROW(E_NOTFOUND); + m_strProgId = QueryValue(comp, _T("") ); + comp.Close(); + } + } + if(m_strClassId.IsEmpty()) COMTHROW(E_NOTFOUND); + + LONG res = comp.Open(HKEY_CLASSES_ROOT, _T("CLSID\\") + m_strClassId + _T("\\InprocServer32"), KEY_READ); + CString m_strPath; + if(res == ERROR_SUCCESS) { + m_strPath = QueryValue(comp, _T("") ); + if (m_strPath == _T("mscoree.dll")) { + CString data; + ULONG count = 1024; + if (comp.QueryStringValue(_T("CodeBase"), data.GetBufferSetLength(count), &count) == ERROR_SUCCESS) { + data.ReleaseBuffer(); + m_strPath = data; + m_strPath = m_strPath.Right(m_strPath.GetLength() - 8); + m_strPath.Replace('/', '\\'); + } else { + count = 1024; + if (comp.QueryStringValue(_T("Assembly"), data.GetBufferSetLength(count), &count) == ERROR_SUCCESS) { + data.ReleaseBuffer(); + m_strPath = _T("GAC: "); + m_strPath += data; + } + } + } else { + // VS2012 puts quotes around the dll path + if (m_strPath[0] == L'\"') { + m_strPath = m_strPath.Right(m_strPath.GetLength() - 1); + } + if (m_strPath[m_strPath.GetLength() - 1] == L'\"') { + m_strPath = m_strPath.Left(m_strPath.GetLength() - 1); + } + } + } + CopyTo(m_strPath, pVal); + + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::get_AssociatedComponents(BSTR paradigm, + componenttype_enum type, regaccessmode_enum mode, VARIANT *progids) +{ + CHECK_OUT(progids); + type = (componenttype_enum)(type & COMPONENTTYPE_ALL); + + COMTRY + { + CStringArray ret; + + CString paradigmstr = paradigm; + + CStringArray components; + if (mode & REGACCESS_USER) + GetComponents_(HKEY_CURRENT_USER, components); + if (mode & REGACCESS_SYSTEM) + GetComponents_(HKEY_LOCAL_MACHINE, components); + for (int i = 0; i < components.GetSize(); i++) { + componenttype_enum comptype = COMPONENTTYPE_NONE; + PutInBstr progid(components.GetAt(i)); + CComBSTR desc; + COMTHROW(QueryComponent(progid, &comptype, &desc, REGACCESS_BOTH)); + if ((comptype & type) && IsAssociated_regaccess(components.GetAt(i), paradigmstr, mode)) { + ret.Add(components.GetAt(i)); + } + } + CopyTo(ret, progids); + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::get_AssociatedParadigms(BSTR progid, regaccessmode_enum mode, VARIANT *paradigms) +{ + CHECK_OUT(paradigms); + + COMTRY + { + + CStringArray ret; + CString progidstr = PutInCString(progid); + + VARIANT all_paradigms_; + VariantInit(&all_paradigms_); + COMTHROW(get_Paradigms(REGACCESS_BOTH, &all_paradigms_)); + ATL::CComSafeArray all_paradigms; + all_paradigms.Attach(all_paradigms_.parray); + ASSERT(all_paradigms.GetDimensions() == 1); + for (LONG i = all_paradigms.GetLowerBound(); i <= all_paradigms.GetUpperBound(); i++) { + BSTR paradigm = all_paradigms.GetAt(i); + if (IsAssociated_regaccess(progidstr, PutInCString(paradigm), mode)) { + ret.Add(static_cast(PutInCString(paradigm))); + } + } + + CopyTo(ret, paradigms); + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::Associate(BSTR progid, BSTR paradigm, regaccessmode_enum mode) +{ + COLE2CT progid2(progid); + CString pname(progid2); + COMTRY + { + bool somethingdone = false; + if(mode & RM_USER) { + CRegKey comp; + LONG res = comp.Open(HKEY_CURRENT_USER, rootreg + _T("\\Components\\") + pname); + CRegKey assocs; + if(res == ERROR_FILE_NOT_FOUND) { // try to create a shadow registry + CRegKey comp1, mga; + res = comp1.Open(HKEY_LOCAL_MACHINE, rootreg + _T("\\Components\\") + pname, KEY_READ); + if(!res) res = mga.Create(HKEY_CURRENT_USER, rootreg); + CRegKey comps; + if(!res) res = ( comps.Create(mga, _T("Components")) ); + if(!res) res = ( comp.Create(comps, pname) ); + } + if(res == ERROR_SUCCESS) res = assocs.Create(comp, _T("Associated")); + if(!res) assocs.SetStringValue( PutInCString(paradigm), _T("")); + if(!res) somethingdone = true; + if(res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; + ERRTHROW(res); + } + if(mode & (RM_SYS | RM_TEST)) { + CRegKey comp; + LONG res = comp.Open(HKEY_LOCAL_MACHINE, rootreg + _T("\\Components\\") + pname); + if(mode & RM_SYS) { + CRegKey assocs; + if(!res) res = assocs.Create(comp, _T("Associated")); + if(!res) res = assocs.SetStringValue( PutInCString(paradigm), _T("")); + } + else { + CRegKey assocs; + LONG res = assocs.Open(comp, _T("Associated")); + if(res != ERROR_SUCCESS && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + } + if(!res) somethingdone = true; + } + if(!somethingdone) COMTHROW(E_NOTFOUND); + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::Disassociate(BSTR progid, BSTR paradigm, regaccessmode_enum mode) +{ + COLE2CT progid2(progid); + CString pname(progid2); + COMTRY + { + if(mode & RM_USER) { + CRegKey comp; + LONG res = comp.Open(HKEY_CURRENT_USER, rootreg + _T("\\Components\\") + pname); + if (res == ERROR_FILE_NOT_FOUND) { + CRegKey comp1, mga; + res = comp1.Open(HKEY_LOCAL_MACHINE, rootreg + _T("\\Components\\") + pname, KEY_READ); + if(!res) res = mga.Create(HKEY_CURRENT_USER, rootreg); + CRegKey comps; + if(!res) res = ( comps.Create(mga, _T("Components")) ); + if(!res) res = ( comp.Create(comps, pname) ); + } + CRegKey assocs; + if(!res) res = assocs.Open(comp, _T("Associated")); + if (res == ERROR_FILE_NOT_FOUND) + res = assocs.Create(comp, _T("Associated")); + if (!res) + res = assocs.SetStringValue(PutInCString(paradigm), _T("Disabled")); + if(res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; + ERRTHROW(res); + } + if(mode & (RM_SYS | RM_TEST)) { + CRegKey comp; + LONG res = comp.Open(HKEY_LOCAL_MACHINE, rootreg + _T("\\Components\\") + pname); + CRegKey assocs; + if(!res) res = assocs.Open(comp, _T("Associated")); + if(mode & RM_SYS) { + if(!res) res = assocs.DeleteValue(PutInCString(paradigm)); + } + if(res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; + ERRTHROW(res); + } + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::IsAssociated(BSTR progid, BSTR paradigm, + VARIANT_BOOL *is_ass, VARIANT_BOOL *can_ass, regaccessmode_enum mode){ + CHECK_IN(progid); + CHECK_OUT(paradigm); + CString progidstr = PutInCString(progid); + CString parc = PutInCString(paradigm); + + COMTRY + { + componenttype_enum type; + + COMTHROW(QueryComponent(progid, &type, NULL, REGACCESS_PRIORITY)); + + if (is_ass) *is_ass = IsAssociated_regaccess(progidstr, parc, mode) ? VARIANT_TRUE : VARIANT_FALSE; + + if (can_ass) *can_ass = VARIANT_FALSE; + VARIANT_BOOL can = VARIANT_FALSE; + CComBSTR pars; + get_ComponentExtraInfo(mode,progid,CComBSTR(L"Paradigm"), &pars); + if(!pars && !(type & COMPONENTTYPE_SCRIPT)) { + CComPtr comp; + CreateMgaComponent(comp, progid); + if(!comp) COMTHROW(E_NOTFOUND); + COMTHROW(comp->get_Paradigm(&pars)); + put_ComponentExtraInfo(REGACCESS_BOTH, progid, CComBSTR(L"Paradigm"), pars); // just try + } + if(!pars) { + can = type & COMPONENTTYPE_PARADIGM_INDEPENDENT ? VARIANT_TRUE : VARIANT_FALSE; + } + else if(!wcscmp(pars, L"*")) { + can = VARIANT_TRUE; + } + else { + can = VARIANT_FALSE; + TokenizeParadigmString(PutInCString(pars), [¶digm, &can](const CString& paradigm2) { + if (static_cast(PutInCString(paradigm)) == paradigm2) + can = VARIANT_TRUE; + }); + } + if(can_ass) *can_ass = can; + + } + COMCATCH(;) +} + + +// --- Actions +typedef HRESULT (STDAPICALLTYPE *CTLREGPROC)(); + +STDMETHODIMP CMgaRegistrar::RegisterComponentLibrary(BSTR path, regaccessmode_enum mode) +{ + COMTRY + { + HMODULE hModule = LoadLibrary(CString(path)); + if( hModule == 0 ) { + HR_THROW(HRESULT_FROM_WIN32(GetLastError())); + } + + CTLREGPROC DLLRegisterServer = + (CTLREGPROC)::GetProcAddress(hModule, "DllRegisterServer"); + + if( DLLRegisterServer == NULL ) + { + FreeLibrary(hModule); + using namespace MgaDotNetServices; + _RegistrarPtr reg; + COMTHROW(reg.CreateInstance(L"MGA.DotNetRegistrar")); + //COMTHROW(reg.CreateInstance(L"{0BB0C371-6835-4F09-A156-0BD8E3DF8216}", NULL, CLSCTX_INPROC)); + reg->Register(_bstr_t(path)); + + return S_OK; + } + else + { + //c++ dll: + COMTHROW( DLLRegisterServer() ); + FreeLibrary(hModule); + } + + + CComObjPtr typelib; + COMTHROW( LoadTypeLibEx(path, REGKIND_REGISTER, PutOut(typelib)) ); + + UINT index = typelib->GetTypeInfoCount(); + while( index-- > 0 ) + { + CComObjPtr typeinfo; + COMTHROW( typelib->GetTypeInfo(index, PutOut(typeinfo)) ); + + TYPEATTR *typeattr = NULL; + COMTHROW( typeinfo->GetTypeAttr(&typeattr) ); + ASSERT( typeattr != NULL ); + + try + { + if( typeattr->typekind == TKIND_COCLASS ) + { + CComPtr component; + // if( SUCCEEDED(typeinfo->CreateInstance(NULL, + // __uuidof(IMgaComponent), (void**)PutOut(component))) ) + if (SUCCEEDED(CreateMgaComponent(component, typeattr->guid))) + { + CComBstrObj desc; + COMTHROW( component->get_ComponentName(PutOut(desc)) ); + + componenttype_enum type; + COMTHROW( component->get_ComponentType(&type) ); + + LPOLESTR olestr; + COMTHROW( ProgIDFromCLSID(typeattr->guid, &olestr) ); + CComBstrObj progid(olestr); + { + LPOLESTR pp = olestr + wcslen(olestr) - 2; + if(wcslen(olestr) > 2 && + pp[0] == '.' && + isdigit(pp[1]) ) { + pp[0] = 0; + CLSID tempGUID; + HRESULT hr = CLSIDFromProgID(olestr, &tempGUID); + if(hr == S_OK && tempGUID == typeattr->guid) { + progid = CComBstrObj(olestr); + } + } + } + + COMTHROW( RegisterComponent(progid, type, desc, mode) ); + CoTaskMemFree(olestr); + + CString paradigms; + COMTHROW( component->get_Paradigm(PutOut(paradigms)) ); + + TokenizeParadigmString(paradigms, [this,&mode,&progid](const CString& par){ + COMTHROW(Associate(progid, PutInBstr(par), mode)); + }); + } + } + + typeinfo->ReleaseTypeAttr(typeattr); + } + catch(hresult_exception &) + { + typeinfo->ReleaseTypeAttr(typeattr); + throw; + } + } + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::UnregisterComponentLibrary(BSTR path, regaccessmode_enum mode) +{ + COMTRY + { + CComObjPtr typelib; + COMTHROW( LoadTypeLibEx(path, REGKIND_NONE, PutOut(typelib)) ); + + UINT index = typelib->GetTypeInfoCount(); + while( index) //WAS: while( --index >= 0 ) // was an infinite loop with UINT + { + --index; + CComObjPtr typeinfo; + COMTHROW( typelib->GetTypeInfo(index, PutOut(typeinfo)) );// index parameter with the range of 0 to GetTypeInfoCount() –1. + + TYPEATTR *typeattr = NULL; + COMTHROW( typeinfo->GetTypeAttr(&typeattr) ); + ASSERT( typeattr != NULL ); + + try + { + if( typeattr->typekind == TKIND_COCLASS ) + { + LPOLESTR olestr; + if( SUCCEEDED(ProgIDFromCLSID(typeattr->guid, &olestr)) ) + { + CComBstrObj progid(olestr); + COMTHROW( UnregisterComponent(progid, mode) ); + } + } + + typeinfo->ReleaseTypeAttr(typeattr); + } + catch(hresult_exception &) + { + typeinfo->ReleaseTypeAttr(typeattr); + throw; + } + } + + // TODO: unregister the type library + } + COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::put_ParadigmExtraInfo(regaccessmode_enum mode, BSTR paradigmName, BSTR paradigmVersionGuid, BSTR name, BSTR newVal) +{ + CString paradigmNameStr = PutInCString(paradigmName); + CString paradigmGuidStr = PutInCString(paradigmVersionGuid); + CString nameStr = PutInCString(name); + + COMTRY + { + if (mode & RM_SYS) { + CRegKey para; + LPCTSTR regpath = rootreg + _T("\\Paradigms\\") + paradigmNameStr + _T("\\") + paradigmGuidStr; + LONG res = para.Open(HKEY_LOCAL_MACHINE, regpath, KEY_WRITE); + if (res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if (res == ERROR_SUCCESS) { + if (!newVal) { para.DeleteValue(nameStr); } + else { para.SetStringValue(nameStr, PutInCString(newVal)); } + } + } + if (mode & RM_USER) { + CRegKey para; + LPCTSTR regpath = rootreg + _T("\\Paradigms\\") + paradigmNameStr + _T("\\") + paradigmGuidStr; + LONG res = para.Open(HKEY_CURRENT_USER, regpath, KEY_WRITE); + if (res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if (res == ERROR_SUCCESS) { + if (!newVal) { para.DeleteValue(nameStr); } + else { para.SetStringValue(nameStr, PutInCString(newVal)); } + } + } + } COMCATCH(;) +} + +STDMETHODIMP CMgaRegistrar::get_ParadigmExtraInfo(regaccessmode_enum mode, BSTR paradigmName, BSTR paradigmVersionGuid, BSTR name, BSTR * pVal) +{ + CHECK_OUT(pVal); + + if ((mode & RM_BOTH) == RM_BOTH) { + HRESULT res; + res = this->get_ParadigmExtraInfo(REGACCESS_USER, paradigmName, paradigmVersionGuid, name, pVal); + CString val = PutInCString(*pVal); + if (val.IsEmpty()) + res = this->get_ParadigmExtraInfo(REGACCESS_SYSTEM, paradigmName, paradigmVersionGuid, name, pVal); + return res; + } + + CString paradigmNameStr = PutInCString(paradigmName); + CString paradigmGuidStr = PutInCString(paradigmVersionGuid); + CString nameStr = PutInCString(name); + + COMTRY + { + HKEY hive = (mode & RM_SYS ? HKEY_LOCAL_MACHINE : (mode & RM_USER ? HKEY_CURRENT_USER : NULL)); + if (hive != NULL) + { + CRegKey para; + LPCTSTR regpath = rootreg + _T("\\Paradigms\\") + paradigmNameStr + _T("\\") + paradigmGuidStr; + LONG res = para.Open(hive, regpath, KEY_READ); + + if (res != ERROR_SUCCESS && res != ERROR_ACCESS_DENIED && res != ERROR_FILE_NOT_FOUND) ERRTHROW(res); + if (res == ERROR_SUCCESS) { + ULONG count = 0; + if (para.QueryStringValue(nameStr, NULL, &count) == ERROR_SUCCESS) { + CString retVal; + if (para.QueryStringValue(nameStr, retVal.GetBufferSetLength(count), &count) == ERROR_SUCCESS) { + retVal.ReleaseBuffer(); + CopyTo(retVal, pVal); + return S_OK; + } + } + } + } + return E_NOTFOUND; + } + COMCATCH(;) +} diff --git a/GME/MgaUtil/MgaRegistrar.h b/GME/MgaUtil/MgaRegistrar.h index 46e1b4d6..99085c40 100644 --- a/GME/MgaUtil/MgaRegistrar.h +++ b/GME/MgaUtil/MgaRegistrar.h @@ -8,8 +8,8 @@ class ATL_NO_VTABLE CMgaRegistrar : public CComObjectRootEx, public CComCoClass, - public IDispatchImpl, - public ISupportErrorInfoImpl<&__uuidof(IMgaRegistrar)>, + public IDispatchImpl, + public ISupportErrorInfoImpl2<&__uuidof(IMgaRegistrar), &__uuidof(IMgaRegistrar2)>, public IGMEVersionInfoImpl { public: @@ -20,7 +20,8 @@ DECLARE_PROTECT_FINAL_CONSTRUCT() BEGIN_COM_MAP(CMgaRegistrar) COM_INTERFACE_ENTRY(IMgaRegistrar) - COM_INTERFACE_ENTRY(IDispatch) + COM_INTERFACE_ENTRY(IMgaRegistrar2) + COM_INTERFACE_ENTRY2(IDispatch, IMgaRegistrar2) COM_INTERFACE_ENTRY(ISupportErrorInfo) COM_INTERFACE_ENTRY_IID(__uuidof(IGMEVersionInfo), IGMEVersionInfoImpl) END_COM_MAP() @@ -141,6 +142,13 @@ END_COM_MAP() STDMETHOD(RegisterComponentLibrary)(BSTR path, regaccessmode_enum mode); STDMETHOD(UnregisterComponentLibrary)(BSTR path, regaccessmode_enum mode); + + // --- IMgaRegistrar2 + + STDMETHOD(put_ParadigmExtraInfo)(regaccessmode_enum mode, BSTR paradigmName, BSTR paradigmVersionGuid, BSTR name, BSTR newVal); + STDMETHOD(get_ParadigmExtraInfo)(regaccessmode_enum mode, BSTR paradigmName, BSTR paradigmVersionGuid, BSTR name, BSTR* pVal); + STDMETHOD(SetParadigmExtraInfoDisp)(BSTR paradigmName, BSTR paradigmVersionGuid, BSTR name, BSTR newVal, regaccessmode_enum mode = REGACCESS_SYSTEM) { return this->put_ParadigmExtraInfo(mode, paradigmName, paradigmVersionGuid, name, newVal); } + STDMETHOD(GetParadigmExtraInfoDisp)(BSTR paradigmName, BSTR paradigmVersionGuid, BSTR name, BSTR* pVal) { return this->get_ParadigmExtraInfo(REGACCESS_BOTH, paradigmName, paradigmVersionGuid, name, pVal); } }; #endif//MGA_MGAREGISTRAR_H diff --git a/GME/MgaUtil/MgaUtil.vcxproj b/GME/MgaUtil/MgaUtil.vcxproj index 1ed437c7..ecc06cdf 100644 --- a/GME/MgaUtil/MgaUtil.vcxproj +++ b/GME/MgaUtil/MgaUtil.vcxproj @@ -115,6 +115,7 @@ Use Level3 ProgramDatabase + /w34189 %(AdditionalOptions) NDEBUG;%(PreprocessorDefinitions) diff --git a/GME/MgaUtil/MgaUtilLib.idl b/GME/MgaUtil/MgaUtilLib.idl index 43e5f7ec..0a756950 100644 --- a/GME/MgaUtil/MgaUtilLib.idl +++ b/GME/MgaUtil/MgaUtilLib.idl @@ -38,7 +38,8 @@ library MGAUtilLib ] coclass MgaRegistrar { - [default] interface IMgaRegistrar; + [default] interface IMgaRegistrar2; + interface IMgaRegistrar; interface IGMEVersionInfo; }; diff --git a/GME/MgaUtil/StdAfx.h b/GME/MgaUtil/StdAfx.h index b2187785..c8bf03df 100644 --- a/GME/MgaUtil/StdAfx.h +++ b/GME/MgaUtil/StdAfx.h @@ -109,6 +109,18 @@ typedef GMEInterfaceVersion_enum GMEInterfaceVersion; #include "Resource.h" regaccessmode_enum regacc_translate(int x); + +template +class ATL_NO_VTABLE ISupportErrorInfoImpl2 : + public ISupportErrorInfo +{ +public: + STDMETHOD(InterfaceSupportsErrorInfo)(_In_ REFIID riid) + { + return (InlineIsEqualGUID(riid, *piid1) || InlineIsEqualGUID(riid, *piid2)) ? S_OK : S_FALSE; + } +}; + //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. diff --git a/Install/GME_bin.wxs b/Install/GME_bin.wxs index 07f31b07..79248be9 100644 --- a/Install/GME_bin.wxs +++ b/Install/GME_bin.wxs @@ -511,6 +511,7 @@ +