Click here to Skip to main content
15,891,033 members
Articles / Desktop Programming / MFC

Resource ID Organiser Add-In for Visual C++ 5.0/6.0/.NET

Rate me:
Please Sign up or sign in to vote.
4.98/5 (71 votes)
10 Jan 2005CPOL25 min read 532.5K   12.1K   201  
An application/add-in to organise and renumber resource symbol IDs
/************************************************************************
 *
 *             Resource ID Organiser Add-In for Visual C++.NET
 *
 * (c) Copyright 2000-2005 by Riverblade Limited (UK). All rights reserved.
 *
 ************************************************************************
 *                                                                       
 *  Description : CResOrgApp - application class
 *                                                                       
 *  Compiler    : Microsoft Visual C++ 6.0, Service Pack 3 or later
 *                Microsoft Visual C++ .NET 2003
 *                                                                       
 *  Target                                                               
 *  Environment : Windows 98/NT/2000/XP
 *
 *  NOTE:
 *
 *    This software is provided "as is". All title and copyrights in and
 *    to the software, including but not limited to any images, text etc.
 *    etc. incorporated into it, are the property of Anna-Jayne Metcalfe
 *    and Riverblade Limited, except where acknowledged otherwise.
 *
 *    Your may freely use this code in your own products, PROVIDED
 *    this notice is not removed or modified.
 *
 *    Please visit http://www.riverblade.co.uk/products/resorg
 *    or email support@riverblade.co.uk for latest updates and product support 
 *
 ************************************************************************
 *
 *   MODIFICATION HISTORY:
 *
 *           This is a controlled document. See project configuration
 *           control tool for latest version and full version history.
 *
 *    $Archive: /Projects/AddIns/ResOrg/ResOrgApp/ResOrgApp.cpp $
 *   $Revision: 46 $
 *       $Date: 30/12/04 21:03 $
 *     $Author: Anna $
 *
 *    $History: ResOrgApp.cpp $
 * 
 * *****************  Version 46  *****************
 * User: Anna         Date: 30/12/04   Time: 21:03
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * Corrected registry key initialisation
 * 
 * *****************  Version 45  *****************
 * User: Anna         Date: 28/12/04   Time: 9:37
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * 1.  Only symbols display child frames now contain a splitter window
 * 2.  Corrected view class for HTML displays
 * 3.  CResOrgApp no longer calls EnableShellOpen() and
 * RegisterShellFileTypes()...this prevents header files from being
 * erroneously registered for opening with ResOrg
 * 4.  Updated banner
 * 
 * *****************  Version 44  *****************
 * User: Anna         Date: 13/12/04   Time: 4:11
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * 1.  Changed company registry key to Riverblade
 * 2.  Updated file banner
 * 
 * *****************  Version 43  *****************
 * User: Anna         Date: 21/08/04   Time: 18:56
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * The application now uses CResOrgMDIChildWnd for MDI child frames
 * instead of CChildFrame (which has been deleted)
 * 
 * *****************  Version 42  *****************
 * User: Anna         Date: 30/01/03   Time: 21:05
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * Moved common application class functionality to CResOrgCoreApp
 * 
 * *****************  Version 41  *****************
 * User: Anna         Date: 19/01/03   Time: 17:30
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * The menu for the multi-file symbols document template is now correctly
 * initialised with toolbar images
 * 
 * *****************  Version 40  *****************
 * User: Anna         Date: 2/01/03    Time: 0:24
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * Initial support for multi-symbol file editing
 * 
 * *****************  Version 39  *****************
 * User: Anna         Date: 25/11/02   Time: 20:26
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * 1.  Updated website address on file banner
 * 2.  Added a call to InitCommonControls() to CResOrgApp::InitInstance()
 * while experimenting with CommCtl v6 Manifests
 * 
 * *****************  Version 38  *****************
 * User: Anna         Date: 22/10/02   Time: 13:28
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * Changed name/mail address (at last!)
 * 
 * *****************  Version 37  *****************
 * User: Andy         Date: 11/08/02   Time: 16:56
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * Set the name of the helpfile explicitly for compatibility with
 * ResOrg.NET and debug builds
 * 
 * *****************  Version 36  *****************
 * User: Andy         Date: 12/06/02   Time: 22:58
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * The add-in load prompt now only runs in the VC 5.0/6.0 version of the
 * app
 * 
 * *****************  Version 35  *****************
 * User: Andy         Date: 11/06/02   Time: 0:31
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * CResOrgApp::InitInstance() now changes the name of the application for
 * the .NET build
 * 
 * *****************  Version 34  *****************
 * User: Andy         Date: 30/05/02   Time: 17:00
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * Use the VS.NET visual style when running the VC6 version on WinXP
 * systems
 * 
 * *****************  Version 33  *****************
 * User: Andy         Date: 27/05/02   Time: 17:40
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * Updated file banner
 * 
 * *****************  Version 32  *****************
 * User: Andy         Date: 27/05/02   Time: 17:32
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * Modifications for compatibility with Visual C++ 7.0 (.NET):
 * 
 * 1.  CWinApp::Enable3DControls() is now only called if _MSC_VER is <
 * 1300 (i.e. Visual C++ 6.0)
 * 2.   CResOrgApp::OnCmdOpenWorkspace() now uses a resizeable file open
 * dialog when compiled with Visual C++ 7.0 (BXFileDialog isn't used in
 * the Visual C++ 7.0 build)
 * 
 * *****************  Version 31  *****************
 * User: Andy         Date: 17/05/02   Time: 22:15
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * Modifications for compatibility with Visual C++.NET
 * 
 * *****************  Version 30  *****************
 * User: Andy         Date: 10/05/02   Time: 16:04
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * Added "Use Office XP style menus" option
 * 
 * *****************  Version 29  *****************
 * User: Andy         Date: 21/04/02   Time: 20:41
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * Use Office XP style menus regardless of the target platform (if there's
 * a demand we can make this an option)
 * 
 * *****************  Version 28  *****************
 * User: Andy         Date: 1/24/02    Time: 10:16p
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * Added support for VC7 workspaces and project files
 * 
 * *****************  Version 27  *****************
 * User: Andy         Date: 12/28/01   Time: 12:39a
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * "Options" are now initialised BEFORE configuring document templates
 * etc.
 * 
 * *****************  Version 26  *****************
 * User: Andy         Date: 11/15/01   Time: 1:41p
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * CResOrgApp::OnCmdResOrgUpdateCheckCompleted() now calls
 * CResOrgptions::OnVersionCheckCompleted() with appropriate parameters
 * 
 * *****************  Version 25  *****************
 * User: Andy         Date: 11/10/01   Time: 12:12p
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * In debug builds the splash screen now stays visible until dismissed (so
 * I can debug it!)
 * 
 * *****************  Version 24  *****************
 * User: Andy         Date: 10/22/01   Time: 11:15a
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * Added an option [through an override of CDocument::OpenDocumentFile()]
 * to call CResOrgSymbolsDoc::CheckNextSymbolValues() when a symbol file
 * is opened. The call is made only if the
 * CResOrgApp::m_bCheckNextSymbolValues flag is TRUE
 * 
 * *****************  Version 23  *****************
 * User: Andy         Date: 24/07/01   Time: 11:40
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * Corrected the Mailing List Prompt to point at the new mailing list
 * 
 * *****************  Version 22  *****************
 * User: Andy         Date: 8/07/01    Time: 16:57
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * Integrated BXFileDialog module (replaces Office2KDlg)
 * 
 * *****************  Version 21  *****************
 * User: Andy         Date: 2/07/01    Time: 22:46
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * Added additional web commands; all now obtain URLs from options
 * 
 * *****************  Version 20  *****************
 * User: Andy         Date: 5/06/01    Time: 19:31
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * Bug fix for context help support
 * 
 * *****************  Version 19  *****************
 * User: Andy         Date: 2/06/01    Time: 19:49
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * Corrected OnUpdateWindowClose() so it works if only non-Symbol displays
 * are open
 * 
 * *****************  Version 18  *****************
 * User: Andy         Date: 2/06/01    Time: 16:59
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * CResOrgApp::CloseOpenDocuments() now closes ALL documents, not just
 * symbol docs
 * 
 * *****************  Version 17  *****************
 * User: Andy         Date: 2/06/01    Time: 16:52
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * Dropped MRU to 9 entries (was 10 before)
 * 
 * *****************  Version 16  *****************
 * User: Andy         Date: 26/05/01   Time: 15:25
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * 1.  Help support
 * 2.  Added a prompt to ask about subscribing to the Mailing List
 * 
 * *****************  Version 15  *****************
 * User: Andy         Date: 22/05/01   Time: 16:00
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * Minor bug fix
 * 
 * *****************  Version 14  *****************
 * User: Andy         Date: 22/05/01   Time: 6:51
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * 1.  Added "ResOrg Mailing List" command to the Help Menu
 * 2.  Tidied up initialisation of document templates
 * 
 * *****************  Version 13  *****************
 * User: Andy         Date: 16/05/01   Time: 21:06
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * Added latest version checking
 * 
 * *****************  Version 12  *****************
 * User: Andy         Date: 12/05/01   Time: 6:49
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * Check whether DevStudio is available before asking whether to load the
 * add-in
 * 
 * *****************  Version 11  *****************
 * User: Andy         Date: 26/04/01   Time: 19:46
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * 1.  Added additional "ResOrg on the Web" commands
 * 2.  Renamed Resource.h to ResOrgAddIn_Res.h
 * 
 * *****************  Version 10  *****************
 * User: Andy         Date: 21/04/01   Time: 7:33
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * 1.  Added splash screen
 * 2.  The workspace display is now shown when a workspace is opened, and
 * hidden when it is closed
 * 
 * *****************  Version 9  *****************
 * User: Andy         Date: 5/04/01    Time: 6:09
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * Added check for version expiry (conditional compilation)
 * 
 * *****************  Version 8  *****************
 * User: Andy         Date: 2/04/01    Time: 17:52
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * Bug fixes to "Recent Workspaces" code
 * 
 * *****************  Version 7  *****************
 * User: Andy         Date: 5/03/01    Time: 19:15
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * 1.  Added workspace open/close related code (some of which was in the
 * mainframe previously)
 * 2.  Tidied up the code a bit
 * 
 * *****************  Version 6  *****************
 * User: Andy         Date: 2/03/01    Time: 17:19
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * Tidied up the code a bit
 * 
 * *****************  Version 5  *****************
 * User: Andy         Date: 17/02/01   Time: 7:13
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * 1.  CResOrgSymbolsView => CResOrgSymbolsListView
 * 2.  When checking the path to the add-in on startup, the path used will
 * be that of the app (this should ensure that the right version of the
 * add-in is loaded)
 * 
 * *****************  Version 4  *****************
 * User: Andy         Date: 5/12/00    Time: 20:37
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * 1.  Added "ResOrg on the Web" support
 * 2.  Raised version to 1.2.1
 * 
 * *****************  Version 3  *****************
 * User: Andy         Date: 3/12/00    Time: 8:32
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * 1.  Updated registry key
 * 2.  Added a prompt dialog to ask whether to load the ResOrg add-in when
 * the application starts
 * 
 * *****************  Version 2  *****************
 * User: Andy         Date: 29/11/00   Time: 18:37
 * Updated in $/Projects/AddIns/ResOrg/ResOrgApp
 * 1.  Moved Office2KDlg code to its own DLL
 * 2.  Added file banners
 *
 * $Nokeywords: $
 *
 ************************************************************************/

