6、有三个API函数可以运行可执行文件WinExec、ShellExecute和CreateProcess。  关于这三者的概述总结,有好几篇,自己选择。

1.CreateProcess因为使用复杂,比较少用。 
2.WinExec主要运行EXE文件。如:WinExec(’Notepad.exe Readme.txt’, SW_SHOW); 
3.ShellExecute不仅可以运行EXE文件,也可以运行已经关联的文件。

最后还有一个功能是打开目录并选中文件:


们一般使用 ShellExecute 来打开一个文件或者目录,也可以用其来打开一个IE窗口、打印窗等等。
现在很多软件在打开文件所在目录的同时都会贴心的把该文件选中,比如FlashGet,BitComet。如何实现呢?很简单:) 使用
Explorer.exe的/select开关。

//打开目录并选定文件 ShellExecute(NULL, _T("open"),
_T("Explorer.exe"), _T(" /select,") + filePath, NULL, SW_SHOWDEFAULT); 
其中 filePath 为文件的绝对路径。 ShellExecute的参数意义可以在MSDN上查到。

注意:/select,最后是有一个,号的!!!

还有一点需要注意:

wchar_t wch[MAX_PATH];
::PathCombine(wch, _T("D:"), _T("./Temp"));  //然后调用
::ShellExecute(this->GetSafeHwnd(), _T("open"), wch, NULL, NULL, SW_SHOW);

注1: ShellExecute函数中的目录或文件要用绝对路径,相对路径不行 ;

注2:调试过程中(EXE路径)可以添加到  系统的环境变量中去,省掉不少麻烦;但是setup时候需要考虑清楚

注3:其实调用PathCombine拼出来的字符串内容是类似: D:\./Temp   对这样的格式类型,系统或ShellExecute是能自动识别的,也是合法路径。

7、只允许一个程序运行

思路:在App程序初始化时,initinstance时检测,findwindow()进行查找,注意的是对于单文档或者多文档的需要注意  无标题-test 这种情况,有文档打开时会有 123.txt-test,这时需要将Window Title的style设置下。如上篇的第一条。

BOOL CTestdanApp::IsFirstInstance(CString title)
{
CWnd *pWndPrev, *pWndChild; if (pWndPrev = CWnd::FindWindow(NULL,title))
{ // AfxMessageBox( _TEXT("只允许一个实例在运行!"));
pWndChild = pWndPrev->GetLastActivePopup();
if (pWndPrev->IsIconic())
pWndPrev->ShowWindow(SW_RESTORE);
pWndChild->SetForegroundWindow(); //找到并激活到前端 CString sCopyData = GetCommandLine(); COPYDATASTRUCT cpd;
cpd.dwData = ;
cpd.cbData = sCopyData.GetLength() + ;//多加一个长度,防止乱码
cpd.lpData = (void*)sCopyData.GetBuffer(cpd.cbData);
pWndChild->SendMessage(WM_COPYDATA,NULL,(LPARAM)&cpd);
return FALSE;
}
else
return TRUE; // 第一个实例
}

单一实例运行

CMyApp中需要添加 到BOOL CMyApp::InitInstance()

BOOL CTestdanApp::InitInstance()
{
if(!IsFirstInstance("titlename"))//前后title对应,尝试FindWindow(class ,null);但有的Class根据不同的环境会发生变化
return false;
AfxEnableControlContainer();
。。。。
。。。。
return true;
}

单一检测

8、传递参数给正在运行的winfrom 程序

在带参数的MFC程序 再次运行时,经过检测已经存在本程序,则需要不创建;然后将参数通过消息 WM_COPYDATA 传递过去

在 BOOL CMainFrame::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) 函数中响应消息映射。

BOOL CMainFrame::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
// TODO: Add your message handler code here and/or call default CString str; str=(char *)pCopyDataStruct->lpData; return CFrameWnd::OnCopyData(pWnd, pCopyDataStruct);
}

9、通过ShellExecute 以及CMD模式下启动MFC单文档程序,其传递参数时, 在  BOOL CMyApp::InitInstance()  中接受参数。

    //标准用法
CCommandLineInfo mycmdinfo;
ParseCommandLine(mycmdinfo);
  //这两行就是CCommandLineInfo类的标准用法,实现了新建、打开文件、打印机等的操作,具体操作链接  if (!ProcessShellCommand(mycmdinfo))
return FALSE;

  

主要过程

