写在前面
MFC是一种用c++设计交互界面的的开发工具,在二三十年前比较流行,但目前比较少用了。所以现在使用MFC进行开发,相关资料的查找也比较困难。最近做了一个与MFC有关的项目,其中用到的相关知识总结与此。在使用工具时,最大的资料其实就是那个库本身,查看库内的代码总会有意想不到的收获。本人用的是VS2017专业版里面的MFC。文末附代码。
项目测试
与开篇一样,在新建项目之后,也就是在总结一的基础上,将工具箱中的Picture Control拖入交互界面中,将画面拉大一些.注意控件的ID,将其修改为IDC_Pic.
opencv配置
由于视频的处理需要使用opencv,因此opencv的配置也是不可少的,项目属性里面VC++目录中的包含目录和库目录,链接器附加依赖项都需要设置,但一定要注意模式是Debug还是Release,环境是x64还是x86,opencv的库则需要小伙伴们按照自己需要去下载了.
添加代码
在testDlg.h中插入头文件
#include <opencv2/opencv.hpp>
#include<opencv2\core\core.hpp>
#include<opencv2\highgui\highgui.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
在BOOL CtestDlg::OnInitDialog()中的”// TODO: 在此添加额外的初始化代码”之后添加如下代码
namedWindow("view", WINDOW_AUTOSIZE);
HWND hWnd = (HWND)cvGetWindowHandle("view");
HWND hParent = ::GetParent(hWnd);
::SetParent(hWnd, GetDlgItem(IDC_Pic)->m_hWnd);
::ShowWindow(hParent, SW_HIDE);
就是用opencv里面的语言先创建一个叫做”view”的窗口,之后将这个窗口绑定到交互界面上的那个Picture Control控件上,之后opencv将图片显示到这个view窗口上就可以了.
完整执行整个代码需要另起一个线程
在testDlg.h中添加一个变量
protected:
HICON m_hIcon;
UINT m_threadID;//添加的变量
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
在testDlf.cpp中BOOL CtestDlg::OnInitDialog()函数另起一个线程如下,就是将图片显示到view窗口.
UINT WINAPI cvDisplayThreadtest(LPVOID lpParam)
{
CtestDlg* pThis = (CtestDlg*)lpParam;
CRect rect;
VideoCapture cap;
cap.open(0);
Mat frame_roi;
while (cap.isOpened())
{
cap >> frame_roi;
pThis->GetDlgItem(IDC_Pic)->GetClientRect(&rect);
cv::Rect dst(rect.left, rect.top, rect.right, rect.bottom);
cv::resize(frame_roi, frame_roi, cv::Size(rect.Width(), rect.Height()));
imshow("view", frame_roi);
}
return 0;
}
在BOOL CtestDlg::OnInitDialog()添加启动线程的语句
(HANDLE)_beginthreadex(NULL, 0, &cvDisplayThreadtest, this, 0, &m_threadID);
程序运行
在使用VS2017时和一些其他版本时可能会出现安全性错误,如下所示
个人的解决方法比较暴力,直接在对应报错的文件中加入,不让它报错.
#pragma warning(disable : 4996)
最后便能实时显示相机内容
至此,视频显示在界面上完成.
代码链接
.