#include "StdAfx.h"
#include <AfxHtml.h>

#include "ResOrgApp.h"

#include "ResOrgAddInLoadPrompt.h"
#include "ResOrgAppProjectsDoc.h"
#include "MainFrame.h"



#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif



/////////////////////////////////////////////////////////////////////////////
// The one and only CResOrgApp object

CResOrgApp theApp;



/////////////////////////////////////////////////////////////////////////////
// CResOrgApp

BEGIN_MESSAGE_MAP(CResOrgApp, CResOrgApp_BASE)
	//{{AFX_MSG_MAP(CResOrgApp)
	ON_COMMAND(				ID_WORKSPACE_OPEN,			OnCmdOpenWorkspace)
	ON_COMMAND(				ID_WORKSPACE_CLOSE,			OnCmdCloseWorkspace)
	ON_UPDATE_COMMAND_UI(	ID_WORKSPACE_CLOSE,			OnUpdateCloseWorkspace)
	ON_COMMAND(				ID_APP_ABOUT,				OnCmdAbout)
	//}}AFX_MSG_MAP

	// Standard file based document commands
	ON_COMMAND(				ID_FILE_NEW,				CResOrgApp_BASE::OnFileNew)
	ON_COMMAND(				ID_FILE_OPEN,				CResOrgApp_BASE::OnFileOpen)

	// Standard print setup command
	ON_COMMAND(				ID_FILE_PRINT_SETUP,		CResOrgApp_BASE::OnFilePrintSetup)

	// MRU - most recently used workspace menu
	ON_UPDATE_COMMAND_UI(	ID_WORKSPACE_MRU_FILE1,		OnUpdateRecentWorkspaceMenu)
	ON_COMMAND_EX_RANGE(	ID_WORKSPACE_MRU_FILE1,
							ID_WORKSPACE_MRU_FILE1+15,	OnCmdOpenRecentWorkspace)