CCommandLineInfo::CCommandLineInfo()   构造函数->

->void CWinApp::ParseCommandLine(CCommandLineInfo& rCmdInfo) /*ParseCommandLine主要是对输入的命令行参数做一些分析 ;/对参数数组进行循环便利/*/ ->

-> for (int i = ; i < __argc; i++)   rCmdInfo.ParseParam(pszParam, bFlag, bLast); ->

->void CCommandLineInfo::ParseParam(const TCHAR* pszParam,BOOL bFlag,BOOL bLast) /* 根据 bFlag 进行选择*/ ->

->CCommandLineInfo::ParseParamFlag(...):   /*ParseParamFlag判断传过来的字符串 ,判断它的参数类型 , 并根据参数类型做不同的处理 . */ ->

->void CCommandLineInfo::ParseLast(BOOL bLast)   /*ParseLast会判断是否是是FileNew打开新文档 , 如果是打开新文档 , 并且打开的文档名不为空的话, 

就假定用户想打开这个文档 , 把命令设置为FileOpen .*/  ->

->返回到   void CWinApp::ParseCommandLine(CCommandLineInfo& )   ->

->主角登场 CWinApp::ProcessShellCommand(...): /*执行*/   ProcessShellCommand 分析m_nShellCommand ,并根据m_nShellCommand不同的类型值进行不同的处理 .
switch (rCmdInfo.m_nShellCommand) -> ->完毕

 关于CCommandLineInfo详解 和 ProcessShellCommand(cmdInfo)函数功能详细解释,请点击这里

/*
When you start a new MFC project using the Application Wizard, the Application Wizard will create a local instance of CCommandLineInfo, and then call ProcessShellCommand and ParseCommandLine in the InitInstance member function. A command line follows the route described below: 1、 After being created in InitInstance, the CCommandLineInfo object is passed to ParseCommandLine. 2、 ParseCommandLine then calls CCommandLineInfo::ParseParam repeatedly, once for each parameter. 3、 ParseParam fills the CCommandLineInfo object, which is then passed to ProcessShellCommand. 4、 ProcessShellCommand handles the command-line arguments and flags.
*/

MSDN解释

定义自己的参数方法

1、从CCommandLineInfo派生一个类,然后重载该类的ParseParam方法,实现参数的解析即可。转自链接

如果需要定义自己的参数,则需要从CCommandLineInfo派生一个类,然后重载该类的ParseParam方法,实现参数的解析即可。

//1.从CCommandLineInfo派生出类CMyCommandLineInfo:

class CMyCommandLineInfo : public CCommandLineInfo
{
public:
void ParseParam(LPCTSTR lpszParam, BOOL bFlag, BOOL bLast);
}; //2.在主程序App类中声明成员变量,用于保存命令行传入的参数:
CString m_strUsername;
CString m_strPassword; //3.重载ParseParam方法: void CMyCommandLineInfo::ParseParam(LPCTSTR lpszParam, BOOL bFlag, BOOL bLast)
{
static int num = ;
CCommandLineInfo::ParseParam(lpszParam, bFlag, bLast);
switch(num)
{
case :
theApp.m_strUsername = CString(lpszParam);
break;
case :
theApp.m_strPassword = CString(lpszParam);
break;
}
num++;
} //该方法通过递归的方式解析命令行中传入的所有参数,依次保存到相应的变量中。 //4.修改主程序的调用,用派生的CCommandLineInfo类替换默认的: CMyCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);   /*通过这简单的几步,就可以方便的取得命令行参数了。要注意的是命令行在传递参数的顺序要同程序里定义的一致。如本例中,第1个参数是用户名,第2个参数是密码,如果顺序错了,程序自然不能得到正确的参数数据。*/

转载,方法1

2、同上,类似的例子。 转自 链接2

MFC应用程序用以下几种方法接收命令行参数

假设执行了命令:D:/Test.exe -arg1 -arg2

1、::GetCommandLine();    //将获取到  "D:/Test.exe" -arg1 -arg2

2、 for (int i=0;i<__argc;i++)  __argv[i];        //将依次得到 D:/Test.exe -arg1 -arg2

3、AfxGetApp()->m_lpCmdLine;   //将获取到 -arg1 -arg2

  第2条 注解:

