VC6.0下实现屏幕抓图功能

来源:互联网 发布:gear s3 知乎 编辑:程序博客网 时间:2024/04/19 07:14

最近有个项目需要用到屏幕抓图功能, 找了一些资料完成了主要的功能.

原理: 抓图的时候把整个屏幕的图片显示在一个全屏窗口中, 然后对该窗口进行操作.

主要代码部分:

全局变量
 CDC memDC;
 CBitmap bm;
 BOOL m_bSelectRgn;
 BOOL m_bSelectOk;
 CRect   m_rectSelect;

// 图片保存至剪贴板
void CScreenWnd::SaveBmp(CBitmap &bmp, CDC &pDc2)
{
 if(!m_bSelectOk)
  return;

 if(m_rectSelect.IsRectEmpty() || m_rectSelect.IsRectNull())
  return;

 CDC dcSave;
 dcSave.CreateCompatibleDC(NULL);
 CBitmap bitmap;
 BITMAP bm;
 bmp.GetObject(sizeof(bm), &bm);
 bm.bmWidth = m_rectSelect.Width();
 bm.bmHeight = m_rectSelect.Height();
 bitmap.CreateBitmapIndirect(&bm);
 CBitmap* pOldBmp = dcSave.SelectObject(&bitmap);
 
 dcSave.StretchBlt(0,0, m_rectSelect.Width(), m_rectSelect.Height(),
  &pDc2, m_rectSelect.left, m_rectSelect.top,
  m_rectSelect.Width(), m_rectSelect.Height(), SRCCOPY);
 
 HBITMAP hBmp = (HBITMAP)bitmap.Detach();
 dcSave.SelectObject(pOldBmp);

 // save to the clipboard
 if(::OpenClipboard(m_hWnd))
 {
 ::EmptyClipboard();
 ::SetClipboardData(CF_BITMAP, hBmp);
 ::CloseClipboard();
 }
}

// 创建窗口时把屏幕图片拷贝到内存中
int CScreenWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
 if (CDialog::OnCreate(lpCreateStruct) == -1)
  return -1;
 
 // TODO: Add your specialized creation code here
 
 CDC dc;
 dc.CreateDC("DISPLAY", NULL, NULL, NULL);
 int m_nWidth = GetSystemMetrics(SM_CXSCREEN);
 int m_nHeight = GetSystemMetrics(SM_CYSCREEN);
 MoveWindow(0, 0, m_nWidth, m_nHeight);
 
 memDC.CreateCompatibleDC(&dc);
 bm.CreateCompatibleBitmap(&dc, m_nWidth, m_nHeight);
 CBitmap *pOldBmp = memDC.SelectObject(&bm);
 memDC.BitBlt(0, 0, m_nWidth, m_nHeight, &dc, 0, 0, SRCCOPY);
 
 return 0;
}

void CScreenWnd::OnLButtonDown(UINT nFlags, CPoint point)
{
 // TODO: Add your message handler code here and/or call default
 if(!m_bSelectOk && m_bSelectRgn)
 {
  m_bSelectOk = TRUE;
 }
 else if (!m_bSelectOk)
 {
  m_bSelectRgn = TRUE;
  m_rectSelect.left = m_rectSelect.right = point.x;
  m_rectSelect.top = m_rectSelect.bottom = point.y; 
 }
 CDialog::OnLButtonDown(nFlags, point);
}

void CScreenWnd::OnLButtonUp(UINT nFlags, CPoint point)
{
 // TODO: Add your message handler code here and/or call default
 if(m_bSelectOk && m_bSelectRgn)
 {
  m_rectSelect.right = point.x;
  m_rectSelect.bottom = point.y;
  m_bSelectRgn = FALSE;
  m_bSelectOk = TRUE;
  GetSelectRect();
  SaveBmp(bm, memDC);
  OnOK();
 } 
 CDialog::OnLButtonUp(nFlags, point);
}

void CScreenWnd::OnMouseMove(UINT nFlags, CPoint point)
{
 // TODO: Add your message handler code here and/or call default
 if(!m_bSelectOk)
 {
  m_rectSelect.right = point.x;
  m_rectSelect.bottom = point.y;
 } 
 DrawRect();
 CDialog::OnMouseMove(nFlags, point);
}

// 绘制图形
void CScreenWnd::DrawRect()
{
 int m_nWidth = GetSystemMetrics(SM_CXSCREEN);
 int m_nHeight = GetSystemMetrics(SM_CYSCREEN);
 CClientDC dc(this);
 CDC dcMem;
 dcMem.CreateCompatibleDC(&dc);
 CBitmap bmp;
 bmp.CreateCompatibleBitmap(&dc, m_nWidth, m_nHeight);
 CBitmap *pOldBmp = dcMem.SelectObject(&bmp);
 dcMem.BitBlt(0, 0, m_nWidth, m_nHeight, &memDC, 0, 0, SRCCOPY);
 //-----------------------------------
 // draw the selected region
 //-------------------------------------
 if(m_bSelectRgn || m_bSelectOk)
 {
  CPen penLine(PS_SOLID, 1, RGB(87, 133, 52));
  CPen* pOldPen = dcMem.SelectObject(&penLine);

  dcMem.MoveTo(m_rectSelect.left, m_rectSelect.top);
  dcMem.LineTo(m_rectSelect.right, m_rectSelect.top);
  dcMem.LineTo(m_rectSelect.right, m_rectSelect.bottom);
  dcMem.LineTo(m_rectSelect.left, m_rectSelect.bottom);
  dcMem.LineTo(m_rectSelect.left, m_rectSelect.top);

  dcMem.SelectObject(pOldPen);
 }
 dc.BitBlt(0,0,m_nWidth, m_nHeight,
  &dcMem,
  0,0,
  SRCCOPY);
 dcMem.SelectObject(pOldBmp);
}

// 右键取消选择或者退出
void CScreenWnd::OnRButtonUp(UINT nFlags, CPoint point)
{
 // TODO: Add your message handler code here and/or call default
 if (m_bSelectOk || m_bSelectRgn)
 {
  m_bSelectOk = FALSE;
  m_bSelectRgn = FALSE;
  DisplayInfo();
 }
 else
 {
  OnOK();
 }
 CDialog::OnRButtonUp(nFlags, point);
}

// 防止背景闪烁
BOOL CScreenWnd::OnEraseBkgnd(CDC* pDC)
{
 // TODO: Add your message handler code here and/or call default
 
 return TRUE;
}

// 用来转换选中的矩形区域
void CScreenWnd::GetSelectRect()
{
 int x = m_rectSelect.left;
 int y = m_rectSelect.top;
 int x1 = m_rectSelect.right;
 int y1 = m_rectSelect.bottom;
 if((x1 - x) < 0 && (y1 - y) < 0)
 {
  int temp;
  temp = x1;
  x1 = x;
  x = temp;
  temp = y1;
  y1 = y;
  y = temp;
 }else if((x1 - x) > 0 && (y1 - y) < 0)
 {
  int temp;
  temp = y1;
  y1 = y;
  y = temp;
 }else if((x1 - x) < 0 && (y1 - y) > 0)
 {
  int temp;
  temp = x1;
  x1 = x;
  x= temp;
 }
 m_rectSelect.left = x;
 m_rectSelect.top = y;
 m_rectSelect.right = x1;
 m_rectSelect.bottom = y1;
}

需要源码请留下Email