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文件 ...
随机推荐
- td太多内容显示...
table style="table-layout:fixed;"td style="text-overflow: ellipsis;white-space: nowra ...
- 论山寨手机与Android联姻 【4】手机产业链
前文说到,生产手机以前,制造厂家需要预先得到软硬件的产品级设计方案,然后按照设计方案亦步亦趋地做,就可以制造出手机了.软硬件的产品级设计包括以下内容, 1. 主板设计,或者Gerber文件,或者PCB ...
- deal with 'non-admin area' warn
We usually use the follow code to delete product in Magento $product = Mage::getSingleton('catalog/p ...
- 嵌入式OS入门笔记-以RTX为案例:六.RTX的任务调度
嵌入式OS入门笔记-以RTX为案例:六.RTX的任务调度 上一篇笔记介绍了一些绕开排程器(或调度程序,scheduler)来进行时间管理的一些小方法.这一篇详细介绍RTX的任务调度原理. RTX主要有 ...
- devexpress中用ChartControl生成柱状图
在界面中拖入一个ChartControl控件,然后添加一个simplebutton控件.在simplebutton控件的click事件中加入如下代码: private void button1_Cli ...
- Java面试题之weblogic相关问题
WebLogic是美国Oracle公司出品的一个application server确切的说是一个基于JAVAEE架构的中间件,BEA WebLogic是用于开发.集成.部署和管理大型分布式Web应用 ...
- css笔记:如何让一个div居于页面正中间
如何让一个div居于页面中间,我今天说的是让一个div水平居中同时垂直居中,而不是简单的top:50%,left:50%.当然,我们就按一开始的思路写一下:top,left属性都设为50%,看一下效果 ...
- Nutch2.3分布执行过程中Mongodb中数据的变化
inject $ nutch inject /opt/nutch/runtime/local/urls/ > db.stats() { "db" : "nutch& ...
- JqMobi学习
JqMobi+phonegap+html5 开发Android.ios应用
- EC读书笔记系列之4:条款8 别让异常逃离析构函数
条款8 别让异常逃离析构函数 记住: ★析构函数绝对不要吐出异常.若一个被析构函数调用的函数可能抛出异常,析构函数应该捕捉任何异常,然后吞下它们(不传播)或结束程序. ★若客户需对某个操作函数运行期间 ...