//几个可以使用的全局变量:
_CRTIMP extern int __argc; /* count of cmd line args */
_CRTIMP extern char ** __argv; /* pointer to table of cmd line args */
_CRTIMP extern wchar_t ** __wargv; /* pointer to table of wide cmd line args */ //如果是MFC项目,可以使用CWinAppm_lpCmdLine变量,注意这个m_lpCmdLine中不包含应用程序自身路径。

个人方法:写出对命令行 cmdinfo 的分析解析函数,采用其中需要的参数。

void CMyApp::ParseComand(CCommandLineInfo &commandinfo)
{
for(int i=;i<__argc;i++) //将程序的第一个参数 跳过,
{
CString m_str;
m_str=__argv[i];
MessageBox(NULL,m_str,_T(""),MB_OK);
}
if (__argc>)
{
__argc=; //其他参数进行操作后,只留下第一个参数, }
// 下一句,根据程序情况进行增删
ParseCommandLine(mycmdinfo);
}
    

NEXT:

    CCommandLineInfo mycmdinfo;
ParseComand(mycmdinfo);//------------ if (!ProcessShellCommand(mycmdinfo))
return FALSE;

 

  这个方法,可以解决出现文件不存在的情况。 如图。

9、View、 MainFrame、 App 、Doc 相互调用

对于单文档单VIEW的情况

1)CMainFrame:

CMyView   *pView=(CMyView   *)this‐>GetActiveView(); //this即当前CMainFrame,可省略 ,GetActiveView()可得到View指针。

CMySDIDoc   *pDoc= pView->GetDocument();//GetActiveDocument()可得到Document指针,但需要依据 pView

CMenu   *pMenu=this->GetMenu();  //GetMenu()获得菜单指针。

2)CDoc:

POSITION pos = GetFirstViewPosition();

CView* pView = GetNextView(pos); //得到View指针  具体解释

     或者     

CMainFrame   *pMain=(CmaimFrame   *)AfxGetApp()‐>m_pMainWnd;    

CMyView   *pView=(CMyView   *)pMain‐>GetActiveView(); 

3) CView:

CMySDIDoc   *pDoc=this->GetDocument();    //一个视只能有一个文档,this 即CView,可省略 ,GetDocument()可得到CDoc指针。

CMainFrame* pframe=(CMainFrame*)AfxGetMainWnd();//AfxGetMainWnd()可得到MainFrame指针

或者

CMainFrame* pframe=(CMainFrame*)AfxGetApp()->m_pMainWnd;

4) CApp:

    成员变量 m_pMainWnd变量就是MainFrame的指针  

或者

    CMainFrame   *pMainFrame   =(CMainFrame*)AfxGetMainWnd();

或者

    CMainFrame   *pMainframe=(CMainFrame*)AfxGetApp();

5) 在任何类中获得应用程序类

 用MFC全局函数AfxGetApp()获得

6) 获得状态栏与工具栏指针

CStatusBar   *pStatusBar=(CStatusBar   *)AfxGetMainWnd()‐>GetDescendantWindow(AFX_IDW_STATUS_BAR);
CToolBar *pToolBar=(CtoolBar *)AfxGetMainWnd()‐>GetDescendantWindow(AFX_IDW_TOOLBAR); //如果框架中加入工具栏和状态栏变量还可以这样 (CMainFrame *)GetParent()‐>m_wndToolBar;
(CMainFrame *)GetParent()‐>m_wndStatusBar;

注意:

1、 在不同类之间进行调用时,需要声明,引用头文件夹  比如

2、引用的同时有的需要引入多个文件,比如 CMyView *pView=(CMyView *)this‐>GetActiveView(); 时,需要引用

 #include "CMyDoc.h"
#include "CMyview.h"

同时注意引用的前后顺序。

