在这个项目中用到了几个GDI的函数,包括CFont CPen CBrush等,一般要和设备上下文DC结合起来使用。
并且创建GDI对象使用完后一定要释放,否则可能会造成资源泄漏
对于CPen CFont CBrush用构造函数定义的GDI对象 和 用 CreateXXX获得的对象在释放时要调用DeleteObject
对于GetXXX获得的对象在释放时要使用ReleaseObject。
1 CDC *pDC0 = GetDlgItem(IDC_VIDEO0)-> GetDC(); 2 CFont font; // GDI对象 3 font.CreatePointFont( 200 , _T( " 宋体 " )); // CreateXXX 4 CFont *oldFont = pDC0->SelectObject(& font); 5 pDC0->TextOut( 20 , 20 , CString(_T( " 1 " ))); 6 pDC0-> SelectObject(oldFont); 7 8 GetDlgItem(IDC_VIDEO0)-> ReleaseDC(pDC0); 9 10 font.DeleteObject(); // 释放GDI对象资源
下面的例子是画一个矩形的边框,矩形是一个Picture控件,当点击该控件时给这个控件的边缘画颜色
1 CRect rect; 2 CDC* pDC = GetDlgItem(m_nCurrentPicture)-> GetDC(); 3 GetDlgItem(m_nCurrentPicture)->GetClientRect(& rect); 4 5 CPen pen(PS_SOLID, 10 , RGB( 0x99 , 0x32 , 0xcc )); 6 CPen *oldPen = NULL; 7 oldPen = pDC->SelectObject(& pen); 8 9 // 上边框; 10 pDC-> MoveTo(rect.TopLeft()); 11 pDC->LineTo(CPoint(rect.TopLeft().x + rect.Width(), // x 12 rect.TopLeft().y // y 13 ) ); 14 15 // 右边框; 16 pDC->MoveTo(CPoint(rect.TopLeft().x + rect.Width(), // x 17 rect.TopLeft().y // y 18 )); 19 pDC-> LineTo(rect.BottomRight()); 20 21 // 下边框; 22 pDC-> MoveTo(rect.BottomRight()); 23 pDC->LineTo(rect.TopLeft().x, // x 24 rect.BottomRight().y // y 25 ); 26 27 // 左边框; 28 pDC->MoveTo(rect.TopLeft().x, // x 29 rect.BottomRight().y // y 30 ); 31 pDC-> LineTo(rect.TopLeft()); 32 33 34 pDC-> SelectObject(oldPen); 35 36 int ret = GetDlgItem(m_nCurrentPicture)-> ReleaseDC(pDC); 37 pDC = NULL; 38 39 pen.DeleteObject();
多个Picture控件,每个Picture控件都在控件中间位置写上1 2 3 4等数字标识是哪个摄像头
1 void CCameraMonitorView::OnDraw(CDC* /* pDC */ ) 2 { 3 // TODO: 在此添加专用代码和/或调用基类; 4 5 if ( 0 != m_nCurrentPicture) 6 { 7 ChoosePicture(m_nCurrentPicture); 8 } 9 10 int index = 0 ; 11 for (index = 0 ; index < MAX_CAMERAS_NUM; ++ index) 12 { 13 if (videoPicturesCtrl[index] != 0 ) 14 { 15 CDC *pDC = GetDlgItem(videoPicturesCtrl[index])-> GetDC(); 16 CFont font; 17 font.CreatePointFont( 800 , _T( " 宋体 " )); 18 CFont *oldFont = pDC->SelectObject(& font); 19 pDC-> SetBkMode(TRANSPARENT); 20 CRect rect; 21 GetDlgItem(videoPicturesCtrl[index])->GetClientRect(& rect); 22 23 int x = (rect.Width() / 2 ) - 20 ; 24 int y = (rect.Height() / 2 ) - 40 ; 25 char numArr[ 5 ] = { 0 }; 26 _itoa_s(index + 1 , numArr, RADIX_10); 27 CString strDisplayNum(numArr); 28 29 pDC-> TextOut(x, y, strDisplayNum); 30 pDC-> SelectObject(oldFont); 31 32 GetDlgItem(IDC_VIDEO1)-> ReleaseDC(pDC); 33 34 font.DeleteObject(); 35 36 } 37 } 38 39 }
从窗口指针获得DC
CDC *pDC = pWnd->GetDC();
根据DC获得HDC
HDC hDC = pDC->GetSafeHdc();
根据句柄获得窗口指针
CWnd *pWnd = FromHandle(hWnd);
void CJietu::OnPaint() { CPaintDC dc( this ); // device context for painting // TODO: 在此处添加消息处理程序代码 // 不为绘图消息调用 CDialog::OnPaint() HWND hWnd = m_hWnd; CWnd *pWnd = FromHandle(hWnd); CDC *pDC = pWnd-> GetDC(); HDC hDC = pDC-> GetSafeHdc(); StretchBlt(hDC, 0 , 0 , m_nCx, m_nCy, m_hDCGlobal, 0 , 0 , m_nCx, m_nCy, SRCCOPY); pWnd -> ReleaseDC(pDC); }
另外一个例子
1 bool DrawPicToHDC(IplImage *img, HWND hWnd, bool bIsShowInfo) 2 { 3 CWnd *pWnd = CWnd::FromHandle(hWnd); 4 if (NULL == pWnd || FALSE == ::IsWindow(pWnd-> m_hWnd)) 5 { 6 AfxMessageBox(_T( " DrawPicToHDC error 2 " )); 7 return false ; 8 } 9 10 CDC *pDC = pWnd-> GetDC(); 11 HDC hDC = pDC-> GetSafeHdc(); 12 CRect rect; 13 pWnd->GetClientRect(& rect); 14 CvvImage cimg; 15 cimg.CopyOf(img); 16 cimg.DrawToHDC(hDC, & rect); 17 18 pDC->SetBkMode(TRANSPARENT); // 文字透明; 19 CTime time = CTime::GetCurrentTime(); // 获得当前时间; 20 CString strTime; 21 strTime = time.Format( " %Y-%m-%d %H:%M:%S " ); 22 23 CFont font; 24 font.CreatePointFont( 200 , _T( " 宋体 " ), NULL); 25 CFont *oldFont = pDC->SelectObject(& font); 26 pDC->SetTextColor(RGB( 255 , 0 , 0 )); // 文字颜色 27 28 pDC->TextOut( 10 , 10 , strTime); 29 30 if ( true == bIsShowInfo) 31 { 32 pDC->TextOut( 10 , 35 , CString( " 正在录像... " )); 33 } 34 35 pDC-> SelectObject(oldFont); 36 37 ReleaseDC(hWnd,hDC); // 释放DC 38 font.DeleteObject(); // 释放GDI对象 39 40 return true ; 41 }