END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CResOrgApp construction/destruction

CResOrgApp::CResOrgApp(void)
{
	m_plistRecentWorkspaces		= NULL;
	m_pProjectsDoc				= NULL;	
}


CResOrgApp::~CResOrgApp(void)
{
	if (NULL != m_pProjectsDoc)
	{
		// m_pProjectsDoc will auto-delete when the last view (the
		// Workspace) is removed. Hence, we don't need to do anything
		// here; this code is included for completeness
		m_pProjectsDoc = NULL;
	}
	if (NULL != m_plistRecentWorkspaces)
	{
		delete m_plistRecentWorkspaces;
	}
}


/////////////////////////////////////////////////////////////////////////////
// CResOrgApp virtual overrides

BOOL CResOrgApp::InitInstance(void)
{
	AfxEnableControlContainer();

	// 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.

	InitCommonControls();

#if _MSC_VER < 1300					// Enable3dControls() is depreciated in VC 7.0 (.NET)
	#ifdef _AFXDLL
		Enable3dControls();			// Call this when using MFC in a shared DLL
	#else
		Enable3dControlsStatic();	// Call this when linking to MFC statically
	#endif
#endif

	// Change the registry key under which our settings are stored.
	SetRegistryKey(_T("Riverblade") );

	#if _MSC_VER >= 1300
		// Change the name of the application
		// The CWinApp destructor will free the memory for us
		free((void*)m_pszAppName);

		CString sAppTitle;
		sAppTitle.LoadString(AFX_IDS_APP_TITLE);

		m_pszAppName = _tcsdup( sAppTitle + _T(" .NET") );

		::AfxGetModuleState()->m_lpszCurrentAppName = m_pszAppName;
	#endif

	// Check the version of the common controls library.
	// (we need at least v5.80 to support Wizard97)
	CNGModuleVersion ver;
	ver.GetFileVersionInfo( _T("comctl32.dll") );

    DWORD dwTargetVerMS = MAKELONG(80, 5);

    if (ver.dwFileVersionMS < dwTargetVerMS)
    {
		CString sVersion = ver.GetValue( _T("FileVersion") );

		DoCommonControlsVersionPrompt(sVersion);

        return FALSE;
    }

	// Set the help file name. This is needed for the debug and .NET builds
	// as the exe has a different name
	SetHelpFileName( _T("ResOrg.hlp") );


	LoadStdProfileSettings(9);  // Load standard INI file options (including MRU)

	m_plistRecentWorkspaces = new CRecentFileList(	0,
													_T("Recent Workspace List"),
													_T("Workspace%d"),
													10);
	m_plistRecentWorkspaces->ReadList();

	#if _MSC_VER < 1300		// BXFileDialog doesn't work with VC7 yet
		m_pDocManager = new BXFileDialogDocManager;
		ASSERT(NULL != m_pDocManager);

		if (NULL != m_pDocManager)
		{
			DWORD dwVersion		= LOWORD(::GetVersion() );

			DWORD dwMajor		= LOBYTE(dwVersion);
			DWORD dwMinor		= HIBYTE(dwVersion);
			DWORD dwUseableVer	= (dwMajor << 8) + dwMinor;

			if (dwUseableVer >= 0x501)
			{
				// Use the VS.NET visual style on WinXP and later
				static_cast<BXFileDialogDocManager*>(m_pDocManager)->SetAppearance(BXFileDialog::APPEARANCE_VSDOTNET);
			}
		}
	#endif

	// Read options from the registry
	Options.Initialise();

	// Use Office XP style menus if selected
	CCJMenu::SetMenuDrawMode(Options.UseXpStyleMenus() ? CCJMenu_DRAWMODE_XP : CCJMenu_DRAWMODE_ORIGINAL);

	// Register the application's document templates.  Document templates
	// serve as the connection between documents, frame windows and views.
	//
	// This is the template for resource symbol files
	CMultiDocTemplate* pDocTemplate;
	pDocTemplate = new CMultiDocTemplate(
		IDR_SYMBOL_FILE_TYPE,
		RUNTIME_CLASS(CResOrgSymbolsDoc),
		RUNTIME_CLASS(CResOrgMDIChildSplitWnd),		// custom MDI child frame
		RUNTIME_CLASS(CResOrgSymbolsListView) );

	AddDocTemplate(pDocTemplate);

	m_pMultiSymbolFileTemplate = new CMultiDocTemplate(
		IDR_SYMBOL_FILE_TYPE,
		RUNTIME_CLASS(CResOrgSymbolsDocMultiFile),
		RUNTIME_CLASS(CResOrgMDIChildSplitWnd),		// custom MDI child frame
		RUNTIME_CLASS(CResOrgSymbolsListView) );

	m_pHtmlDocTemplate = new CMultiDocTemplate(
		IDR_HTML_TYPE,
		RUNTIME_CLASS(CResOrgHtmlDoc),
		RUNTIME_CLASS(CResOrgMDIChildWnd),
		RUNTIME_CLASS(CResOrgHtmlView) );

	// Create the "Projects" document
	m_pProjectsDoc = new CResOrgAppProjectsDoc;
	ASSERT_KINDOF( CDocument, m_pProjectsDoc );

	// Create main MDI Frame window
	CMainFrame* pMainFrame = new CMainFrame;
	if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
	{
		return FALSE;
	}

	pMainFrame->SetTitle(m_pszAppName);
	pMainFrame->SetWindowText(m_pszAppName);

	m_pMainWnd = pMainFrame;

	// Initialize the cool menus...
	UINT nToolBars[] =	{
							IDR_MAINFRAME
						}; // can be many tool bars
		
	pMainFrame->InitializeMenu(	pDocTemplate,
								IDR_SYMBOL_FILE_TYPE,
								nToolBars,
								1,			
								IDR_MAINFRAME);
	
	pMainFrame->InitializeMenu(	m_pMultiSymbolFileTemplate,
								IDR_SYMBOL_FILE_TYPE,
								nToolBars,
								1,			
								IDR_MAINFRAME);
	
	pMainFrame->InitializeMenu(	m_pHtmlDocTemplate,
								IDR_HTML_TYPE,
								nToolBars,
								1,			
								IDR_MAINFRAME);
	// Enable drag/drop open
	m_pMainWnd->DragAcceptFiles();

	// Enable DDE Execute open
	//EnableShellOpen();
	//RegisterShellFileTypes(TRUE);

	// Parse command line for standard shell commands, DDE, file open
	CCommandLineInfo cmdInfo;
	ParseCommandLine(cmdInfo);

	// Create splash window if not run silently
	if (cmdInfo.m_bShowSplash)
	{
		ShowSplashScreen();
	}
	// Dispatch commands specified on the command line
	if (cmdInfo.m_nShellCommand == CCommandLineInfo::FileNew)
	{
		cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing;
	}
	if (!ProcessShellCommand(cmdInfo))
	{
		return FALSE;
	}
	// The main window has been initialized, so show and update it.
	pMainFrame->ShowWindow(m_nCmdShow);
	pMainFrame->UpdateWindow();


	#ifdef _RESORG_EXPIRY_DATE
		::DoVersionExpiryCheck();
	#endif

	#if _MSC_VER < 1300		// The VC7 build of the app can't load the corresponding add-in
		CString sAddInName;
		sAddInName.LoadString(IDS_RESORG_LONGNAME);

		CDSAddInLoader loader(sAddInName);
		if (!loader.IsLoaded() && loader.CanLoad() )
		{
			// If ResOrg hasn't been loaded before, work out default values
			// for the filename and description fields
			CNGSplitPath split(m_pszHelpFilePath);

			CString sFileName = split.GetDrive() +
								split.GetDirectory() +
								_T("ResOrgAddIn.dll");

			if (!::FileExists(sFileName) )
			{
				sFileName = _T("");
			}

			// If necessary, ask the user whether to load the Add-In
			if (!sFileName.IsEmpty() && Options.AskAboutLoadingAddIn() )
			{
				CResOrgAddInLoadPrompt dlg;
				if (IDYES == dlg.DoModal())
				{
					CString sDescription = loader.GetDescription();
					if (sDescription.IsEmpty())
					{
						sDescription.LoadString(IDS_RESORG_DESCRIPTION);
					}
					loader.SetDescription(sDescription);
					loader.SetPathName(sFileName);
					loader.Load(TRUE);
				}
				if (dlg.m_bDontAskAgain)
				{
					Options.AskAboutLoadingAddIn(FALSE);
				}
			}
		}
	#endif

	if (Options.IsMailingListPromptEnabled() )
	{
		Options.EnableMailingListPrompt(FALSE);		// Only ask once

		if (IDYES == DoMailingListQuery())
		{
			::ShellExecute(	::GetDesktopWindow(),
							_T("open"),
							Options.GetMailingListURL(),
							NULL,
							NULL,
							SW_SHOWNORMAL);
		}
	}
	Options.DoVersionCheck();

	return TRUE;
}


