MFC的使用记录和总结

本文详细介绍如何使用MFC在Visual Studio中构建图形用户界面,包括文本框数据读取、图像显示及保存等操作,并提供了实例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 关于MFC的一些说明

    • MFC在Visual studio中,用于制作可视化界面,有点类似于Qt。
    • 关于MFC的介绍,可以参考一些大佬的博客 ;
  • 首先需要在类中声明需要用到的变量

class CMy03intrinsiccompareDlg : public CDialogEx
{
public:
	double k1[12] = { 0,0,0,0,0,0,0,0,0,0,0,0 };
	CString str_intrinsic_1;	
	int enlarge;
}
  • 从编辑文本框中获取字符,并将字符转换成double数组
void CMy03intrinsiccompareDlg::OnBnClickedButton1(){
	CString str_intrinsic_1;
	double k1[12] = { 0,0,0,0,0,0,0,0,0,0,0,0 };
	
	GetDlgItem(IDC_EDIT1)->GetWindowText(str_intrinsic_1);
	//判断str_intrinsic_1是否有除了数字、负号、空格、的情况出现
	if (!judge_image_sie(str_intrinsic_1)) {
			return;
		}
		//将cstring转换成数组
	cstring2array(str_intrinsic_1, k1);
}
bool CMy03intrinsiccompareDlg::judge_intrinsic(CString intrinsic) {
	
	bool a = true;
	if (intrinsic.GetAt(0) == ' ' && intrinsic.GetLength() == 1) {

		MessageBox("未输入内参,请输入内参数据 M[4] D[8],用空格分开。");
		a = false;
		return a;
	}
	if (intrinsic.GetAt(0) == ' ') {
		MessageBox("内参的第一个字符不能是空格,请输入内参数据 M[4] D[8],用空格分开");
		a = false;
		return a;
	}
	for (int i = 0; i < intrinsic.GetLength(); i++) {
		int temp = intrinsic.GetAt(i) - '0';
		if ((temp >= 0 && temp <= 9) ||
			intrinsic.GetAt(i) == '.'||
			intrinsic.GetAt(i) == ' ' ||
			intrinsic.GetAt(i) == '-') {
			//do nothing
		}
		else {
			MessageBox("请正确输入内参数据 M[4] D[8],用空格分开");
			a = false;
			return a;
		}
	}
	return a;
}
void CMy03intrinsiccompareDlg::cstring2array(CString cstr, double k[12]) {

	const char* str_ = (LPCTSTR)cstr;
	char *str = const_cast<char*>(str_);
	char *ptr;
	char *pTmp = NULL;
	ptr = strtok_s(str, " ", &pTmp);
	int i = 0;
	while (ptr != NULL)
	{
		k[i] = atof(ptr);
		i++;
		ptr = strtok_s(NULL, " ", &pTmp);
	}
}
  • 加载工程子目录下的txt文档,并将其写入到编辑文本框
BOOL CMy03intrinsiccompareDlg::OnInitDialog(){
	CStdioFile file;
	if (file.Open("parameter/intrinsic_compare.txt", CFile::modeRead))
	{	
		if (file.ReadString(str_intrinsic_1))
			GetDlgItem(IDC_EDIT2)->SetWindowText(str_intrinsic_1);
		file.Close();
	}
return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}	
  • 在对话框关闭之前,将编辑文本框的内容写入工程子目录下的txt文档中
