界面——C++_MFC从入门到放弃(一)

目录

MFC——窗口静态显示

MFC——定时器:窗口动态显示

MFC——【X】退出菜单缓存清除

MFC——警告弹窗MessageBox

MFC——相机单帧采集

MFC——问题:non-unicode character set is deprdeprecated

MFC——多线程:

MFC——纯ALT读取图(静态和动态)

MFC——字符、字符串、数值等之间的转换

MFC——改变控件大小


MFC——窗口静态显示

利用Opencv库进行窗口显示

需要材料:CvvImage.h和CvvImage.cpp

步骤:第一步:头文件、第二步:声明、第三步:使用

/*
功能;画入指定IDC
第一步:头文件:在当前的类的的头文件代码区头包含:#include "CvvImage.h"
第二步:将函数在当前所在的类的头文件声明:void CMFC_CalibrationDlg::drawToDC(IplImage* image, UINT ID)
第三步:使用 
IplImage img = src;	
drawToDC(&img, 自己指定IDC窗口);	//显示	
*/
void C自己MFC的Dlg::drawToDC(IplImage* image, UINT ID)//画到指定ID(默认IDC_STATIC)在头文件声明函数
{
	CDC* pDC = GetDlgItem(ID)->GetDC();
	HDC pHdc = pDC->GetSafeHdc();

	CRect rect;
	GetDlgItem(ID)->GetClientRect(&rect);

	CvvImage cimg;
	cimg.CopyOf(image);
	cimg.DrawToHDC(pHdc, rect);

	ReleaseDC(pDC);
}


MFC——定时器:窗口动态显示

/*
// 窗口定时事件
窗口类向导——》消息——》WMTimer——》OnTimer双击——》编辑代码
使用:
SetTimer(1, 10, NULL);//开启定时器1
KillTimer(1);    //关闭定时器防止缓存滞留
*/
void CdahengDlg::OnTimer(UINT_PTR nIDEvent)
{
	// TODO:  在此添加消息处理程序代码和/或调用默认值
	switch (nIDEvent)
	{
	case 1://Timer(1)
	{			//objImageDataPtr获取相机缓存
			   my_camera.objImageDataPtr = my_camera.ObjStreamPtr->GetImage(100);//超时时间使用500ms,用户可以自行设定
			   if (my_camera.objImageDataPtr->GetStatus() == GX_FRAME_STATUS_SUCCESS)
			   {
				   my_camera.ImageFlag = true;		//图片采集成功

				   //假设原始数据是BayerRG8图像,则 GX_BIT_0_7
				   void* pRGB24Buffer = NULL;
				   pRGB24Buffer = my_camera.objImageDataPtr->ConvertToRGB24(GX_BIT_0_7, GX_RAW2RGB_NEIGHBOUR, true);

				   Mat test;
				   test.create(my_camera.objImageDataPtr->GetHeight(), my_camera.objImageDataPtr->GetWidth(), CV_8UC3);
				   memcpy(test.data, pRGB24Buffer, my_camera.objImageDataPtr->GetPayloadSize() * 3);
				   if (test.data){
					   IplImage image;
					   image = test;
					   drawToDC(&image, IDC_STATIC_SHOW);
				   }
			   }
			  else
			  {
				  KillTimer(1);    //关闭定时器防止缓存滞留
				  if (MessageBox(_T("请连接相机"), _T("相机事件"), MB_YESNO | MB_ICONWARNING) == IDNO)
				  {
					  //关闭定时刷新					 
					  break;
				  }
			  }
			  break;
	}
	case 2://Timer(2)
	{
			  // 用户程序
			  break;
	}

	}

	CDialogEx::OnTimer(nIDEvent);
}

MFC——【X】退出菜单缓存清除

