Tuesday, March 17, 2009

Command Line Parsing in MFC - VC++

Processing command line in MFC application.

While working with DocuMight our client need some additional features like automatic showing files, some type of permissions etc . After discussion with our project team we concluded to have a command line parameter. Frankly I don’t have much experience in command line processing. I only worked with C style command line arguments.
[ int main(int argc, char *argv[])]
Following are my sample test code wrote in InitInstance()of CWinApp.

TCHAR *pCommandLine = ::GetCommandLine();//here we will get all command line
                                          //parameter including exe name.

int nArgc = 0;
LPWSTR *pArgv = ::CommandLineToArgvW( pCommandLine,  &nArgc);
for( int nCmdCount=0; nCmdCount < nArgc; ++nCmdCount)
{
      TRACE2("%d: %s\n",nCmdCount, pArgv[nCmdCount]); 
}

The above work only in Unicode character set, and also have so many problems. So I searched for a optimum solution and finally found the following solution.

Step1: Derive a class from CCommandLineInfo and override ParseParam
Step2: pass customized CCommandLineInfo  to ParseCommandLine method.

#pragma once
class
CMyCommandLineInfo : public CCommandLineInfo
{
public:
      virtual void ParseParam(  const TCHAR* pszParam, BOOL bFlag, BOOL bLast);
      CString m_strMergeFileName;
      bool m_bHideToolBar;
};

#include "StdAfx.h"
#include "MyCommandLineInfo.h"
void CMyCommandLineInfo::ParseParam(  const TCHAR* pszParam, BOOL bFlag, BOOL bLast)
{
      if( TRUE == bFlag)//indicates that command start with /,-
      {
            CString strCommand = pszParam;
            strCommand.MakeUpper();
            if( strCommand.Compare( _T("H")) == 0)
            {
                  this->m_bHideToolBar = true;
            }
      }
      else
      {
            m_strMergeFileName = pszParam;                                   
      }
}

BOOL CtestCmdApp::InitInstance()
{
      //previous code  ...
      CWinApp::InitInstance();
      CMyCommandLineInfo commandLineInfo;
      __super::ParseCommandLine(commandLineInfo);
      if( true == commandLineInfo.m_bHideToolBar )
      {
            //code to hide toolbar.
      }
      if( TRUE == :: PathFileExists( commandLineInfo.m_strMergeFileName ))
      {
            //code to merge file.
      }
      //previous code  ...
}

If you want to manipulate more specific commands I recommend following code.

for (int nArgc = 1; nArgc < __argc; ++nArgc)
{
      LPCTSTR pszParam = __targv[nArgc];
      if (pszParam[0] == '-' || pszParam[0] == '/')
      {
            //do falg specific code.
      }
}

 

No comments: