402上位机VC MFC实现参数文件拖拽或双击打开
实现文件拖拽或双击打开
功能展示
参数文件的打开方式有多种,可通过选择对话框选择打开,可拖拽文件到窗口打开,可双击文件图标打开,我们当前例程通过这三种方式打开参数文件,效果如图。点击两个按钮可以弹出对话框进行保存或打开文件操作,将参数文件拖拽到窗口上可以打开读取参数文件,双击参数文件也可打开与读取文件参数,读取成功都会将参数文件名称显示在窗口正上方;
要点提示
例程实现三种方式打开文件,方法一直接通过CFileDialog打开文件,通过构造一个实例,再调用实例的DoModal()函数就可方便选择要打开的文件,文件是打开还是保存可修改其构造函数参数实现,CFileDialog( BOOL bOpenFileDialog, LPCTSTR lpszDefExt = NULL, LPCTSTR lpszFileName = NULL, DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, LPCTSTR lpszFilter = NULL, CWnd* pParentWnd = NULL );
bOpenFileDialog:TRUE为打开文件对话框;FALSE为保存文件对话框。
lpszDefExt:缺省的扩展名
lpszFileName:缺省显示在文件名组合框的编辑框的文件名,一般可选NULL
dwFlags:对话框风格,一般为OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, 即隐藏只读选项和覆盖已有文件前提示。其他不常用类型可查阅MSDN手册。
lpszFilter:文件筛选类型,它指明可供选择的文件类型和相应的扩展名。参数格式如:? "Chart Files (*.xlc)|*.xlc|Worksheet Files (*.xls)|*.xls|Data Files (*.xlc;*.xls)|*.xlc; *.xls|All Files (*.*)|*.*||";文件类型说明和扩展名间用 | 分隔,同种类型文件的扩展名间可以用 ; 分割,每种文件类型间用 | 分隔,末尾用 || 指明。
pParentWnd:父窗口指针,一般可选NULL.
文件的拖拽打开分两步实现,首先设置窗口具有WS_EX_ACCEPTFILES风格,可通过设置对话框资源属性,可可通过代码ModifyStyleEx(m_hWnd,0,WS_EX_ACCEPTFILES,NULL);实现。其次是关联消息WM_DROPFILES的处理函数,在函数内部实现拖拽文件的参数读取;
双击文件打开方式首先得将文件类型与我们的程序关联,既实现参数文件后缀用我们程序打开。
双击文件时,系统都会将文件的路径传递到程序入口函数中,对话框中程序可在APP类的InitInstance()函数中调用CCommandLineInfo cmdInfo; ParseCommandLine(cmdInfo); cmdInfo.m_strFileName就是双击文件时系统传递的文件路径。
其次是上位机程序仅允许运行一个,所以还得实现单实例运行,即仅运行一个程序,双击文件打开的其它实例必须全部终止运行,在终止前还得向运行中实例传递文件路径,例程通过自定义函数IsProgramRunning()实现这些功能
这里要提示的是,对注册表的操作在WIN7系统上有时得具有管理员操作权限,可以参照前面例程实现权限获取
实现功能
1.新建基于对话框的应用程序
2.依次添加11个编辑框IDC_EDIT1到IDC_EDIT11,一复选框IDC_CHECK1及一静态文本IDC_NAME用于测试参数保存功能,添加两按钮<选择工艺文件><保存为..>关联点击函数,实现文件的打开保存功能
void CGkbc8Dlg::OnSave()
{
CFileDialog FileDlg(FALSE,".pra","工控编程吧",
OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "工艺文件(*.pra)|*.pra||",NULL);
if(IDOK == FileDlg.DoModal())
{
CStdioFile File;
if(!File.Open(FileDlg.GetPathName(),CFile::modeCreate|CFile::modeWrite) )
{
MessageBox("参数文件保存失败");
return;
}
CString sTemp;
int nData;
nData = GetDlgItemInt(IDC_EDIT1);
sTemp.Format("%d\r\n",nData);
File.WriteString(sTemp);
nData = GetDlgItemInt(IDC_EDIT2);
sTemp.Format("%d\r\n",nData);
File.WriteString(sTemp);
nData = GetDlgItemInt(IDC_EDIT3);
sTemp.Format("%d\r\n",nData);
File.WriteString(sTemp);
nData = GetDlgItemInt(IDC_EDIT4);
sTemp.Format("%d\r\n",nData);
File.WriteString(sTemp);
nData = GetDlgItemInt(IDC_EDIT5);
sTemp.Format("%d\r\n",nData);
File.WriteString(sTemp);
nData = GetDlgItemInt(IDC_EDIT6);
sTemp.Format("%d\r\n",nData);
File.WriteString(sTemp);
nData = GetDlgItemInt(IDC_EDIT7);
sTemp.Format("%d\r\n",nData);
File.WriteString(sTemp);
nData = GetDlgItemInt(IDC_EDIT8);
sTemp.Format("%d\r\n",nData);
File.WriteString(sTemp);
nData = GetDlgItemInt(IDC_EDIT9);
sTemp.Format("%d\r\n",nData);
File.WriteString(sTemp);
nData = GetDlgItemInt(IDC_EDIT10);
sTemp.Format("%d\r\n",nData);
File.WriteString(sTemp);
nData = GetDlgItemInt(IDC_EDIT11);
sTemp.Format("%d\r\n",nData);
File.WriteString(sTemp);
nData = ((CButton*)GetDlgItem(IDC_CHECK1))->GetCheck();
sTemp.Format("%d\r\n",nData);
File.WriteString(sTemp);
File.Close();
MessageBox("已保存参数");
}
}
void CGkbc8Dlg::OnChoose()
{
CFileDialog FileDlg(TRUE,".pra","工控编程吧",
OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "工艺文件(*.pra)|*.pra||",NULL);
if(IDOK == FileDlg.DoModal())
{
LoadParameter(FileDlg.GetPathName());
}
}
3.上面有一自定义函数LoadParameter()用于加载文件,自己复制添加。再来实现文件拖拽打开,程序初始化调用代码ModifyStyleEx(m_hWnd,0,WS_EX_ACCEPTFILES,NULL);设置窗口拖拽文件属性,关联消息WM_DROPFILES处理函数,实现拖拽文件的内容读取
void CGkbc8Dlg::OnDropFiles(HDROP hDropInfo)
{
/* //判断拖入文件的个数,这里只取第一个即可
UINT nNumOfFiles = DragQueryFile(hDropInfo, 0xFFFFFFFF, szFileName, 1024);
*/
TCHAR szFileName[_MAX_PATH] = {0};
DragQueryFile(hDropInfo, 0, szFileName, _MAX_PATH);
CString sFilePath(szFileName);
sFilePath = sFilePath.Right(sFilePath.GetLength()-sFilePath.ReverseFind('.'));
if(sFilePath.Compare(".pra"))
{
MessageBox("文件类型不匹配");
return;
}
LoadParameter(szFileName);
CDialog::OnDropFiles(hDropInfo);
}
4.实现双击文件打开功能,分两步处理:通过注册表实现双击指定后缀文件打开我们的程序,既在主对话框中调用一次自定义函数ConectFileType()设置下注册表便可;
5.在APP类中添加自定义函数IsProgramRunning()并在InitInstance()中调用
CCommandLineInfo cmdInfo; ParseCommandLine(cmdInfo); m_FilePath = cmdInfo.m_strFileName
if(IsProgramRunning()) return FALSE;
用于判断程序是否已运行,运行中则会传递消息WM_COPYDATA,顺带传递双击文件的路径,在主对话框类中添加消息WM_COPYDATA处理函数,接收传递过来双击文件的路径,与此同时再调用自定义函数LetMeShow()将程序最前端显示。另外为了实现仅允许一实例运行,还得在主对话框初始化时添加SetProp(m_hWnd,sPropName,(HANDLE)1);退出时添加RemoveProp(m_hWnd,sPropName); PropName为定义的一字符串#define sPropName "Gkbc8_OnlyRunOneInstance“
6.第五步中m_FilePath 为CString 类型用于保存双击的文件路径,在每次主对话框运行时都判断此变量是否带有双击文件的路径,有侧说明用户双击了文件,我们读取文件内容
CString sFilePath = ((CGkbc8App*)AfxGetApp())->m_FilePath;
if( !sFilePath.IsEmpty() )
{//双击文件方式启动程序时加载文件参数
LoadParameter(sFilePath);
((CGkbc8App*)AfxGetApp())->m_FilePath.Empty();
}
我们来演示下功能实现的整个过程
如果您认可,可联系功能定制! 如果您着急,充值会员可直接联系发您资料!
|