/******************************************************************************
 *	Idle processing handler
 *
 ******************************************************************************/

BOOL CResOrgApp::OnIdle(LONG lCount) 
{
	// Call base class idle implementation first...
	BOOL bResult = CResOrgApp_BASE::OnIdle(lCount);

#ifndef _DEBUG
	// ...then do our stuff
	if ( (NULL != m_pwndSplash) && (NULL != m_pwndSplash->GetSafeHwnd()) )
	{
		if (::GetTickCount() - m_dwSplashTime > SPLASHWND_DURATION)
		{
			// Timeout expired, destroy the splash window
			KillSplashScreen();

			// NOTE: don't set bResult to FALSE,
			// (CResOrgApp_BASE::OnIdle may have returned TRUE)
		}
		else
		{
			// Check again later...
			bResult = TRUE;
		}
	}
#endif
	return bResult;
}


/******************************************************************************
 *	Destroy the splash window if a keypress or mouse button event is detected
 *
 ******************************************************************************/

BOOL CResOrgApp::PreTranslateMessage(MSG* pMsg) 
{
	BOOL bResult = CResOrgApp_BASE::PreTranslateMessage(pMsg);

	if ( (NULL != m_pwndSplash) &&
		(NULL != m_pwndSplash->GetSafeHwnd()) &&
		(WM_KEYDOWN == pMsg->message ||
		 WM_SYSKEYDOWN == pMsg->message ||
		 WM_LBUTTONDOWN == pMsg->message ||
		 WM_RBUTTONDOWN == pMsg->message ||
		 WM_MBUTTONDOWN == pMsg->message ||
		 WM_NCLBUTTONDOWN == pMsg->message ||
		 WM_NCRBUTTONDOWN == pMsg->message ||
		 WM_NCMBUTTONDOWN == pMsg->message ))
	{
		KillSplashScreen();
	}
	return bResult;
}


