项目积木积累1

易忽略点总结:

1.使用MFC操作Word(使用模板)

使用书签的方法生成我们所需要的word文档

2.mfc建的一个文档,要按上面的保存按钮后保存文档,该怎么做? 

	TCHAR szFilter[] = _T("Word文件(*.doc)|*.doc|所有文件(*.*)|*.*||");
	// 构造保存文件对话框    
	CFileDialog fileDlg(FALSE, _T("doc"), _T("报告"), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter, this);
	CString strFilePath;
	CStdioFile file;
	CString a;

	GetDlgItemText(IDC_SAVE_EDIT, a);
	// 显示保存文件对话框    
	if (IDOK == fileDlg.DoModal())
	{
		// 如果点击了文件对话框上的“保存”按钮,则将选择的文件路径显示到编辑框里    
		strFilePath = fileDlg.GetPathName();
		file.Open(strFilePath, CFile::modeCreate | CFile::modeWrite | CFile::typeText);
		file.WriteString(a);  //写入edit box中的数据
		file.Close();
		//SetDlgItemText(IDC_SAVE_EDIT, strFilePath);    
	}

3. MFC选择文件夹的对话框-我需要是保存文件,能弹出一个选择文件夹对话框,实际搜索要这样去搜,才能模糊搜索到

/*
文件:SelectFolderDlg.h
说明:提供一个选择文件夹的对话框
*/

#ifndef SELECT_FOLDER_DLG_H
#define SELECT_FOLDER_DLG_H


#ifndef BIF_NEWDIALOGSTYLE
#define  BIF_NEWDIALOGSTYLE  0x0040
#endif

class CSelectFolderDlg
{
public:
	//创建一个选择文件夹的对话框,返回所选路径
	static CString Show()
	{
		TCHAR			szFolderPath[MAX_PATH] = {0};
		CString			strFolderPath = TEXT("");
		
		BROWSEINFO		sInfo;
		::ZeroMemory(&sInfo, sizeof(BROWSEINFO));
		sInfo.pidlRoot   = 0;
		sInfo.lpszTitle   = _T("请选择一个文件夹:");
		sInfo.ulFlags   = BIF_DONTGOBELOWDOMAIN | BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE | BIF_EDITBOX;
		sInfo.lpfn     = NULL;

		// 显示文件夹选择对话框
		LPITEMIDLIST lpidlBrowse = ::SHBrowseForFolder(&sInfo); 
		if (lpidlBrowse != NULL)
		{
			// 取得文件夹名
			if (::SHGetPathFromIDList(lpidlBrowse,szFolderPath))  
			{
				strFolderPath = szFolderPath;
			}
		}
		if(lpidlBrowse != NULL)
		{
			::CoTaskMemFree(lpidlBrowse);
		}

		return strFolderPath;

	}

};

#endif

应用到自己项目中,需要这个返回出来的路径:strFolderPath

	///创建一个选择文件夹的对话框,返回所选路径  
	TCHAR           szFolderPath[MAX_PATH] = { 0 };
	CString         strFolderPath = TEXT("");

	BROWSEINFO      sInfo;
	::ZeroMemory(&sInfo, sizeof(BROWSEINFO));
	sInfo.pidlRoot = 0;
	sInfo.lpszTitle = _T("请选择一个文件夹保存文档:");
	sInfo.ulFlags = BIF_DONTGOBELOWDOMAIN | BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE | BIF_EDITBOX;
	sInfo.lpfn = NULL;

	// 显示文件夹选择对话框  
	LPITEMIDLIST lpidlBrowse = ::SHBrowseForFolder(&sInfo);
	if (lpidlBrowse != NULL)
	{
		// 取得文件夹名  
		if (::SHGetPathFromIDList(lpidlBrowse, szFolderPath))
		{
			strFolderPath = szFolderPath;
		}
	}
	if (lpidlBrowse != NULL)
	{
		::CoTaskMemFree(lpidlBrowse);
	}
把strFolderPath拿到其他地方,可以使用

4.MFC获取系统当前时间

1.使用CTime类   

 

CString str; //获取系统时间   

CTime tm; tm=CTime::GetCurrentTime();   