/*
//窗口关闭【X】的事件
窗口类向导——》消息——》WMClose双击——》OnClose程序块——》添加代码
使用:
直接在此程序块进行操作
*/
void CdahengDlg::OnClose()
{
	// TODO:  在此添加消息处理程序代码和/或调用默认值
	// 关闭相机
	if (my_camera.DeviceFlag == true)
	{
		my_camera.DeviceFlag = false;
		my_camera.ImageFlag = false;
		my_camera.OpenFlag = true;//初始化重启
		KillTimer(1);    //关闭定时器防止缓存滞留
		//发送停采命令
		my_camera.ObjFeatureControlPtr->GetCommandFeature("AcquisitionStop")->Execute();
		my_camera.ObjStreamPtr->StopGrab();

		//释放资源
		my_camera.ObjStreamPtr->Close();
		my_camera.ObjDevicePtr->Close();
		//反初始化库
		MessageBox(_T("相机【确定】关闭"), _T("相机事件..."));
		IGXFactory::GetInstance().Uninit();
	}	
	
	CDialogEx::OnClose();
}

MFC——警告弹窗MessageBox

// 更多功能查找其他说明书
MessageBox(_T("相机【确定】关闭"), _T("相机事件..."));

MFC——相机单帧采集

/*利用按钮进行标志位,然后定时器里面进行赋值命令*/

// 图像处理
void CdahengDlg::OnBnClickedButtonPro()
{
	// TODO:  在此添加控件通知处理程序代码
	if (my_camera.OpenFlag == true)
	{
		MessageBox(_T("请打开相机"));
		return;
	}
	if (my_camera.ImageFlag == true)
	{
		my_camera.ImageClo = true;//相片结束标志
	}	
}


// 采集命令
if (my_camera.ImageClo == true)//相片处理按钮标志
{
	test.copyTo(my_camera.src);
	if (my_camera.src.data)
	{
		IplImage image;
		image = my_camera.src;
		drawToDC(&image, IDC_STATIC_SHOWPRO);
		my_camera.ImageClo = false;//相片结束标志
	}
}

项目链接

MFC——问题:non-unicode character set is deprdeprecated

错误    1    error MSB8031: Building an MFC project for a non-Unicode character set is deprecated. You must change the project property to Unicode or download an additional library. See http://go.microsoft.com/fwlink/p/?LinkId=286820 for more information.    C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppBuild.targets    369    5    Signal

下载xian相应的支持包:http://go.microsoft.com/fwlink/p/?LinkId=286820

MFC——多线程:

//创建实例:
CWinThread*  XXXXX;

//线程函数:
UINT ChildThread1(LPVOID Param);/*重点:CMFC_CZDlg* pDlg = (CMFC_CZDlg*)Param;	//参数传入*/

//开启:
XXXXX = AfxBeginThread(ChildThread1, (LPVOID)this, THREAD_PRIORITY_NORMAL);//开启子线程1

//暂停(挂起):
XXXXX ->SuspendThread(); //暂停

//继续:
XXXXX ->ResumeThread(); //继续

//执行完毕再终止:
DWORD dwRetVal = WaitForSingleObject(mythread->m_hThread, INFINITE);