void CResOrgApp::WinHelp(DWORD dwData, UINT nCmd)
{
	if (m_bHelpMode)
	{
		CWnd* pMainWnd = AfxGetMainWnd();
		ASSERT_VALID(pMainWnd);

		// return global app help mode state to FALSE (backward compatibility)
		m_bHelpMode = FALSE;
		pMainWnd->PostMessage(WM_KICKIDLE); // trigger idle update

		pMainWnd->WinHelp(dwData, HELP_CONTEXTPOPUP);
	}
	else
	{
		CResOrgApp_BASE::WinHelp(dwData, nCmd);
	}
}


int CResOrgApp::ExitInstance(void)
{
	// If a version check is running, Wait until it finishes
	// before exiting (by now the main window has gone)
	Options.OnExit();

	int nResult = CResOrgApp_BASE::ExitInstance();

	if (NULL != m_plistRecentWorkspaces)
	{
		// Write the workspace MRU list back to the registry
		m_plistRecentWorkspaces->WriteList();
	}
	return nResult;
}


/////////////////////////////////////////////////////////////////////////////
// CResOrgApp operations

BOOL CResOrgApp::OpenWorkspace(const CString& sPathName)
{
	if (DoCloseAllWindowsQuery() && m_pProjectsDoc->OnOpenDocument(sPathName) )
	{
		AddToRecentWorkspacesList(sPathName);

		CMainFrame* pMainFrame = (CMainFrame*)m_pMainWnd;
		pMainFrame->ShowWorkspace(TRUE);

		m_pProjectsDoc->UpdateAllViews(NULL, SHOW_WORKSPACE);

		return TRUE;
	}
	return FALSE;
}