str=tm.Format("现在时间是%Y年%m月%d日 %X");

MessageBox(str,NULL,MB_OK);

5.想实现如何把VC每次生成的word文件保存为不同的文件名,请问如何实现??

思路:

使用不同的文件名
将文件名作为参数传入saveas函数
比如文件名可以有个固定的名字:fileName,然后在固定名字后面加上时间戳
这样就永远都不会覆盖了
 
	//把生成的word报告保存到用户想要的指定路径//VARIANT* FileName, 文档保存路径	//    covOptional,  //文档的保存格式
	///创建一个选择文件夹的对话框,返回所选路径  
	TCHAR           szFolderPath[MAX_PATH] = { 0 };
	CString         strFolderPath = TEXT("");

	BROWSEINFO      sInfo;
	::ZeroMemory(&sInfo, sizeof(BROWSEINFO));
	sInfo.pidlRoot = 0;
	sInfo.lpszTitle = _T("请选择一个文件夹保存文档:");
	sInfo.ulFlags = BIF_DONTGOBELOWDOMAIN | BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE | BIF_EDITBOX;
	sInfo.lpfn = NULL;

	// 显示文件夹选择对话框  
	LPITEMIDLIST lpidlBrowse = ::SHBrowseForFolder(&sInfo);
	if (lpidlBrowse != NULL)
	{
		// 取得文件夹名  
		if (::SHGetPathFromIDList(lpidlBrowse, szFolderPath))
		{
			strFolderPath = szFolderPath;
		}
	}
	if (lpidlBrowse != NULL)
	{
		::CoTaskMemFree(lpidlBrowse);
	}
	//获取时间戳
	CTime currTime;
	currTime = CTime::GetCurrentTime();
	CString strTime;
	strTime.Format(_T("%.4d-%.2d-%.2d-%.2d-%.2d-%.2d"), currTime.GetYear(), currTime.GetMonth(), currTime.GetDay(), currTime.GetHour(), currTime.GetMinute(), currTime.GetSecond());
	CString strSavePath;
	strSavePath = strFolderPath + "\\"+ strTime + _T(".docx");
	docx.SaveAs(COleVariant(strSavePath), covOptional, covOptional, covOptional, covOptional,
		covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional);

6.MFC基于对话框上插入MENU菜单栏并点击菜单弹出新窗口

百度时候:先搜MFC点击菜单弹出新窗口-模糊搜索

7.MFC中获取文件的相对路径与绝对路径 在做项目过程中一切涉及到从外面选路径进来,一定要注意是相对路径,不能在项目里面有绝对路径的东西出现,否则会报错很多

        //CString strExePath, strExePath2; 老狗的代码
	//CString strPath;
	//GetModuleFileName(NULL, strPath.GetBufferSetLength(MAX_PATH + 1), MAX_PATH + 1);
	//int nPos = strPath.ReverseFind(_T('\\'));
	//strExePath = strPath.Left(nPos + 1);		  
	//strExePath2 = strExePath + _T("template.dot");
	//MessageBox(strExePath);//显示debug所在路径
	//MessageBox(strExePath2);//显示获取的指向.dot模板路径

	//MFC获取程序目录相对路径,小心文件是放在项目外面的x64-Debug里面  自己写的
	CString path;
	GetModuleFileName(NULL, path.GetBufferSetLength(MAX_PATH + 1), MAX_PATH);
	path.ReleaseBuffer();
	int pos = path.ReverseFind('\\');
	path = path.Left(pos);
	path = path + _T("\\template2.dot");
	//MessageBox(path);
	COleVariant    covZero((short)0),
		covTrue((short)TRUE),
		covFalse((short)FALSE),
		covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR),
		covDocxType((short)0),
		start_line, end_line,
		dot(path);//相对路径
		//dot(_T("F:\\template2.dot"));// 绝对路径

8.利用MFC截取对话框图像或者截取全屏图像

利用MFC截取对话框图像或者截取全屏图像

9.解决MFC读取txt,分割显示到listctrl控件上这个积木

1.先搜MFC如何读取txt.在搜listctrl控件如何显示信息--搜索时候,注意不要涉及太多控件,一个就好,搜索不超过十个字,积木论第二条

