Captura simpla de ecran utilizand MFC/ATL

Ovidiu Cucu, 11.01.2011

Mediu: Visual Studio 2005/2008/2010, Windows XP/Vista/7

Introducere

CImage este o clasa comuna bibliotecilor MFC si ATL. Ea permite lucrul usor cu bitmap-uri si cu diverse formate de fisiere grafice (BMP, JPEG, GIF, si PNG) Acest articol prezinta o clasa care extinde CImage avand metode pentru captura de imagini de pe ecran.

Clasa CScreenImage

CScreenImage este derivata din CImage si poate fi folosita in orice aplicatie MFC sau ATL.

class CScreenImage : public CImage
{
public:
    BOOL CaptureRect(const CRect& rect) throw();
    BOOL CaptureScreen() throw();
    BOOL CaptureWindow(HWND hWnd) throw();
};

  • CScreenImage::CaptureRect - captureaza o imagine dintr-o portiune data a ecranului;
  • CScreenImage::CaptureScreen - captureaza tot ecranul;
  • CScreenImage::CaptureWindow - captureaza imaginea unei ferestre date.
CScreenImage::CaptureRect face efectiv captura si de aceea am dat impementarea in detaliu mai jos.
Utilizeaza metoda clasica de transfer (bit-blitting) dintr-un DC (device context) pentru ecran, intr-un DC de memorie compatibil. In cele din urma, handle-ul bitmap-ului rezultat este atasat la obiectul curent.
De notat flag-ul CAPTUREBLT care este utilizat in apelul functiei BitBlt pentru a lucra inclusiv cu ferestre layered.
/**********************************************************************
 Function:   CScreenImage::CaptureRect
 Purpose:    captures a screen rectangle
 Parameters: rect: screen rectangle to be captured
 Return:     non-zero value if successful
***********************************************************************/
BOOL CScreenImage::CaptureRect(const CRect& rect)
{
   // detach and destroy the old bitmap if any attached
   CImage::Destroy();
   
   // create a screen and a memory device context
   HDC hDCScreen = ::CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
   HDC hDCMem = ::CreateCompatibleDC(hDCScreen);
   // create a compatible bitmap and select it in the memory DC
   HBITMAP hBitmap = 
      ::CreateCompatibleBitmap(hDCScreen, rect.Width(), rect.Height());
   HBITMAP hBmpOld = (HBITMAP)::SelectObject(hDCMem, hBitmap);

   // bit-blit from screen to memory device context
   // note: CAPTUREBLT flag is required to capture layered windows
   DWORD dwRop = SRCCOPY | CAPTUREBLT;
   BOOL bRet = ::BitBlt(hDCMem, 0, 0, rect.Width(), rect.Height(), 
                        hDCScreen, rect.left, rect.top, dwRop);
   // attach bitmap handle to this object
   Attach(hBitmap);

   // restore the memory DC and perform cleanup
   ::SelectObject(hDCMem, hBmpOld);
   ::DeleteDC(hDCMem);
   ::DeleteDC(hDCScreen);

   return bRet;
}
Implementarea celorlalte metode poate fi gasita in sursele atasate la articol.

Aplicatia demo

Aplicatia demo este o aplicatie simpla SDI care afiseaza intr-un view imaginile capturate cu ajutorul clasei CScreenImage.

Din meniul Capture se pot selecta urmatoarele comenzi:

  • Screen, pentru a captura imaginea de pe tot ecranul;
  • Foreground window, pentru a captura imaginea ferestrei in care utilizatorul lucreaza;
  • Rectangle, pentru a captura imaginea dintr-o zona selectata cu mouse-ul.
Bineinteles, aplicatia poate fi dezvoltata prin adaugarea de noi functii cum ar fi capturarea oricarei ferestre top-level sau child, pentru capturarea zonei client a unei ferestre, pentru salvarea imaginii etc.

Link-uri

Atasamente

Va rugam sa va autentificati pentru a descarca fisierele!

CScreenImage_src.zip - Fisiere sursa
CaptureDemo_sln.zip - Proiect demo


Unelte: