MFC的命令行
一个程序,我们通过输入不同的命令行参数,就可以实现一个可执行文件,多种功能,通过命令行来控制它的行为,例如,我们在控制台的时候,就是遇到最多的,如一个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的命令行的更多相关文章
- MFC接收命令行参数的三种方法
方法一: CString sCmdline = ::GetCommandLine(); AfxMessageBox(sCmdline); 将获取到 "C:\test\app.exe -1 - ...
- 命令行下的C++程序转换成VC的MFC程序需要注意的问题
在将命令行下的C++程序转换成MFC窗口程序时一般会提示下面这种错误: fatal error C1010: unexpected end of file while looking for prec ...
- <VS>MFC程序显示命令行窗口
编写MFC程序时,想打印出调试信息,使用cout后,发现程序并没有像想象中那样自动弹出命令行窗口,要输出的信息也没地方去查看.百度后知道要手动调出命令行窗口,才可以看到输出的信息. 百度上介绍了两 ...
- MFC命令行及CCommandLineInfo类
获取命令行的方法: 1.GetCommandLine() 获取输入的所有信息,包括程序所在路径及参数 2.AfxGetApp()->m_lpCmdLine 只包含参数 一般情况下,获取到命令行后 ...
- Windows的命令行查看,修改,删除,添加环境变量
查看当前所有可用的环境变量:输入 set 即可查看. 显示某环境变量: 例如:echo %SystemDrive% 类似linux下面的echo $PATH这种用法. 首先明确一点:所有的在cmd命令 ...
- 转 命令行下玩VC
说明:(1)转载请注明出处:http://www.cnblogs.com/opangle/p/4298155.html (2)以下以VS2013为例,并假设VC安装路径为%VC_INSTALL_PAT ...
- 命令行下玩VC
说明:(1)转载请注明出处:http://www.cnblogs.com/opangle/p/4298155.html (2)以下以VS2013为例,并假设VC安装路径为%VC_INSTALL_PAT ...
- 用Visual Studio创建集成了gtest的命令行工程
gtest代码库中的sample代码 在gtest的代码库中,包含了10个sample的代码,覆盖了gtest的常见用法,sample的代码位于以下文件夹: gtest\samples 由于gtest ...
- Windows 编程,程序编译使用的命令行工具。
Windows 编程,程序编译使用的命令行工具. 1.cl.exe文件是Visual C\C++的编译器,它将程序源代码文件编译为obj文件. 2.rc.exe文件是资源编译器.工程项目中的.rc文件 ...
随机推荐
- python 初学笔记 (一)
初学python第一天,希望自己真正了解计算机语言,并且做出成效. 写下学习笔记,记录学习进度,娱乐学习,不断成长. python详细介绍: python是什么?运用到哪里?有哪些在使用它? pyth ...
- jchat:linux聊天程序2:MySQL
该软件使用的数据库为MySQL,因为它免费.开源,在linux下几乎就是最好的选择. 首先要在mysql中root用户新建数据库并赋权给本用户: create database jchat; gran ...
- Three.js基础
Three.js基础探寻一 Three.js基础探寻一 1.webGL 一种网络标准,定义了一些较底层的图形接口. 2.Three.js 一个3Djs库,webGL开源框架中比较优秀的一个.除了w ...
- J2SE知识点摘记(六)
1. static关键字的使用 static 关键字:可以用于修饰属性,也可以用于修饰方法,还可以用于修饰类. static 修饰属性:无论一个类生成了多少个对象,所有这些对象共同使用唯 ...
- Flex中如何通过showAllDataTips属性使鼠标移动到图表时显示所有的数据Tips的例子
原文 http://blog.minidx.com/2008/11/10/1616.html 接下来的例子演示了Flex中如何通过showAllDataTips属性,使鼠标移动到图表时显示所有的数据T ...
- Apache OpenOffice 与 LibreOffice 之间的抉择
Apache OpenOffice 与 LibreOffice 之间的抉择 Apache OpenOffice和LibreOffice都 是OpenOffice.org的现代衍生产品.最近几年,几乎所 ...
- Linux下利用fork()创建子进程并使父进程等待子进程结束
int status; pid_t t = fork(); if(t){ waitpid(t, &status, 0); }else{ system("vi temp ...
- Linux学习之六-Yum命令的使用
详细介绍一下yum命令的用法.如果你是一个Linux的初学者,一定会被软件的安装所困扰过,尽管RPM包解决了一定层度的问题,但有些RPM的包的依赖关系让人很是头疼.而YUM.APT等一些RPM包的管理 ...
- Ubuntu安装二:在VM中安装Ubuntu
在VM中安装Ubuntu,先的安装VM,VM的安装请见:http://blog.csdn.net/u011043843/article/details/35291799 1.打开VM,新建虚拟机 2. ...
- T-SQL变量
T-SQL中变量分为全局变量和局部变量,分别使用@@和@前缀. 全局变量 常用的全局变量有@@VERSION .@@IDENTITY.@@ERROR.@@ROWCOUNT 用法 select @@VE ...