2.阅读相关博客:MFC逐行读取txt文件内容    MFC:读取整个记事本文件 利用了其中部分代码,来做MFC读取txt文本信息

MFC读取txt,分割显示到listctrl控件上抓住这篇文章实现功能的思路,进行操作,发现自己实现了指定路径下读取txt文本信息,以及选择文件夹对话框,来读取相关txt信息,按照实现功能思路,下一步,我需要做的是进行分割字符操作,于是我看了如下有用博客:MFC按行读取txt数据并分割每行数据 发现此分割函数,无法满足我的需要,于是又利用了这篇博客:VC中自带的只有使用字符分割字符串的split函数,运行其中API函数,到自己代码当中,最后一步需要显示到自己listctrl控件,利用这篇博客ListCtrl控件的使用中一句代码:

m_listctrl.SetItemText(i,0,buf);//显示在当前行的第0列

形成如下代码:

在海上目标检测跟踪Dlg.cpp文件中添加“分割文本信息的字符函数”的声明


//分割文本信息的字符函数
int SplitString(LPCTSTR lpszStr, LPCTSTR lpszSplit, CStringArray& rArrString, BOOL bAllowNullString)
{
	rArrString.RemoveAll();
	CString szStr = lpszStr;
	szStr.TrimLeft();
	szStr.TrimRight();
	if (szStr.GetLength() == 0)
	{
		return 0;
	}
	CString szSplit = lpszSplit;
	if (szSplit.GetLength() == 0)
	{
		rArrString.Add(szStr);
		return 1;
	}
	CString s;
	int n;
	do {
		n = szStr.Find(szSplit);
		if (n > 0)
		{
			rArrString.Add(szStr.Left(n));
			szStr = szStr.Right(szStr.GetLength() - n - szSplit.GetLength());
			szStr.TrimLeft();
		}
		else if (n == 0)
		{
			if (bAllowNullString)
				rArrString.Add(_T(""));
			szStr = szStr.Right(szStr.GetLength() - szSplit.GetLength());
			szStr.TrimLeft();
		}
		else
		{
			if ((szStr.GetLength()>0) || bAllowNullString)
				rArrString.Add(szStr);
			break;
		}
	} while (1);
	return (int)rArrString.GetSize();
}


void C海上目标检测跟踪Dlg::OnBnClickedFileConfiguration()
{

	// TODO:  在此添加控件通知处理程序代码
	//CString strFileName = _T("F:\\abc.txt");//指定路径
	//选择任一路径
	CString strFileName;
	CStdioFile file;
	CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
		_T("txt记事本(*.txt)|*.txt|ini文档(*.ini)|*.ini|pem文档(*.pem)|*.pem||"), AfxGetMainWnd());
	if (IDOK == dlg.DoModal())
	{
		strFileName = dlg.GetPathName();
		//SetDlgItemText(IDC_FileNameEdit, strFileName);//显示打开要读取配置文件位置
		if (!PathFileExists(strFileName))
		{
			MessageBox("打开文件错误");
		}
		if (!file.Open(strFileName, CFile::modeRead))
		{
			MessageBox("打开文件错误");
		}
		//vector<CString> vecResult;
		CString strValue = _T("");
		CString szSplit = _T(",");
		CStringArray szList;
		int rows = 0;//行数
		while (file.ReadString(strValue))
		{
			//字符分割函数

			int Count = SplitString(strValue, szSplit, szList, FALSE);
			if (0 == Count)
			{
				MessageBox(TEXT("err"));
			}
			//CString a1 = szList.GetAt(0);
			//CString a2 = szList.GetAt(1);
			//CString a3 = szList.GetAt(2);	
			int t = 0;	
			for (int columns = 1; columns < 11 && (t < Count); columns++)
			{		
				m_list.SetItemText(rows, columns, szList[t]);//显示在当前行的第0列
				++t;
			}
			++rows;
			//strValue.TrimRight();//消除从右侧起所遇到的所有空格字符
			//szList.Add(strValue);//这句就是每次都把读到的strValue压入szList中
		}
		file.Close();
	}
}