BOOL CResOrgApp::CloseWorkspace(void)
{
	if (DoCloseAllWindowsQuery() )
	{
		CMainFrame* pMainFrame = (CMainFrame*)m_pMainWnd;

		if (Options.AutoHideWorkspace() )
		{
			pMainFrame->ShowWorkspace(FALSE);
		}

		m_pProjectsDoc->UpdateAllViews(NULL, CLEAR_WORKSPACE);
		m_pProjectsDoc->DeleteContents();
	}
	return TRUE;
}


/////////////////////////////////////////////////////////////////////////////
// CResOrgApp implementation

void CResOrgApp::AddToRecentWorkspacesList(LPCTSTR lpszPathName)
{
	ASSERT_VALID(this);
	ASSERT(lpszPathName != NULL);
	ASSERT(AfxIsValidString(lpszPathName));

	if (NULL != m_plistRecentWorkspaces)
	{
		m_plistRecentWorkspaces->Add(lpszPathName);
	}
}


/////////////////////////////////////////////////////////////////////////////
// CResOrgApp message handlers

void CResOrgApp::OnCmdOpenWorkspace(void) 
{
	// Browse for the workspace (.dsw) file
	#if _MSC_VER < 1300		// BXFileDialog doesn't work with VC7 yet
		BXFileDialog dlg(	TRUE,												// Open
							FALSE,												// No preview
							TRUE,												// Resizeable
							CString( (LPCTSTR)IDS_FILE_FILTER_WORKSPACES_EXT),	// Default extension
							NULL,												// Default filename
							OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST,				// Flags
							CString( (LPCTSTR)IDS_FILE_FILTER_WORKSPACES),		// File filter
							AfxGetMainWnd() );									// Parent window

		DWORD dwVersion		= LOWORD(::GetVersion() );

		DWORD dwMajor		= LOBYTE(dwVersion);
		DWORD dwMinor		= HIBYTE(dwVersion);
		DWORD dwUseableVer	= (dwMajor << 8) + dwMinor;

		if (dwUseableVer >= 0x501)
		{
			// Use the VS.NET visual style on WinXP and later
			dlg.SetAppearance(BXFileDialog::APPEARANCE_VSDOTNET);
		}
	#else
		CFileDialog dlg(	TRUE,												// Open
							CString( (LPCTSTR)IDS_FILE_FILTER_WORKSPACES_EXT),	// Default extension
							NULL,												// Default filename
							OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_ENABLESIZING,
																				// Flags
							CString( (LPCTSTR)IDS_FILE_FILTER_WORKSPACES),		// File filter
							AfxGetMainWnd() );									// Parent window
	#endif

	if (IDOK == dlg.DoModal() )
	{
		// Open and parse it (via the document)
		CString sPathName = dlg.GetPathName();

		OpenWorkspace(sPathName);
	}
}


void CResOrgApp::OnCmdCloseWorkspace(void) 
{
	CloseWorkspace();
}


void CResOrgApp::OnUpdateCloseWorkspace(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable( m_pProjectsDoc->IsWorkspaceOpen() );
}


BOOL CResOrgApp::OnCmdOpenRecentWorkspace(UINT nID)
{
	ASSERT_VALID(this);
	ASSERT(m_plistRecentWorkspaces != NULL);

	ASSERT(nID >= ID_WORKSPACE_MRU_FILE1);
	ASSERT(nID < ID_WORKSPACE_MRU_FILE1 + (UINT)m_plistRecentWorkspaces->GetSize());
	int nIndex = nID - ID_WORKSPACE_MRU_FILE1;

	if (!(*m_plistRecentWorkspaces)[nIndex].IsEmpty() )
	{
		TRACE2("MRU: open workspace (%d) '%s'.\n", (nIndex) + 1,
				(LPCTSTR)(*m_plistRecentWorkspaces)[nIndex]);

		if (!OpenWorkspace( (*m_plistRecentWorkspaces)[nIndex]) )
		{
			m_plistRecentWorkspaces->Remove(nIndex);
		}
	}
	return TRUE;
}


void CResOrgApp::OnUpdateRecentWorkspaceMenu(CCmdUI* pCmdUI)
{
	ASSERT_VALID(this);

	BOOL bEnable = FALSE;

	// The code below adds the workspaces MRU list to the
	// "Recent Workspaces" popup menu. Because the CMenu
	// pointer in the CCmdUI object we've been passed is
	// the root of the submenu, we need to replace it with
	// the first entry in the submenu, or the entries will
	// be added to the file menu itself (which causes a
	// conflict in the accelerator keys assigned to the two
	// MRU lists...)
	if (NULL != pCmdUI->m_pMenu)
	{
		CMenu* pSubMenu = NULL;
		pSubMenu = pCmdUI->m_pSubMenu;
/*		for (UINT n = 0; n < pCmdUI->m_pMenu->GetMenuItemCount(); n++)
		{
			CMenu* pMenu = pCmdUI->m_pMenu->GetSubMenu(n);
			if ( (NULL != pMenu) && (ID_WORKSPACE_MRU_FILE1 == pMenu->GetMenuItemID(0) ) )
			{
				pSubMenu = pMenu;
				break;
			}
		}
*/
		if (NULL != pSubMenu)
		{
			if (NULL != m_plistRecentWorkspaces)
			{
				int nSize = m_plistRecentWorkspaces->GetSize();
				if (nSize > 0)
				{
					for (int i = 0; i < nSize; i++)
					{
						if ((*m_plistRecentWorkspaces)[i].GetLength() > 0)
						{
							pCmdUI->m_pMenu = pSubMenu;
							m_plistRecentWorkspaces->UpdateMenu(pCmdUI);
							bEnable = TRUE;
							break;
						}
					}
				}
			}
			if (!bEnable)
			{
				// No MRU workspaces - so disable entry
				pSubMenu->EnableMenuItem(	ID_WORKSPACE_MRU_FILE1,
											MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);  
//				pCmdUI->m_pMenu->EnableMenuItem(	0,
//													MF_BYPOSITION | MF_DISABLED | MF_GRAYED);  
			}
		}
	}
}


