一个程序,我们通过输入不同的命令行参数,就可以实现一个可执行文件,多种功能,通过命令行来控制它的行为,例如,我们在控制台的时候,就是遇到最多的,如一个exe程序,加入为test..exe,我们可以设置一些命令行参数,如/t,/q,在我们输入不同的命令行的时候,实现不同的行为,但是一般在控制台见得普遍,在窗口化程序中,是否没有怎么看到,之所以我们没有看到,是因为使用的方式不同,对于窗口化的程序,我们通常根据功能的不同,我们把这些参数都写入了注册表,然后在右键快捷菜单中设置相应的菜单项,当我们选择不同的菜单项目的时候,其实就是使用了通过不同的命令行来达到不同的程序行为,另外,我们还可以在我们编写的mfc程序中,通过参数来控制行为以后,我们不在继续执行,创建窗口等操作,而是直接退出。如此一来,我们就可以通过一个exe文件实现不同的功能,如一个基于对话框的程序,我们通过输入不同的参数以后,可以实现一些功能,但是呢,我们不启动对话框。那么,下面就来说说如何mfc是如何使用命令行的。

在文档类的InitInstance中会看到这样的一句话,前面是一个类,这个类只有一个方法,就是CCommandLineInfo::ParseParam,别的全是数据成员和构造函数,ParseCommandLine函数是CWinapp的一个方法,它以cmdInfo对象为参数,它的作用就是重复的调用ParseParam方法来解析传入程序的命令行,根据标记和参数来填充CCommandLineInfo的数据成员,它是重复调用的,直到将所有的参数解析完毕。然后我们在这段代码的下面,找到一句:

if (!ProcessShellCommand(cmdInfo))
        return FALSE;

这个就是通过参数,执行相应的命令,如打开文件,新建文件等等命令,这些都可以在MSDN的CWinapp类中找到,但是呢,这些都是默认的,MFC内置的命令,如果我们要实现我们自己的命令参数呢,应该如何做呢,那么,我们应该自定义一个类,这个类继承了CCommandLineInfo类,这里顺便说一下如何添加类到MFC到我们的项目中,通过类向导,选择添加MFC类,如下图:

这中添加方式,就可以直接将相应的头文件,源文件关联然后加入项目中,而且类的基本框架页实现了,但是有的类,如我们现在要添加一个继承自CCommandLineInfo类的自定义类,我们发现,没有这个基类,那么应该如何做呢,我们可以选择继承自CObject类,这个类是所有mfc类的基类,它是一个很重要的类,同学们可以到msdn中查阅学习。继续刚才的,我们继承了CObject这个类,但是我们不是要继承CCommandLineInfo类吗,其实这不要紧,看下图:

我们只要将CObject换成我们的CCommandLineInfo类,这样就可以了,大家可以看到,用这种方式添加的类,构造函数,析构函数都有了,所以建议大家用这中方式添加自定义MFC类。在这里,我添加了两个数据成员,分别为TCHAR类型的常量指针,之所以为常量,是为了和我们后面要写的ParseParam相对应。我用这两个变量来保存我们自定义的命令行标记和参数。命令行里面的标记呢,是指如/t,-t,这样的就是标记,在解析的时候,自动将/和-符号移除。加/和-的效果是一样的,关键是标记后面的值。参数,如我们打开一个文件,“C:\Test.txt”,用双引号引起来的,就是参数。在解析的时候,引号也自动去掉。如果我们的参数中必须要有引号,那么在最外面的引号里面通过转义字符来表示如\",这样一来,就可以将双引号包含如命令中。最后,我重写了CCommandLineInfo类唯一的方法ParseParam方法,如下图:

由上面可以看到,bFlag是一个布尔值,如果是TURE,说明这个命令行是一个标记,那么就将它存入F中,否则就是参数,存入P中。最后在调用基类的方法,主要是响应MFC默认的一些命令,当然,这里呢,对于是否调用基类的判断不是很好,大家根据自己的实际情况,来设定。如此一来,我们就可以获取我们定义的命令行了。下面是如何处理我们自定义的命令行

在最初的基础之上,我先处理了自己的自定义的命令行,然后根据需要来看是否调用处理默认的MFC命令。这是在mfc的文档类中,我们充分利用了mfc框架,实现了自定义命令行的实现,那么我们还有一种方式,这种方式和SDK的WinMain函数中处理由WinMain函数传递进来的命令行处理是一样的,如下:

int CALLBACK WinMain(
_In_  HINSTANCE hInstance,
_In_  HINSTANCE hPrevInstance,
_In_  LPSTR lpCmdLine,
_In_  int nCmdShow
);

其中lpCmdLine就是命令行,下面我就在基于对话框的MFC程序中说明一下。

WinMain的这个参数传递进来以后,就把值赋给了app类的m_lpCmdLine数据成员中,那么我们只要解析它就可以了,如下图:

在这里我们在输出窗口中可以看到m_lpCmdLine中的值,就是我调试的时候设置的命令行。然后我通过一个while语句,将字符指针中的字符复制到一个字符数组中,因为字符数组通过索引来查找字符,便于我们解析。但是这个要麻烦一点,因为不会像MFC提供的CCommandLine类一样为我们自动移除引号和/,-标记。这些全部要我们自己来操作。那么,我们默认调试运行的时候,参数是空,我们如何在调试的时候加入参数呢,见下图:

在属性当中,调试,命令参数中,我们就可以输入参数,在运行的时候,就可以传入参数,来帮助我们调试不同命令行下的参数运行情况。那么,第二种方式,就完全和SDK总的WinMain中的参数解析一样的,如此一来,就完全没有使用MFC提供给我们的方法,就是麻烦一点,但是有大的灵活性。

最后,总结一下,通过命令行,控制我们程序启动时的行为,实现一个exe文件,多个功能,如在上面的例子中,我们可以在处理我们自己的命令之后,可以返回,退出,而不继续执行,建立窗口。但是大家要记住处理命令行的地方,那就是在app类的InitInstance方法中,应该在调用基类的CWinApp::InitInstance();方法之前调用,因为基类的这个方法就开始创建实例了,如果再创建实例之后,处理我们自己的命令行就直接返回,会造成内存泄露的情况。

MFC的命令行的更多相关文章

  1. MFC接收命令行参数的三种方法

    方法一: CString sCmdline = ::GetCommandLine(); AfxMessageBox(sCmdline); 将获取到 "C:\test\app.exe -1 - ...

  2. 命令行下的C++程序转换成VC的MFC程序需要注意的问题

    在将命令行下的C++程序转换成MFC窗口程序时一般会提示下面这种错误: fatal error C1010: unexpected end of file while looking for prec ...

  3. <VS>MFC程序显示命令行窗口

    编写MFC程序时,想打印出调试信息,使用cout后,发现程序并没有像想象中那样自动弹出命令行窗口,要输出的信息也没地方去查看.百度后知道要手动调出命令行窗口,才可以看到输出的信息.   百度上介绍了两 ...

  4. MFC命令行及CCommandLineInfo类

    获取命令行的方法: 1.GetCommandLine() 获取输入的所有信息,包括程序所在路径及参数 2.AfxGetApp()->m_lpCmdLine 只包含参数 一般情况下,获取到命令行后 ...

  5. Windows的命令行查看,修改,删除,添加环境变量

    查看当前所有可用的环境变量:输入 set 即可查看. 显示某环境变量: 例如:echo %SystemDrive% 类似linux下面的echo $PATH这种用法. 首先明确一点:所有的在cmd命令 ...

  6. 转 命令行下玩VC

    说明:(1)转载请注明出处:http://www.cnblogs.com/opangle/p/4298155.html (2)以下以VS2013为例,并假设VC安装路径为%VC_INSTALL_PAT ...

  7. 命令行下玩VC

    说明:(1)转载请注明出处:http://www.cnblogs.com/opangle/p/4298155.html (2)以下以VS2013为例,并假设VC安装路径为%VC_INSTALL_PAT ...

  8. 用Visual Studio创建集成了gtest的命令行工程

    gtest代码库中的sample代码 在gtest的代码库中,包含了10个sample的代码,覆盖了gtest的常见用法,sample的代码位于以下文件夹: gtest\samples 由于gtest ...

  9. Windows 编程,程序编译使用的命令行工具。

    Windows 编程,程序编译使用的命令行工具. 1.cl.exe文件是Visual C\C++的编译器,它将程序源代码文件编译为obj文件. 2.rc.exe文件是资源编译器.工程项目中的.rc文件 ...

随机推荐

  1. Python之路第四天,基础(4)-装饰器,迭代器,生成器

    装饰器 装饰器(decorator)是一种高级Python语法.装饰器可以对一个函数.方法或者类进行加工.在Python中,我们有多种方法对函数和类进行加工,比如在Python闭包中,我们见到函数对象 ...

  2. [Backbone.js]如何用backbone写一个仿网页版微信的webapp?

    var Chat = Backbone.Model.extend({ idAttribute:'id', initialize:function(options){ var users = this. ...

  3. 利用jQuery打造个性网站

    网页结构 编写全局样式(reset.css) /*全局样式*/ body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,pre,form,fi ...

  4. Delphi XE6 通过JavaScript API调用百度地图

    参考昨天的内容,有朋友还是问如何调用百度地图,也是,谁让咱都在国内呢,没办法,你懂的. 首先去申请个Key,然后看一下百度JavaScript的第一个例子:http://developer.baidu ...

  5. Windows系统的线程调度与软件中断分发

    在Windows操作系统内核把软件中断分为三个中断级别:DISPATCH_LEVEL,APC_LEVEL,PASSVIE_LEVEL.同时他们与线程的调试相关,WINDOWS内核中没有一个专门的程序来 ...

  6. SpringMVC、SpringMVC XML配置(纯XML方式)

    1.引入SrpingMVC所使用的Java包: cglib-nodep-2.1_3.jar.commons-logging.jar.spring-aspects-4.1.7.RELEASE.jar.s ...

  7. Struts2 四、Struts2 处理流程

    1. 一个请求在Struts2框架中的处理步骤: a) 客户端初始化一个指向Servlet容器的请求: b) 根据Web.xml配置,请求首先经过ActionContextCleanUp过滤器,其为可 ...

  8. Reward(拓扑结构+邻接表+队列)

    Reward Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total Submis ...

  9. ICSharpCode.SharpZipLib.Zip

    //压缩整个目录下载 var projectFolder = Request.Params["folder"] != null ? Request.Params["fol ...

  10. jquery ajax 参数可以序列化

    <form> <input type="text" name="FirstName" value="Bill" /> ...