15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Visual C++/MFC 4.1 - display MRU file at startup

Andi Giri -- agiri@ctiis.com
Thursday, May 02, 1996

Hello

My environment is : Visual C++ 4.1, MFC 4.1 / WIN 95

I am porting a 32-bit MDI application developed using Visual C++ 2.2/MFC 3.0
to run on Visual C++/MFC 4.1.

The project contains
1) Smrt.cpp with this code only
2) MainFrm.cpp, SmrtView.cpp, SmrtDoc.cpp, ChildFrm.cpp
3) A host of non-MFC source code

PROBLEM:
Display the first file in MRU list, when the MDI application is initiated
without any command-line parameter.

DETAILED DESCRIPTION:
The following MFC 3.0-based existing code in CSmrtApp::InitInstance() lets
the first document in the MRU file list get displayed on the initially
created child window, when the app is initiated without a document name in
the command-line paramater.


-----------------------------------------------------

BOOL CSmartListApp::InitInstance()
{
	// Standard initialization
		.
		.
		.
	// create main MDI Frame window
	CMainFrame* pMainFrame = new CMainFrame;
	if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
		return FALSE;
	m_pMainWnd = pMainFrame;

// START - code for command-line parsing and processing
	// simple command line parsing
	if (m_lpCmdLine[0] == '\0')
	{
		// Determine if there was a last used file
		if( m_pRecentFileList->m_arrNames[0].IsEmpty() )
		{
			OnFileNew();
		}
		else
		{
			// Open the last used file if possible
			m_pMainWnd->PostMessage(WM_COMMAND,
				MAKEWPARAM(ID_FILE_MRU_FILE1,0),0L);
		}
	}
	else
	{
		// open an existing document
		OpenDocumentFile(m_lpCmdLine);
	}
// END - code for command-line parsing and processing

	// The main window has been initialized, so show and update it.
	pMainFrame->ShowWindow(SW_SHOWMAXIMIZED);
	pMainFrame->UpdateWindow();

	return TRUE;
}


The problem with code generated by Visual C++ 4.0 is that Command-line
processing is done by a call to ProcessShellCommand() in InitInstance(), 
and this in turn calls OnFileNew() if the command line is empty.
ProcessShellCommand() is not a virtual
function for me to override; OnFileNew() is virtual, but there is no way to
figure out whether it was initiated by ProcessShellCommand() or by the user
clicking the menu item File->New later on.  If I were to add the above code
to the new 4.0 CWinApp()::InitInstance(),
I will end up having an empty document created by ProcessShellCommand()
initially, and then a separate document created by the message processing
of ID_FILE_MRU_FILE1.  I would like to have the MRU document on the first
view itself, not two separate views.

Is there an easy way of doing it, other than writing something like this:

BOOL CSmartListApp::InitInstance()
{
	// Standard initialization
		.
		.
		.
	// create main MDI Frame window
	CMainFrame* pMainFrame = new CMainFrame;
	if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
		return FALSE;
	m_pMainWnd = pMainFrame;

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

	// Dispatch commands specified on the command line
	if  (m_lpCmdLine[0] == '\0') // empty command line
	{
		if (!MyProcessShellCommand(cmdInfo))
			return FALSE;
	}
	else
		if (!ProcessShellCommand(cmdInfo))
			return FALSE;

BOOL CWinApp::MyProcessShellCommand(CCommandLineInfo& rCmdInfo)
{
	BOOL bResult = TRUE;
	if (rCmdInfo.m_nShellCommand == CCommandLineInfo::FileNew)
	{
		if (m_pMainWnd == NULL)
			bResult = FALSE;
		m_nCmdShow = SW_SHOWNORMAL;
	}
	// Determine if there was a last used file
	if( m_pRecentFileList->m_arrNames[0].IsEmpty() )
	{
		OnFileNew();
	}
	else
	{
		// Open the last used file if possible
		m_pMainWnd->PostMessage(WM_COMMAND,
			MAKEWPARAM(ID_FILE_MRU_FILE1,0),0L);
	}
	return bResult;
}







Frederic Steppe -- FredericS@msn.com
Saturday, May 04, 1996

[Mini-digest: 3 responses]

>My environment is : Visual C++ 4.1, MFC 4.1 / WIN 95
>
>PROBLEM:
>Display the first file in MRU list, when the MDI application is initiated
>without any command-line parameter.

Here is how to do it with VC++ 4.0.  I guess it is quite the qame with VC++ 
4.1

Suppose your application's class name is CMyApp.  Add the following lines to 
CMyApp class definition :

public:
	BOOL ProcessShellCommand(CCommandLineInfo& rCmdInfo);

Remember that you can override a non-virtual function. The main difference is 
that if some function of the parent class (CWinApp) calls this function 
(ProcessShellCommand), the parent class' function will be called.  In this 
case, tou call ProcessShellCommand from CMyApp, so the good one will be 
executed.

Add the following to CMyApp implementation :

#include 	// some non-documented classes definition.  Needed for 
CRecentFileList.
		// May change in future releases (still there in VC++ 4.1 ???).

BOOL CMyApp::ProcessShellCommand(CCommandLineInfo& rCmdInfo)
{
	if (rCmdInfo.m_nShellCommand == CCommandLineInfo::FileNew)	// empty command 
line
	{
		ASSERT(m_pRecentFileList != NULL);
		
		if(m_pRecentFileList->GetSize() > 0 && (*m_pRecentFileList)[0].GetLength() > 
0)
		{
			if(OpenDocumentFile((*m_pRecentFileList)[0]) != NULL)
				return TRUE;
			m_pRecentFileList->Remove(0);
		}
	}
	return CWinApp::ProcessShellCommand(rCmdInfo);
}

That's it.

Frederic Steppe (frederics@msn.com)
-----From: mikeblas@interserv.com

On Thu, 2 May 1996, Andi Giri  wrote:

>My environment is : Visual C++ 4.1, MFC 4.1 / WIN 95

Thanks.

>Is there an easy way of doing it, other than writing something like this:

I would say so!  You should write your own override of ParseCommandLine() so 
that it tweaks the rCmdInfo.m_nShellCommand value to be what you want.  
That's why ParseCommandLine() is there!  See if the command line is empty.  
If it is, post your message and make rCmdInfo.m_nShellCommand be zero so that 
the default implementation of ProcessShellCommand() won't do anything.

.B ekiM
--
TCHAR szDisc[] = _T("These words are my own; I do not speak for Microsoft.");

-----From: Niels Ull Jacobsen 

How about just=20

...

if  (m_lpCmdLine[0] =3D=3D '\0')    // If empty command line - try to open=
 most
recent file
{
   static CString newCmdLine =3D m_pRecentFileList->m_arrNames[0];
   m_lpCmdLine =3D newCmdLine.GetBuffer();
}

CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
if (!ProcessShellCommand(cmdInfo))
   return FALSE;
Niels Ull Jacobsen, Kr=FCger A/S (nuj@kruger.dk)
Everything stated herein is THE OFFICIAL POLICY of the entire Kruger group
and should be taken as legally binding in every respect. Pigs will grow
wings and fly.









| Вернуться в корень Архива |