// App command to run the dialog
void CResOrgApp::OnCmdAbout(void)
{
	CResOrgAboutBox aboutDlg;

	aboutDlg.DoModal();
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Founder Riverblade Limited
United Kingdom United Kingdom
I haven't always written software for a living. When I graduated from Surrey University in 1989, it was with an Electronic Engineering degree, but unfortunately that never really gave me the opportunity to do anything particularly interesting (with the possible exception of designing Darth Vader's Codpiece * for the UK Army in 1990).
    * Also known as the Standard Army Bootswitch. But that's another story...
Since the opportunity arose to lead a software team developing C++ software for Avionic Test Systems in 1996, I've not looked back. More recently I've been involved in the development of subsea acoustic navigation systems, digital TV broadcast systems, port security/tracking systems, and most recently software development tools with my own company, Riverblade Ltd.

One of my personal specialities is IDE plug-in development. ResOrg was my first attempt at a plug-in, but my day to day work is with Visual Lint, an interactive code analysis tool environment with works within the Visual Studio and Eclipse IDEs or on build servers.

I love lots of things, but particularly music, photography and anything connected with history or engineering. I despise ignorant, intolerant and obstructive people - and it shows...I can be a bolshy cow if you wind me up the wrong way...Laugh | :laugh:

I'm currently based 15 minutes walk from the beach in Bournemouth on the south coast of England. Since I moved here I've grown to love the place - even if it is full of grockles in Summer!

Comments and Discussions