MFC中小笔记(二)的更多相关文章

  1. 《MFC游戏开发》笔记二 建立工程、调整窗口

    本系列文章由七十一雾央编写,转载请注明出处.  http://blog.csdn.net/u011371356/article/details/9300383 作者:七十一雾央 新浪微博:http:/ ...

  2. MFC 学习笔记

    MFC 学习笔记 一.MFC编程基础: 概述: 常用头文件: MFC控制台程序: MFC库程序: 规则库可以被各种程序所调用,扩展库只能被MFC程序调用. MFC窗口程序: 示例: MFC库中类的简介 ...

  3. 《CMake实践》笔记二:INSTALL/CMAKE_INSTALL_PREFIX

    <CMake实践>笔记一:PROJECT/MESSAGE/ADD_EXECUTABLE <CMake实践>笔记二:INSTALL/CMAKE_INSTALL_PREFIX &l ...

  4. jQuery源码笔记(二):定义了一些变量和函数 jQuery = function(){}

    笔记(二)也分为三部分: 一. 介绍: 注释说明:v2.0.3版本.Sizzle选择器.MIT软件许可注释中的#的信息索引.查询地址(英文版)匿名函数自执行:window参数及undefined参数意 ...

  5. Mastering Web Application Development with AngularJS 读书笔记(二)

    第一章笔记 (二) 一.scopes的层级和事件系统(the eventing system) 在层级中管理的scopes可以被用做事件总线.AngularJS 允许我们去传播已经命名的事件用一种有效 ...

  6. Python 学习笔记二

    笔记二 :print 以及基本文件操作 笔记一已取消置顶链接地址 http://www.cnblogs.com/dzzy/p/5140899.html 暑假只是快速过了一遍python ,现在起开始仔 ...

  7. WPF的Binding学习笔记(二)

    原文: http://www.cnblogs.com/pasoraku/archive/2012/10/25/2738428.htmlWPF的Binding学习笔记(二) 上次学了点点Binding的 ...

  8. webpy使用笔记(二) session/sessionid的使用

    webpy使用笔记(二) session的使用 webpy使用系列之session的使用,虽然工作中使用的是django,但是自己并不喜欢那种大而全的东西~什么都给你准备好了,自己好像一个机器人一样赶 ...

  9. AJax 学习笔记二(onreadystatechange的作用)

    AJax 学习笔记二(onreadystatechange的作用) 当发送一个请求后,客户端无法确定什么时候会完成这个请求,所以需要用事件机制来捕获请求的状态XMLHttpRequest对象提供了on ...

随机推荐

  1. [译]ASP.NET Core 2.0 全局配置项

    问题 如何在 ASP.NET Core 2.0 应用程序中读取全局配置项? 答案 首先新建一个空项目,并添加两个配置文件: 1. appsettings.json { "Section1&q ...

  2. nginx + tomcat + redis 部署项目,解决session共享问题。

    最近自己搭了一套nginx的环境,集群部署了公司的一个项目,中间解决了session共享的问题.记录如下,以备日后查看. 1.环境 windows10 家庭中文版,jdk 7, tomcat 7.0. ...

  3. Java基础笔记9

    super关键字 表示父类对象. 1.可以调用父类中被重写的方法. 2.还有调用父类中的构造方法.放在子类构造方法的第一行. 不能和this关键字同时出现. final关键字 1.修饰属性.表示常量. ...

  4. .6-Vue源码之AST(2)

    上一节获取到了DOM树的字符串,准备进入compile阶段: // Line-9326 function compileToFunctions(template,options,vm) { // 获取 ...

  5. Java 常用正则表达式,Java正则表达式,Java身份证校验,最新手机号码正则表达式

    Java 常用正则表达式,Java正则表达式,Java身份证校验,最新手机号码校验正则表达式 ============================== ©Copyright 蕃薯耀 2017年11 ...

  6. MySQL冗余和重复索引

    MySQL允许在相同列上创建多个索引,无论是有意还是无意,mysql需要单独维护重复的索引,并且优化器在优化查询的时候也需要逐个地进行考虑,这会影响性能. 重复索引是指的在相同的列上按照相同的顺序创建 ...

  7. 如何在 Apple TV 上使用描述文件

    您可以使用 OS X 上的 Apple Configurator 在 Apple TV 上安装配置描述文件. 开始前,请在 Mac 上安装最新版本的 Apple Configurator(如果尚未安装 ...

  8. 基于netfilter和LVM的密码窃取

    一:要求: 编写一个基于netfilter的模块,该模块的功能是捕获如mail.ustc.edu.cn等使用明文传输用户名和密码的网站的用户名和密码:并在接收到特定的ICMP数据包之后将捕获的用户名和 ...

  9. 蓝桥杯-算法训练--ALGO-8 操作格子

    问题描述 有n个格子,从左到右放成一排,编号为1-n. 共有m次操作,有3种操作类型: 1.修改一个格子的权值, 2.求连续一段格子权值和, 3.求连续一段格子的最大值. 对于每个2.3操作输出你所求 ...

  10. display:none和visibility:hidden区别

    <!-- display:none和visible:hidden都能把网页上某个元素隐藏起来,但两者有区别: --> <!-- display:none 不为被隐藏的对象保留其物理空 ...