但是当你完全这样照做时候,会发现显示在listctrl控件信息会出现,英文不乱码,中文乱码,这个时候,需要看这篇博客解决这个问题:使用MFC编写的程序有乱码怎么办?但是,当你这么照做会出现一些错误,你需要一个个去解决,比如会遇到一些问题:

1."SetWindowTextW": 不是“CWnd”或者“CButton”的成员怎么解决?:我采用把所有的"SetWindowTextW"改成"SetWindowTextA"即可;

2.有时候你会发现AfxMessageBox会报错,那就改成MessageBox()来操作,发现就可以了

3.当你所有bug都解决的后,你会发现你的listctrl控件信息显示,有些不是很完整,那你就要小心文本信息中小括号不能是中文输入法打进去,当英文输入法打小括号就ok了,能完全显示了

10.如何在子界面里初始化下拉框CCombox?

对于这个问题,我们需要解决第一个问题是MFC子窗口怎么设置OnInitDialog函数

类向导---(选择子窗口的类)---增加虚函数 --- 选择OnInitDialog

解决第二个问题是:当你写入类似如下程序:
	// TODO:  在此添加额外的初始化代码
	//下拉框添加
	m_cbx.AddString(TEXT("唐僧"));
	m_cbx.AddString(TEXT("孙悟空"));
	m_cbx.AddString(TEXT("猪八戒"));
	m_cbx.AddString(TEXT("沙僧"));
	

	//设置默认选项
	m_cbx.SetCurSel(0);

	//插入
	m_cbx.InsertString(4,TEXT("白龙马"));
	//删除
	m_cbx.DeleteString(3);

	CString str;
	//获取1号的索引的具体内容
	m_cbx.GetLBText(1,str);//void GetLBText(int nIndex, CString& rString) const;
	MessageBox(str);

运行后,子界面的下拉框中内容无法显示完全,这个时候你需要做的是设置问题。你点那个向下得小箭头,可以拖动扩大左右,再点一次就可以拖动向下的显示长度。你需要多长就拖多长。运行起来就可以了

11.解决创建一个选择文件夹的对话框,点击按钮弹出系统自带选择文件夹对话框,但是点击“取消”或者“弹出框的X”,会对后面的代码造成影响,这个时候我所采用方法是:当用户不选择时候,进行提示,并且在if语句中加循环,直至用户进行选择为止

	//把生成的word报告保存到用户想要的指定路径//VARIANT* FileName, 文档保存路径	//    covOptional,  //文档的保存格式
	///创建一个选择文件夹的对话框,返回所选路径  
	TCHAR           szFolderPath[MAX_PATH] = { 0 };
	CString         strFolderPath = TEXT("");

	BROWSEINFO      sInfo;
	::ZeroMemory(&sInfo, sizeof(BROWSEINFO));
	sInfo.pidlRoot = 0;
	sInfo.lpszTitle = _T("请选择一个文件夹保存文档:");
	sInfo.ulFlags = BIF_DONTGOBELOWDOMAIN | BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE | BIF_EDITBOX;
	sInfo.lpfn = NULL;

	// 显示文件夹选择对话框  
	LPITEMIDLIST lpidlBrowse = ::SHBrowseForFolder(&sInfo);
	if (NULL == lpidlBrowse)
	{
		AfxMessageBox("没有选择路径,请重新选择!");
		while (!lpidlBrowse)
		{
			// 重新显示文件夹选择对话框
			lpidlBrowse = ::SHBrowseForFolder(&sInfo);
			// 重新取得文件夹名  
			if (::SHGetPathFromIDList(lpidlBrowse, szFolderPath))
			{
				strFolderPath = szFolderPath;
			}
		}
	}
	else
	{
		//取得文件夹名
		if (::SHGetPathFromIDList(lpidlBrowse, szFolderPath))
		{
			strFolderPath = szFolderPath;
		}
	}
	//释放资源
	if (lpidlBrowse != NULL)
	{
		::CoTaskMemFree(lpidlBrowse);
	}

12.解决播放按钮“开始”,点击之后,进行选择视频文件,如果没选,就会发生bug,无法进行正常播放

