下面以vs2013+opencv2.4.9的实验环境做出演示:
首先建立对话框工程对话框,界面如下:
设置定时器来更新picture显示框
在CMFCdisplayDlg.h中添加以下变量
private:
CRect rect;
CStatic* pStc; //标识图像显示的Picture控件
CDC* pDC; //视频显示控件设备上下文
HDC hDC; //视频显示控件设备句柄
CvCapture* capture; //视频获取结构
public:
afx_msg void OnTimer(UINT_PTR nIDEvent);
afx_msg void OnOpenCamera();
afx_msg void OnCloseCamera();
在CMFCdisplayDlg.cpp中添加添加ON_WM_TIMER()消息映射,
BEGIN_MESSAGE_MAP(CMFCNumberReDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_COMMAND(ID_32771, &CMFCdisplayDlg::OnOpenCamera)
ON_WM_TIMER()
ON_COMMAND(ID_32772, &CMFCdisplayDlg::OnCloseCamera)
END_MESSAGE_MAP()
在BOOL CMFCdisplayDlg::OnInitDialog()初始化对话框中添加
pStc=(CStatic *)GetDlgItem(IDC_PICUPANO);//IDC_VIEW为Picture控件ID
pStc->GetClientRect(&rect);//将CWind类客户区的坐标点传给矩形
pDC=pStc->GetDC(); //得到Picture控件设备上下文
hDC=pDC->GetSafeHdc(); //得到控件设备上下文的句柄
添加打开摄像头的消息处理函数
void CMFCdisplayDlg::OnOpenCamera()
{
// TODO: 在此添加命令处理程序代码
//AfxMessageBox("OK");
if (!capture)
{
capture = cvCaptureFromCAM(0);
//AfxMessageBox("OK");
}
if (!capture)
{
MessageBox(_T("无法打开摄像头"));
return;
}
// 设置计时器,每10ms触发一次事件
SetTimer(1, 10, NULL); //其中“1”为定时器的ID
}
添加定时器OnTimer消息处理函数:
void CMFCdisplayDlg::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
IplImage* m_Frame;
m_Frame=cvQueryFrame(capture); //从视频中取出一幅图像
......
在此处可添加图像处理相关代码
......
CvvImage m_CvvImage;
m_CvvImage.CopyOf(m_Frame,1);
m_CvvImage.DrawToHDC(hDC, &rect); //通过句柄hDC,显示
CUpanoCameraDlg::OnTimer(nIDEvent);
}
添加关闭摄像头的消息处理函数:
void CMFCdisplayDlg::OnCloseCamera()
{
// TODO: 在此添加命令处理程序代码
//在picture control控件上显示位图
CDC MemDC;
CBitmap m_Bitmap1;
m_Bitmap1.LoadBitmap(IDB_BITMAP1);
MemDC.CreateCompatibleDC(NULL);
MemDC.SelectObject(&m_Bitmap1);
pDC1->StretchBlt(rect1.left, rect1.top, rect1.Width(), rect1.Height(), &MemDC, 0, 0, 48, 48, SRCCOPY);
KillTimer(1);//关闭定时器,不写这句程序会崩溃
CDialogEx::OnClose();
附录:
(1)如何在对话框中添加菜单栏并显示
在资源管理器中添加资源:
在CMFCdisplayDlg.h中添加CMenu类型的变量
public:
CMenu m_Menu;
在 CMFCdisplayDlg::OnInitDialog()中添加初始化代码
m_Menu.LoadMenu(IDR_MENU1);
SetMenu(&m_Menu);
这样菜单栏才能在对话框中显示