易忽略点总结:
使用书签的方法生成我们所需要的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截取对话框图像或者截取全屏图像
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);
}