//终止:
TerminateThread(XXXXX->m_hThread, 0);    //停止线程、
XXXXX = NULL;//清除缓存
// 线程ChildThread1
UINT ChildThread1(LPVOID Param)
{
	
	//子线程1
	CMFC_CZDlg* pDlg = (CMFC_CZDlg*)Param;	//参数传入
	CButton* pButton;
	pButton = (CButton*)(pDlg->GetDlgItem(IDC_CHECK_COLOR));
	int flage_color = pButton->GetCheck();
	pButton = (CButton*)(pDlg->GetDlgItem(IDC_CHECK_SHAPE));
	int flage_shape = pButton->GetCheck();
	pButton = (CButton*)(pDlg->GetDlgItem(IDC_CHECK_GRAIN));
	int flage_grain = pButton->GetCheck();

	/*图片个数检索、图资源PIC_x + IO_x的参数*/
	vector<CImage> VecPIC_x = { pDlg->PIC_1, pDlg->PIC_2, pDlg->PIC_3, pDlg->PIC_4, pDlg->PIC_5, pDlg->PIC_6, pDlg->PIC_7, pDlg->PIC_8 }; //图
	vector<int> VecIO_x = { pDlg->IO_1, pDlg->IO_2, pDlg->IO_3, pDlg->IO_4, pDlg->IO_5, pDlg->IO_6, pDlg->IO_7, pDlg->IO_8 }; //IO出口
	int label = 0;	//分类标签
	int num = 0;
	for (size_t i = 0; i < 8; i++)
	{
		if (!VecPIC_x[i].IsNull() && VecIO_x[i] != 0)
		{
			num++;
			label = num;
		}
		else
		{
			break;
		}		
	}
	CString NUM;
	NUM.Format(_T("%d"), label);
	pDlg->MessageBox(NUM, _T("图片_IO的个数,即为多少类别"));
	/*
	图片有了,
	检索方式选择
	【
	输入图VecPIC_x[i]	——CImage、
	输入标签号label(i个)——int、
	输入出口VecIO_x[i]	——int
	返回分类模型
	】
	*/
	if (label > 0)
	{		
		// 线程开启
		pDlg->flag_thresh == true;

		// 按钮不能再碰
		pDlg->DISABLE_IO(IDC_BUTTON_11, IDC_BUTTON_18);
		pDlg->DISABLE_IO(IDC_BUTTON_21, IDC_BUTTON_28);
		pDlg->DISABLE_IO(IDC_BUTTON_31, IDC_BUTTON_38);
		pDlg->DISABLE_IO(IDC_BUTTON_41, IDC_BUTTON_48);
		pDlg->DISABLE_IO(IDC_BUTTON_51, IDC_BUTTON_58);
		pDlg->DISABLE_IO(IDC_BUTTON_61, IDC_BUTTON_68);
		pDlg->DISABLE_IO(IDC_BUTTON_71, IDC_BUTTON_78);
		pDlg->DISABLE_IO(IDC_BUTTON_81, IDC_BUTTON_88);
		pDlg->GetDlgItem(IDC_BUTTON_1_Open_CAMERA)->EnableWindow(FALSE);
		pDlg->GetDlgItem(IDC_BUTTON_2_COLOCT)->EnableWindow(FALSE);
		pDlg->GetDlgItem(IDC_BUTTON_3_IO_SETTING)->EnableWindow(FALSE);
		pDlg->GetDlgItem(IDC_CHECK_COLOR)->EnableWindow(FALSE);
		pDlg->GetDlgItem(IDC_CHECK_SHAPE)->EnableWindow(FALSE);
		pDlg->GetDlgItem(IDC_CHECK_GRAIN)->EnableWindow(FALSE);
		pDlg->GetDlgItem(IDC_BUTTON_7_RESET_ALL)->EnableWindow(FALSE);
		pDlg->GetDlgItem(IDC_BUTTON_5_START)->EnableWindow(FALSE);
		for (size_t i = IDC_BUTTON_RESET_1; i <= IDC_BUTTON_RESET_8; i++)
		{
			pDlg->GetDlgItem(i)->EnableWindow(FALSE);
		}

		for (size_t i = 0; i < 5; i++)
		{
			Sleep(2000);
			pDlg->MessageBox(_T("循环中"));
		}
		
	


		if (flage_color && flage_shape && flage_grain || !flage_color && !flage_shape && !flage_grain)
		{
			pDlg->MessageBox(_T("111"), _T("检索方式"));
			/*
			图像识别子程序
			如果已经有图片库,从图片库读取图 + 标签 + IO,如果没有就采集图片
			是否重新训练模型的判断
			*/
			/*——————————*/
		}
		else if (flage_color && flage_shape && !flage_grain)
		{
			pDlg->MessageBox(_T("110"), _T("检索方式"));
		}
		else if (flage_color && !flage_shape && flage_grain)
		{
			pDlg->MessageBox(_T("101"), _T("检索方式"));
		}
		else if (flage_color && !flage_shape && !flage_grain)
		{
			pDlg->MessageBox(_T("100"), _T("检索方式"));
		}
		else if (!flage_color && flage_shape && flage_grain)
		{
			pDlg->MessageBox(_T("011"), _T("检索方式"));
		}
		else if (!flage_color && flage_shape && !flage_grain)
		{
			pDlg->MessageBox(_T("010"), _T("检索方式"));
		}
		else if (!flage_color && !flage_shape && flage_grain)
		{
			pDlg->MessageBox(_T("001"), _T("检索方式"));
		}
	}
	else
	{
		pDlg->MessageBox(_T("【没有图片资源】、【检查是否设置IO出口】"));
		return 0;
	}	
	return 1;

}

MFC——为按钮添加图片(资源位图、开关指示灯颜色等)

方法:

  • 直接调用SetBitmap;  CButton pButton->SetBitmap(hBitmap);
  • 使用CButtonST控件;
  • 使用CDC;
  • 使用CBitmapButton;

CBitmapButton作为MFC的控件类,具体使用如下:

 

  1. 首先添加按钮控件,将属性Owner Draw设为True,按钮ID: IDC_BUTTON1
  2. 添加位图资源ID: IDB_BITMAP_CLOSE  和  IDB_BITMAP_RED(资源添加bitmap自己定义名字和ID)
  3. 在对话框类中添加private成员变量: CBitmapButton m_button;    bool LedFlag;
  4. 在初始化函数OnInitDialog里添加图片加载:
  5. 第一步:使用CBitmapButton::LoadBitmaps装载各种状态的图片
  6. 第二步:再用SubclassDlgItem关联到想要的按钮,
  7. 第三步:使用CBitmapButton::SizeToContent函数使按钮适合图片大小。注意Loadbitmaps一定要在关联到按钮之前进行!
  8. 为按钮控件添加单击事件处理函数,输入如下代码: 
  9. 按理来说,写上m_ctrlButton.LoadBitmaps(图片ID);就可以了,可是这样做之后,发现按键了没反应。无意中将对话框最小化再还原,发现图片变了。所以实际上是没有进行刷新导致的。在后面加上m_button.Invalidate()就可以了。
  10. 运行程序

MFC——纯ALT读取图(静态和动态)

//静态————————————————————方法一(综合):
/*CImage读取静态图*/
//【第一步:CImage加载图片】
CImage Image;
Image.Load(_T("test.jpg"));
if (Image.IsNull())
{
	MessageBox(_T("没加载成功"));
}
//【第二步:CRect获取控件范围】
CRect rect;//定义矩形类  
GetDlgItem(IDC_STATIC_CAMERA_SHOW)->GetClientRect(&rect);//将窗口矩形选中到picture控件上 

//【第三步:CDC】
/*
利用StretchBlt缩小图片时有时会出现颜色失真。解决步骤如下:
      	1、先把目标DC (也就是 HDC(或CDC) hDestDC) ::SetStretchBltMode (hDestDC, HALFTONE); //调整图片缩放平均颜色
      	2、调用一下 ::SetBrushOrgEx(hDestDC, 0, 0, NULL); //设置刷子起始点(可用可不用)
      	3、最后调用 CImage 的 StretchBlt	//Image.Draw(pDC->m_hDC, rect);
*/
CDC *pDC = GetDC();//获取对话框控件
pDC = GetDlgItem(IDC_STATIC_CAMERA_SHOW)->GetDC();  // 获取picture控件DC
SetStretchBltMode(pDC->m_hDC, HALFTONE);//调整图片缩放平均颜色
//SetBrushOrgEx(pDC->m_hDC, 0, 0, NULL);//设置刷子起始点(可用可不用)
Image.Draw(pDC->m_hDC, rect);


//静态——————————————————————————方法二
//从资源中加载图片(不调整大小)
CBitmap bitmap;
//加载指定位图资源 Bmp图片ID
bitmap.LoadBitmap(IDB_BITMAP2);
//获取对话框上的句柄 图片控件ID
CStatic *p = (CStatic *)GetDlgItem(IDC_STATIC_CAMERA_SHOW);
//设置静态控件窗口风格为位图居中显示
p->ModifyStyle(0xf, SS_BITMAP | SS_CENTERIMAGE);
//将图片设置到Picture控件上
p->SetBitmap(bitmap);


//动态————————————————————-————
(只读取bmp图(为了增加对bmp格式的理解),else读取bmp\jpg等)加载动态图步骤:
1.先定义打开文件对话框, 通过它获取bmp图片, 其中dlg.DoMal() == IDOK表示按下确认按钮, 实现后面操作.如果你学过C#就会发现它的OpenFileDialog控件与这个有些类似.
2.然后, 获取读取文件的路径和后缀, 确保其为bmp时执行读取图片信息,
在"https://wenku.baidu.com/view/c955d0fdfab069dc50220147.html"中, 我曾详细讲述过如何读取bmp图片,
这里也是二进制读取文件, 读取其文件头(BITMAPFILEHEADER)、信息头(BITMAPINFOHEADER)、获取其位图数据.
3.最后显示图像到Picture控件中, 并通过GetClientRect函数获取矩形区域, 显示图像.
代码:
//打开文件 定义四种格式的文件bmp gif jpg tiff
CString filter;
filter = "所有文件(*.bmp,*.jpg,*.gif,*tiff)|*.bmp;*.jpg;*.gif;*.tiff| BMP(*.bmp)|*.bmp| JPG(*.jpg)|*.jpg| GIF(*.gif)|*.gif| TIFF(*.tiff)|*.tiff||";
CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY, filter, NULL);

//按下确定按钮 dlg.DoModal() 函数显示对话框
if (dlg.DoModal() == IDOK)
{
	//打开对话框获取图像信息
	CString BmpName = dlg.GetPathName();     //获取文件路径名   如D:\pic\abc.bmp
	CString EntName = dlg.GetFileExt();      //获取文件扩展名
	EntName.MakeLower();                     //将文件扩展名转换为一个小写字符

	if (EntName.Compare(_T("bmp")) == 0)
	{
		//定义变量存储图片信息
		BITMAPINFO *pBmpInfo;       //记录图像细节
		BYTE *pBmpData;             //图像数据
		BITMAPFILEHEADER bmpHeader; //文件头
		BITMAPINFOHEADER bmpInfo;   //信息头
		CFile bmpFile;              //记录打开文件

		//以只读的方式打开文件 读取bmp图片各部分 bmp文件头 信息 数据
		if (!bmpFile.Open(BmpName, CFile::modeRead | CFile::typeBinary))
			return;
		if (bmpFile.Read(&bmpHeader, sizeof(BITMAPFILEHEADER)) != sizeof(BITMAPFILEHEADER))
			return;
		if (bmpFile.Read(&bmpInfo, sizeof(BITMAPINFOHEADER)) != sizeof(BITMAPINFOHEADER))
			return;
		pBmpInfo = (BITMAPINFO *)new char[sizeof(BITMAPINFOHEADER)];
		//为图像数据申请空间
		memcpy(pBmpInfo, &bmpInfo, sizeof(BITMAPINFOHEADER));
		DWORD dataBytes = bmpHeader.bfSize - bmpHeader.bfOffBits;
		pBmpData = (BYTE*)new char[dataBytes];
		bmpFile.Read(pBmpData, dataBytes);
		bmpFile.Close();

		//显示图像
		CWnd *pWnd = GetDlgItem(IDC_STATIC_CAMERA_SHOW); //获得pictrue控件窗口的句柄
		CRect rect;
		pWnd->GetClientRect(&rect); //获得pictrue控件所在的矩形区域
		CDC *pDC = pWnd->GetDC(); //获得pictrue控件的DC
		pDC->SetStretchBltMode(COLORONCOLOR);
		StretchDIBits(pDC->GetSafeHdc(), 0, 0, rect.Width(), rect.Height(), 0, 0,
			bmpInfo.biWidth, bmpInfo.biHeight, pBmpData, pBmpInfo, DIB_RGB_COLORS, SRCCOPY);
	}
	else
	{
		//MessageBox(BmpName);
		//【第一步:CImage加载图片】
		CImage Image;
		Image.Load((BmpName));
		if (Image.IsNull())
		{
			MessageBox(_T("没加载成功"));
		}
		//【第二步:CRect获取控件范围】
		CRect rect;//定义矩形类  
		GetDlgItem(IDC_STATIC_CAMERA_SHOW)->GetClientRect(&rect);//将窗口矩形选中到picture控件上 

		//【第三步:CDC】
		/*
		利用StretchBlt缩小图片时有时会出现颜色失真。解决步骤如下:
		      	1、先把目标DC (也就是 HDC(或CDC) hDestDC) ::SetStretchBltMode (hDestDC, HALFTONE); //调整图片缩放平均颜色
				      	2、调用一下 ::SetBrushOrgEx(hDestDC, 0, 0, NULL); //设置刷子起始点(可用可不用)
						      	3、最后调用 CImage 的 StretchBlt	//Image.Draw(pDC->m_hDC, rect);
								*/
		CDC *pDC = GetDC();//获取对话框控件
		pDC = GetDlgItem(IDC_STATIC_CAMERA_SHOW)->GetDC();  // 获取picture控件DC
		SetStretchBltMode(pDC->m_hDC, HALFTONE);//调整图片缩放平均颜色
		//SetBrushOrgEx(pDC->m_hDC, 0, 0, NULL);//设置刷子起始点(可用可不用)
		Image.Draw(pDC->m_hDC, rect);
	}
}

