/************************************************************************
*
* Resource ID Organiser Add-In for Visual C++.NET
*
* (c) Copyright 2000-2002 by Anna-Jayne Metcalfe (resorg@annasplace.me.uk)
* All rights reserved.
*
************************************************************************
*
* Filename : MainFrame.cpp
*
* Description : CMainFrame - MDI main frame window class
*
* Compiler : Microsoft Visual C++ 7.0
*
* Target
* Environment : Windows 2000/XP
*
* NOTE:
*
* This software is provided "as is" free for personal use. All
* title and copyrights in and to the software, including but not
* limited to any images, text, etc. incorporated into it, are
* owned by Anna-Jayne Metcalfe, except where acknowledged otherwise.
*
* Your may freely to use this code in your own products, PROVIDED
* this notice is not removed or modified.
*
*
* Visit http://www.annasplace.me.uk/resorg for latest updates
*
************************************************************************
*
* MODIFICATION HISTORY:
*
* This is a controlled document. See project configuration
* control tool for latest version and full version history.
*
* $Archive: /Projects/AddIns/ResOrg/ResOrgNETAddIn/MainFrame.cpp $
* $Revision: 7 $
* $Date: 25/11/02 15:27 $
* $Author: Anna $
*
* $History: MainFrame.cpp $
*
* ***************** Version 7 *****************
* User: Anna Date: 25/11/02 Time: 15:27
* Updated in $/Projects/AddIns/ResOrg/ResOrgNETAddIn
* Changed website address in banner
*
* ***************** Version 6 *****************
* User: Anna Date: 22/10/02 Time: 14:15
* Updated in $/Projects/AddIns/ResOrg/ResOrgNETAddIn
* Changed name/email address (at last!)
*
* ***************** Version 5 *****************
* User: Andy Date: 9/08/02 Time: 17:02
* Updated in $/Projects/AddIns/ResOrg/ResOrgNETAddIn
* Minor changes in DoModal() and OnMsgShowMainWindow()
*
* ***************** Version 4 *****************
* User: Andy Date: 6/08/02 Time: 10:42
* Updated in $/Projects/AddIns/ResOrg/ResOrgNETAddIn
* Reverted back to the VC6 way of displaying the main window - I've been
* unable to find an alternative which works well
*
* ***************** Version 3 *****************
* User: Andy Date: 1/08/02 Time: 16:44
* Updated in $/Projects/AddIns/ResOrg/ResOrgNETAddIn
* Further development of ResOrg.NET - particularly the tool window
*
* ***************** Version 2 *****************
* User: Andy Date: 10/06/02 Time: 17:15
* Updated in $/Projects/AddIns/ResOrg/ResOrgAddInVc7
* Woohoo! Activated the Projects Display
*
* ***************** Version 1 *****************
* User: Andy Date: 7/06/02 Time: 22:28
* Created in $/Projects/AddIns/ResOrg/ResOrgAddInVc7
*
* $Nokeywords: $
*
************************************************************************/
// MainFrame.cpp : implementation of the CMainFrame class
//
#include "StdAfx.h"
#include <afxpriv.h> // For WM_KICKIDLE
#include "ResOrgNETAddIn_Res.h"
#include "ResOrgAddInApp.h" // For CVc7AutomationHelper extern declaration
#include "ResOrgProjectsDoc.h"
#include "ResOrgProjectsView.h"
#include "MainFrame.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CMainFrame
IMPLEMENT_DYNCREATE(CMainFrame, CMainFrame_BASE)
const UINT WM_RESORG_OPEN = ::RegisterWindowMessage( _T("ResOrgShowMainWnd") );
const UINT WM_RESORG_DOMODAL = ::RegisterWindowMessage( _T("ResOrgDoModal") );
BEGIN_MESSAGE_MAP(CMainFrame, CMainFrame_BASE)
//{{AFX_MSG_MAP(CMainFrame)
ON_WM_CREATE()
ON_WM_CLOSE()
ON_MESSAGE( WM_KICKIDLE, OnKickIdle)
ON_REGISTERED_MESSAGE( WM_RESORG_OPEN, OnMsgShowMainWindow)
ON_REGISTERED_MESSAGE( WM_RESORG_DOMODAL, OnMsgDoModal)
//}}AFX_MSG_MAP
ON_COMMAND_EX( ID_VIEW_WORKSPACE, OnBarCheck)
ON_UPDATE_COMMAND_UI( ID_VIEW_WORKSPACE, OnUpdateControlBarMenu)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMainFrame construction/destruction
CMainFrame::CMainFrame(void)
{
m_pProjectsDoc = NULL;
m_hwndVisualStudio = NULL;
}
CMainFrame::~CMainFrame(void)
{
}
/////////////////////////////////////////////////////////////////////////////
// CMainFrame virtual overrides
int CMainFrame::DoModal(void)
{
if (NULL == m_hwndVisualStudio)
{
SetVisualStudioMainWnd( FindVisualStudioMainWnd() );
}
// Disable parent (before creating window)
PreModal();
BOOL bEnableParent = FALSE;
BOOL bMaximised = FALSE;
BOOL bActive = FALSE;
if ( (NULL != m_hwndVisualStudio) && ::IsWindowEnabled(m_hwndVisualStudio) )
{
bMaximised = ::IsZoomed(m_hwndVisualStudio) ;
bActive = (::GetActiveWindow() == m_hwndVisualStudio);
::ShowWindow(m_hwndVisualStudio, SW_HIDE);
::EnableWindow(m_hwndVisualStudio, FALSE);
EnableWindow(TRUE);
bEnableParent = TRUE;
}
try
{
// Refresh the workspace
m_pProjectsDoc->UpdateAllViews(NULL, SHOW_WORKSPACE);
if (Options.AutoHideWorkspace())
{
ShowWorkspace(Workspace.GetProjectCount() > 0);
}
else
{
ShowWorkspace(TRUE);
}
// Show window
ShowWindow(bMaximised ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL);
// ASSERT(::IsWindowEnabled(m_hWnd) );
// Get the size/position of the DevStudio main window and use them
WINDOWPLACEMENT wndPlacement;
if (::GetWindowPlacement(m_hwndVisualStudio, &wndPlacement) )
{
::SetWindowPlacement(m_hWnd, &wndPlacement);
}
RunModalLoop(MLF_SHOWONIDLE);
// Hide the window before enabling the parent, etc.
if (NULL != m_hWnd)
{
ShowWindow(SW_HIDE);
}
}
catch (CException* e)
{
e->Delete();
m_nModalResult = -1;
}
// Get the workspace to clear and release it's IProject pointers
m_pProjectsDoc->UpdateAllViews(NULL, CLEAR_WORKSPACE);
if (NULL != m_hwndVisualStudio)
{
if (bEnableParent)
{
::ShowWindow(m_hwndVisualStudio, bMaximised ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL);
::EnableWindow(m_hwndVisualStudio, TRUE);
}
if (bActive)
{
::SetActiveWindow(m_hwndVisualStudio);
}
}
PostModal();
// Close all symbol documents
// Note that the "Projects" document is unaffected
::AfxGetApp()->CloseAllDocuments(FALSE);
// Unlock/free resources as necessary
return m_nModalResult;
}
void CMainFrame::PreModal(void)
{
// Allow OLE servers to disable themselves
CWinApp* pApp = AfxGetApp();
if (pApp != NULL)
{
pApp->EnableModeless(FALSE);
}
}
void CMainFrame::PostModal(void)
{
// R-enable windows
if (::IsWindow(m_hWndTop))
{
::EnableWindow(m_hWndTop, TRUE);
}
m_hWndTop = NULL;
CWinApp* pApp = AfxGetApp();
if (pApp != NULL)
{
pApp->EnableModeless(TRUE);
}
}
BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
if (CMainFrame_BASE::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo) )
{
return TRUE;
}
return m_wndWorkspace.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
/////////////////////////////////////////////////////////////////////////////
// CMainFrame operations
bool CMainFrame::SetVisualStudioMainWnd(HWND hwndVisualStudio)
{
if (m_hwndVisualStudio != hwndVisualStudio)
{
m_hwndVisualStudio = hwndVisualStudio;
ASSERT(::IsWindow(m_hwndVisualStudio) );
}
return true;
}
void CMainFrame::ShowWorkspace(BOOL bShow)
{
ShowControlBar(&m_wndWorkspace, bShow, FALSE);
}
/////////////////////////////////////////////////////////////////////////////
// CMainFrame diagnostics
#ifdef _DEBUG
void CMainFrame::AssertValid(void) const
{
CMainFrame_BASE::AssertValid();
}
void CMainFrame::Dump(CDumpContext& dc) const
{
CMainFrame_BASE::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CMainFrame implementation
// Use with care - this will fail if Visual Studio is not the active window
HWND CMainFrame::FindVisualStudioMainWnd(void) const
{
HWND hWndDevStudio = NULL;
HWND hWndDesktop = ::GetDesktopWindow();
HWND hWnd = ::GetActiveWindow();
while ( (NULL != hWnd) && (hWnd != hWndDesktop) )
{
hWndDevStudio = hWnd;
hWnd = ::GetParent(hWnd);
}
return hWndDevStudio;
}
/////////////////////////////////////////////////////////////////////////////
// CMainFrame message handlers
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
int nResult = CMainFrame_BASE::OnCreate(lpCreateStruct);
if (-1 != nResult)
{
// Create the "Workspace" docking window.
//
// Initialise m_wndWorkspace control bar
if( !m_wndWorkspace.Create( this,
ID_VIEW_WORKSPACE,
_T("Workspace"),
CSize(225,100),
CBRS_LEFT ) )
{
TRACE0("Failed to create dialog bar m_wndWorkspace\n");
return -1; // fail to create
}
m_wndWorkspace.EnableFlatLook();
// Create the document for each of the tab views, then add the
// document / view to the tab control. This is a very simple implementation.
// you could go further and actually create a document template for each tab,
// and add it to the app. If so, you would pass in m_pMyDocTemplate->CreateNewDocument(),
// instead of dynamically allocating a pointer for each document as shown here.
// This was done for simplicity.
//
// "Projects" tab (the only one at present)
m_pProjectsDoc = new CResOrgProjectsDoc;
ASSERT_KINDOF( CDocument, m_pProjectsDoc );
m_wndWorkspace.AddView( _T( "Projects" ), RUNTIME_CLASS( CResOrgProjectsView ), m_pProjectsDoc );
// Define the image list to use with the tab control
m_TabImages.Create( IDB_WORKSPACE_TABS, 16, 1, RGB( 0, 255, 0 ));
m_wndWorkspace.SetTabImageList( &m_TabImages );
m_wndWorkspace.EnableDockingOnSizeBar( CBRS_ALIGN_ANY );
EnableDockingSizeBar( CBRS_ALIGN_ANY );
DockSizeBar( &m_wndWorkspace );
// Set the popoup menu id.
m_wndWorkspace.SetMenuID( IDR_MAINFRAME, NULL, 1 );
// Set the ID of the view so we can link in the topic
// for context help
//
// Note that this has to be a command (ID_) or the
// wrong help context ID will be generated by the
// framework (this only happens because the view
// is inside a control bar)
CView* pView = m_wndWorkspace.GetView(0);
if (NULL != pView)
{
pView->SetDlgCtrlID(ID_DISPLAY_WORKSPACE);
}
// Restore the previous bar and window states.
LoadBarState(_T("Bar State"));
}
return nResult;
}
void CMainFrame::OnClose(void)
{
CWinApp* pApp = ::AfxGetApp();
if ( (NULL != pApp) && (this == pApp->m_pMainWnd) )
{
// Attempt to save all modified documents
if (!pApp->SaveAllModified())
{
return; // Don't close just yet
}
}
// Save the bar and window states.
m_state.SaveWindowPos(this);
SaveBarState(_T("Bar State"));
m_nModalResult = IDOK;
EndModalLoop(m_nModalResult);
}
// Handle MFC private message WM_KICKIDLE. LPARAM is the idle count.
// Return TRUE/FALSE continue/discontinue idle processing.
LRESULT CMainFrame::OnKickIdle(WPARAM, LPARAM lCount)
{
return ::AfxGetApp()->OnIdle( (LONG)lCount);
}
LRESULT CMainFrame::OnMsgShowMainWindow(WPARAM, LPARAM lParam)
{
CString sPathName = (LPCTSTR)lParam;
if (!sPathName.IsEmpty() )
{
::AfxGetApp()->OpenDocumentFile(sPathName);
}
PostMessage(WM_RESORG_DOMODAL);
return 0L;
}
LRESULT CMainFrame::OnMsgDoModal(WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(wParam);
UNREFERENCED_PARAMETER(lParam);
DoModal();
return 0L;
}