Virusl C++ >> GUI >> Win32 API

Screen Capture


好用的副程式

int CaptureImage(HWND hWnd)
{
  RECT rt={0};
  int ret = 0;
  HDC hdcWindow;
  HDC hdcMemDC = NULL;
  HBITMAP hbmScreen = NULL;
  BITMAP bmpScreen;

  hdcWindow = GetDC(NULL);
  hdcMemDC = CreateCompatibleDC(hdcWindow);
  if(!hdcMemDC){
    ret = -1;
    goto done;
  }

  rt.right = GetSystemMetrics(SM_CXSCREEN);
  rt.bottom = GetSystemMetrics(SM_CYSCREEN);
  if(hWnd != NULL){
    GetWindowRect(hWnd, &rt);
  }

  hbmScreen = CreateCompatibleBitmap(hdcWindow, rt.right-rt.left, rt.bottom-rt.top);
  if(!hbmScreen){
    ret = -2;
    goto done;
  }
  SelectObject(hdcMemDC, hbmScreen);
  if (!BitBlt(hdcMemDC, 0, 0, rt.right - rt.left, rt.bottom - rt.top, hdcWindow, rt.left, rt.top, SRCCOPY)){
    ret = -3;
    goto done;
  }
  GetObject(hbmScreen, sizeof(BITMAP), &bmpScreen);
  BITMAPFILEHEADER bmfHeader;
  BITMAPINFOHEADER bi;
  bi.biSize = sizeof(BITMAPINFOHEADER);
  bi.biWidth = bmpScreen.bmWidth;
  bi.biHeight = bmpScreen.bmHeight;
  bi.biPlanes = 1;
  bi.biBitCount = 32;
  bi.biCompression = BI_RGB;
  bi.biSizeImage = 0;
  bi.biXPelsPerMeter = 0;
  bi.biYPelsPerMeter = 0;
  bi.biClrUsed = 0;
  bi.biClrImportant = 0;

  DWORD dwBmpSize = ((bmpScreen.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmpScreen.bmHeight;
  HANDLE hDIB = GlobalAlloc(GHND, dwBmpSize);
  char *lpbitmap = (char*)GlobalLock(hDIB);
  GetDIBits(hdcWindow, hbmScreen, 0, (UINT)bmpScreen.bmHeight, lpbitmap, (BITMAPINFO*)&bi, DIB_RGB_COLORS);

  HANDLE hFile = CreateFile(_T("c:\\demo.bmp"), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
  bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);
  bmfHeader.bfSize = dwSizeofDIB;
  bmfHeader.bfType = 0x4D42; //BM   

  DWORD dwBytesWritten = 0;
  WriteFile(hFile, (LPSTR)&bmfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL);
  WriteFile(hFile, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL);
  WriteFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &dwBytesWritten, NULL);
  GlobalUnlock(hDIB);
  GlobalFree(hDIB);
  CloseHandle(hFile);

done:
  DeleteObject(hbmScreen);
  DeleteObject(hdcMemDC);
  ReleaseDC(NULL, hdcWindow);
  return ret;
}

使用方式如下所示

CaptureImage(NULL); // whole screen
CaptureImage(hWnd); // hWnd point to the specific windows that we would like to capture


返回上一頁