- 分割单文档
首先为单文档客户群开辟一个空间,可以在空间上添加控件。
1.自定义一个类这里起名时CDview,基类时CFormView,添加成功后资源视图中会出现IDD_DVIEW在这里面添加控件就可以了。
2.在CMainFrame头文件中声明CSplitterWnd m_wndSplitter;并且在CMainFrame源文件中添加两个头文件。
因为SingleDocView.h中先读SingleDocDoc.h若没有先添加SingleDocDoc.h则会报错。
在CMainFrame中添加OnCreateClient消息响应。如下代码是完成视图分割的主要代码。
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
// TODO: 在此添加专用代码和/或调用基类
if(m_wndSplitter.CreateStatic(this,1,2)==NULL)
{
return FALSE;
}
CRect rect;
GetClientRect(&rect);
m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CDview), CSize(int(rect.Height()/4), int(rect.Width()/ 4)), pContext);
m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CSingleDocView), CSize(int(3*rect.Height()/ 4), 3*int(rect.Width())/ 4), pContext);
m_Dview = (CDview *)m_wndSplitter.GetPane(0, 0);
m_SingleDocView = (CSingleDocView *)m_wndSplitter.GetPane(0, 1);
return TRUE;
return CFrameWnd::OnCreateClient(lpcs, pContext);
}
图下效果图,控件是我自己添加的左边是自己定义的类CDview右边是MFC自带的视觉类。
2.打开图片
1.双击打开图片控件,在弹出函数中添加下面代码。
CString filter;
CString strFilename = _T("");
filter = _T("All(*.*)|*.*||");
CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, filter, NULL);
if (dlg.DoModal() == IDOK)
{
strFilename = dlg.GetPathName();
if (strFilename.GetLength() > 0)
{
String name(CW2A(strFilename.GetString()));
g_src = imread(name, 1);
MatToImage(g_src, g_img);
//pMain->m_SingleDocView->Invalidate();
}
2.因为想让图片在视图区显示,也就是客户区右边区域,所以要在MFC自带的视类的Ondraw中写代码。
CMainFrame *pMain = (CMainFrame*)theApp.m_pMainWnd; //m_pMainWnd 返回CWnd*
CDview *pview = (CDview*)pMain->GetActiveView();
if (pview->g_src.data!=NULL)
{
pview->g_img.Draw(pDC->GetSafeHdc(), 100, 100);
}
3.打开视频
视频就是图片连续播放所以,要让摄像头一直抓取图片一直播放,这样就需要用到线程的知识,不过今天的我不会。。。明天在研究,所以这地方用了以前用过的计时器。
1在CDview类中添加On_Time响应。
2双击打开视频控件创建函数在函数中填写 ,其中cap是在头文件声明的全局变量 VideoCapture
void CDview::OnBnClickedOpenvid()
{
// TODO: 在此添加控件通知处理程序代码
cap = 0;
SetTimer(1,1000,NULL);
}
3.在OnTimer中写如下代码,因为我之前在对话框中用过计时器是好用的,但是在这里发现invalidate确实是重绘了客户区,但是没有出发OnDraw,对话框中是用的OnPain是可以触发的。这个地方我也没弄明白咋回事。
另外在CDview中获取CSingleDocView的DC是获取不到的。
void CDview::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
cap >> g_src;
MatToImage(g_src, g_img);
CMainFrame*p_Main = (CMainFrame*)theApp.m_pMainWnd;
CSingleDocView* p_view = (CSingleDocView*)p_Main->GetActiveView();
CDC *pDC = p_view->GetDC();
g_img.Draw(pDC->GetSafeHdc(), 100, 100);
p_view->Invalidate(FALSE);
CFormView::OnTimer(nIDEvent);
}
很尴尬的是就算上述代码通过编译也不能获取到了CSingleDocView的DC。结果就是获取的是自定义类的DC。在自定义的CDview中是可以实现视频的采集(右边),而在MFC自带的视类只能采集第一帧图片,只有改变窗口大小才会再次调用Ondraw,左边图片才会再次改变。
今天没做出来。明天在研究研究线程把这个功能实现。