解决方法:采用当模态对话框显示时,程序会暂停执行,直到关闭这个模态对话框之后,才能执行程序中的其他任务,所以第一个模态对话框出现后,如果你还想出现对话框,必须要去重新做个打开文件对话框,用新的模态对话框,来进行操作

	//指定路径打开视频文件
	//pCapture = cvCreateFileCapture("F://text1.mp4");
	// 构造打开文件对话框 
	TCHAR szFilter[] = _T("媒体文件(*.avi,*.rm,*.rmvb,*.mkv,*.mp4)|*.avi;*.rm;*.rmvb;*.mkv;*.mp4|");
	CFileDialog fileDlg(TRUE, _T("txt"), NULL, OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY, szFilter, NULL);//选项图片的约定
	CString strFilePath;
	fileDlg.m_ofn.lpstrTitle = _T("请选择需要处理的视频!");//设置标题  
	int clickflag = (IDOK == fileDlg.DoModal()); //连起来看的一起是,显示一个模态对话框,当你按下确认按钮时,执行这里面的代码
	
	//重新显示 文件对话框   直到选择到相应的视频文件
	TCHAR szFilter1[] = _T("媒体文件(*.avi,*.rm,*.rmvb,*.mkv,*.mp4)|*.avi;*.rm;*.rmvb;*.mkv;*.mp4|");
	// 构造打开文件对话框   
	CFileDialog fileDlg1(TRUE, _T("txt"), NULL, OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY, szFilter, NULL);//选项图片的约定
	fileDlg1.m_ofn.lpstrTitle = _T("请选择需要处理的视频!");//设置标题  
	// 显示打开文件对话框   
	//来解决bug:当视频文件未选择进来时候,无法正常播放视频
	if (!clickflag)
	{
		AfxMessageBox(_T("未选择视频文件,请重新选择相应的视频文件!"));
		//当模态对话框显示时,程序会暂停执行,直到关闭这个模态对话框之后,才能执行程序中的其他任务
		//这里需要重新再设置一个,才能弹出新的模态对话框
		clickflag = (IDOK == fileDlg1.DoModal()); //连起来看的一起是,显示一个模态对话框,当你按下确认按钮时,执行这里面的代码
		while (clickflag)
		{
			strFilePath = fileDlg1.GetPathName();//小心这里必须是fileDlg1 否则还会有bug问题依然存在
			pCapture = cvCreateFileCapture(strFilePath);
			break;
		}
	}else{
		strFilePath = fileDlg.GetPathName();
		pCapture = cvCreateFileCapture(strFilePath);
	}

13.当程序正常运行时候,发现我直接点击对话框右上角x号,整个系统会发生中断崩溃状态,这个时候我想了办法,就是禁止这个x号,自己做一个退出按钮,来退出系统

禁用对话框右上角的关闭按钮 运用这里方法,来把右上角关闭按钮给禁止掉


自己添加一个CButton,退出系统按钮:双击后添加消息响应函数

//禁用MFC对话框关闭按钮后,自己做的退出系统的消息处理
void C海上目标检测跟踪Dlg::OnBnClickedExit()
{
	// TODO:  在此添加控件通知处理程序代码
	if (::MessageBox(NULL, "Save the current interface before exit?", "System Exit", MB_OKCANCEL) == IDOK)
	{
		exit(0);//1.退出程序
	}
	

	//2.退出当前对话框
	//CDialog::OnOK();

	//3.取消对话框
	//CDialog::OnCancel();

}

在做的过程中看到,MFC对话框Enter键、Esc键、关闭按钮的消息处理,发现我的系统也出现这样的情况,于是我也进行如下操作,来禁掉这些按键,防止程序正常运行中,发生秒退系统,系统发生崩溃:类视图下点击C...Dlg.cpp右击选择属性,点击重写找到:


//重载PreTranslateMessage函数,屏蔽对话框的Enter、Esc键盘消息
BOOL C海上目标检测跟踪Dlg::PreTranslateMessage(MSG* pMsg)
{
	// TODO:  在此添加专用代码和/或调用基类
	if (pMsg->message == WM_KEYDOWN)
	{
		switch (pMsg->wParam)
		{
		case VK_RETURN:
			return TRUE;

		case VK_ESCAPE:
			return TRUE;

		default:
			break;
		}
	}
	return CDialogEx::PreTranslateMessage(pMsg);
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值