MFC——字符、字符串、数值等之间的转换

int转CString:
CString str; 
int a = 1;
str.Format(_T("%d"), a);

MFC——改变控件大小

/*
对话框的控件尺寸调整
第一步:WM_size消息生成OnSize函数-在函数中添加Invalidate(TRUE);刷新防止原有边缘的残留
第二步:构建全局变量CRect m_rect;
第三步:构建并再当前类的头文件声明子函数void CMFC_MutipleDlg::ChangeSize(int x, int y, UINT nID)
第四步:OnSize函数调用子函数ChangeSize
*/
//尺寸调整m_rect
CRect m_rect;
void CMFC_MutipleDlg::OnSize(UINT nType, int cx, int cy)
{
	CDialogEx::OnSize(nType, cx, cy);

	// TODO:  在此处添加消息处理程序代码
	if (nType == 1) return;   //如果是窗体最小化则什么都不做
	//对每个控件进行调整(dj)
	//对每一个控件依次做调整//IDC_OpenCamera
	ChangeSize(cx, cy, IDC_STATIC);
	ChangeSize(cx, cy, IDC_STATIC1);
	ChangeSize(cx, cy, IDC_STATIC2);
	ChangeSize(cx, cy, IDC_OpenCamera);
	GetClientRect(&m_rect);//将变化后的对话框大小设为旧大小
	Invalidate(TRUE);//必须有,放置窗口有残留痕迹
}

//改变控件的子函数(改变大小和位置)
void CMFC_MutipleDlg::ChangeSize(int x, int y, UINT nID) //nID为控件ID,x,y分别为对话框的当前长和宽
{
	CWnd *pWnd;
	pWnd = GetDlgItem(nID);
	if (pWnd != NULL) //判断是否为空,因为在窗口创建的时候也会调用OnSize函数,但是此时各个控件还没有创建,Pwnd为空
	{
		CRect rec;
		pWnd->GetWindowRect(&rec); //获取控件变化前的大小
		ScreenToClient(&rec); //将控件大小装换位在对话框中的区域坐标
		rec.left = rec.left*x / m_rect.Width(); //按照比例调整空间的新位置
		rec.top = rec.top*y / m_rect.Height();
		rec.bottom = rec.bottom*y / m_rect.Height();
		rec.right = rec.right*x / m_rect.Width();
		pWnd->MoveWindow(rec); //伸缩控件
	}
}

 

  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

智能之心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值