void CMy03intrinsiccompareDlg::OnBnClickedCancel()
{
	GetDlgItemText(IDC_EDIT2, str_intrinsic_1);////获取指定ID的编辑框内容
	CStdioFile FileWrite;
	if (FileWrite.Open(strFile, CStdioFile::modeCreate | CStdioFile::modeNoTruncate | CStdioFile::modeWrite))//创建/打开文件
	{
		FileWrite.SetLength(0);  //写入之前,将文档清空
		FileWrite.WriteString(str_intrinsic_1);
		FileWrite.WriteString(_T("\n"));
		FileWrite.Close();//关闭输出文件
CDialogEx::OnCancel();
  • 将opencv的图像显示在图像控件中
void CMy03intrinsiccompareDlg::DrawcvMat(cv::Mat m_cvImg, UINT ID)
{
	cv::Mat img;
	CRect rect;

	GetDlgItem(ID)->GetClientRect(&rect);
	if (rect.Width() % 4 != 0)
	{
		rect.SetRect(rect.left, rect.top, rect.left + (rect.Width() + 3) / 4 * 4, rect.bottom);  //调整图像宽度为4的倍数
		GetDlgItem(ID)->SetWindowPos(NULL, rect.left, rect.top, rect.Width(), rect.Height(), SWP_NOMOVE);
	}

	cv::Rect dst(rect.left, rect.top, rect.right, rect.bottom);
	cv::resize(m_cvImg, img, cv::Size(rect.Width(), rect.Height()));  //使图像适应控件大小 

	unsigned int m_buffer[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
	BITMAPINFO* m_bmi = (BITMAPINFO*)m_buffer;
	BITMAPINFOHEADER* m_bmih = &(m_bmi->bmiHeader);
	memset(m_bmih, 0, sizeof(*m_bmih));
	m_bmih->biSize = sizeof(BITMAPINFOHEADER);
	m_bmih->biWidth = img.cols;   //必须为4的倍数
	m_bmih->biHeight = -img.rows; //在自下而上的位图中 高度为负
	m_bmih->biPlanes = 1;
	m_bmih->biCompression = BI_RGB;
	m_bmih->biBitCount = 8 * img.channels();

	if (img.channels() == 1)  //当图像为灰度图像时需要设置调色板颜色
	{
		for (int i = 0; i < 256; i++)
		{
			m_bmi->bmiColors[i].rgbBlue = i;
			m_bmi->bmiColors[i].rgbGreen = i;
			m_bmi->bmiColors[i].rgbRed = i;
			m_bmi->bmiColors[i].rgbReserved = 0;
		}
	}

	CDC *pDC = GetDlgItem(ID)->GetDC();
	::StretchDIBits(pDC->GetSafeHdc(), 0, 0, rect.Width(), rect.Height(), 0, 0, rect.Width(), rect.Height(), img.data, (BITMAPINFO*)m_bmi, DIB_RGB_COLORS, SRCCOPY);
	ReleaseDC(pDC);
}
  • 保存控件图像为bmp格式到工程目录的子文件夹
void save_control_picture() {
	CWnd* bmpShow = GetDlgItem(IDC_image);
	CDC *pdc = bmpShow->GetDC();
	CImage  imag;
	CRect rect;

	GetClientRect(&rect);        //获取画布大小
	bmpShow->GetWindowRect(&rect);
	imag.Create(rect.Width(), rect.Height(), 32);
	::BitBlt(imag.GetDC(), 0, 0, rect.Width(), rect.Height(), pdc->m_hDC, 0, 0, SRCCOPY);

	CFileDialog fileDlg(FALSE, _T("bmp"), _T("result/error_image.bmp"));
	CString picturePath = fileDlg.GetPathName();//获取完整路径
	HRESULT hResult = imag.Save(picturePath); //保存图片
	ReleaseDC(pdc);
	imag.ReleaseDC();
}
  • 保存控件图像为bmp格式到自定义文件夹
/*手动选择保存路径*/
	TCHAR szFilter[] = _T("jpg file(*.jpg)|*.jpg|bmp file(*.bmp)|*.bmp|所有文件(*.*)|*.*||");  //文件格式过滤
	// 构造保存文件对话框    
	CFileDialog fileDlg(FALSE, _T("jpg"), _T("*.jpg"), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter, this);
	fileDlg.m_ofn.lpstrTitle = _T("保存直方图");  //保存对话窗口标题名
	CString picturePath;
	if (IDOK == fileDlg.DoModal())  //按下确认键
	{
		picturePath = fileDlg.GetPathName();  //文件路径
	}

	HRESULT hResult = imag.Save(picturePath); //保存图片
	ReleaseDC(pdc);
	imag.ReleaseDC();
}
  • 保存Mat类型的图像到工程目录下的子文件(result)中,并修改名称
void save_Mat_image(cv::Mat image){
char file[100];
char* s = "error_image";
sprintf_s(file, "result/%s_%d.bmp", s,enlarge);  //使用sprintf_s函数
imwrite(file, image);
}
  • opencv保存图像自动命名这篇博客写的很棒,有图有真相。但是将时间作为文件名,我没有搞定,不能成功运行。

  • 发布软件注意事项

    • 改用Release模式;
    • 工程属性中:配置属性-常规,MFC使用类型选择“在共享的DLL中使用MFC”;
    • 工程属性中:C/C++ - 代码生成-MFC的使用 选择“多线程DLL(/MD)”;
    • 将使用的*.dll文件拷贝到和 *.exe文件所在的同一个目录下(*d.dll文件名称最后一个字符是d,表示debug版本)

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值