2009. 8. 28. 07:14

클립보드(Clipboard)에 비트맵 저장 & 로드

클립보드에 비트맵을 저장하는 방법과 다시 그 비트맵을 클립보드로부터 로드하여 파일에 저장하는 코드 예이다.

원본 출처 : http://soulfree.net/187


CMaptoolDoc* pDoc = GetDocument();


   HANDLE                    hDIB;   

   BITMAPFILEHEADER          bifileHdr;

   BYTE*                     lptrData;

  

   CClientDC dc(this); //클립보드로 현재 이미지를 전송

  

   CDC MemDC;

   MemDC.CreateCompatibleDC(&dc);

  

   CRect rect;

   GetClientRect(rect); //뷰 영역의 크기를 얻어온다   

   rect.right = pDoc->map_arr_x*(pDoc->tile_pixel_x+pDoc->view_size);

   rect.bottom = pDoc->map_arr_y*(pDoc->tile_pixel_y+pDoc->view_size);


   CBitmap BMP;

   BMP.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height());

   CBitmap* pOldBitmap = MemDC.SelectObject(&BMP);    // 메모리 DC로 BitMap 선택.

  

   MemDC.BitBlt(0, 0, rect.Width(), rect.Height(), &dc, 0, 0, SRCCOPY);

   // 현재 화면의 내용을 메모리 DC로 전송한다.


   /////////////////////////////////////////////////////////////////////////////////

   // 클립보드에 캡춰한 비트맵을 설정한다.

   OpenClipboard();        // 현재 클립보드를 연다.

   EmptyClipboard();        // 현재 클립보드의 내용을 모두 제거한다.

   SetClipboardData(CF_BITMAP, BMP.GetSafeHandle()); // Capture한 비트맵 설정

   CloseClipboard();


   MemDC.SelectObject(pOldBitmap);

   BMP.Detach();        // 비트맵 객체 제거


   OpenClipboard();


   //클립보드로 카피된게 DIB 형식이 아니면 바로 리턴.

   if(!IsClipboardFormatAvailable(CF_DIB))

   {

       AfxMessageBox("Image file save Fail");

       return;

   }


   hDIB = ::GetClipboardData(CF_DIB);


   if(!hDIB)

   {

       AfxMessageBox("Image file save Fail");

       CloseClipboard();

       return;

   }   


   CloseClipboard();


   //비트맵 헤더의 크기를 계산하고

   bifileHdr.bfType        = 0x4D42;

   bifileHdr.bfSize        = sizeof(BITMAPFILEHEADER) + GlobalSize(hDIB);

   bifileHdr.bfReserved1    = 0;

   bifileHdr.bfReserved2    = 0;

   bifileHdr.bfOffBits        = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

  


   lptrData = (BYTE *)GlobalLock(hDIB);


   char szFilter[] = "BMP File(*.bmp)|*.bmp|All Files(*.*)|*.*||";

   CFileDialog dlg(FALSE, "bmp", "*.bmp", OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter);

   if(IDOK == dlg.DoModal())

   {

       CFile file;

       file.Open(dlg.GetPathName(), CFile::modeCreate | CFile::modeWrite);    

       file.Write(&bifileHdr, sizeof(BITMAPFILEHEADER));

       file.Write(lptrData, GlobalSize(hDIB));

       file.Close();      

   }

   GlobalUnlock(hDIB);

   GlobalFree(hDIB);  

참조사이트

http://www.codeguru.com/Cpp/G-M/bitmap/capturing/article.php/c4919/

http://www.codeguru.com/Cpp/G-M/bitmap/capturing/article.php/c4915/