⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hdibapi.cpp

📁 该文件是教你如何来保存窗口的图形,以及如何截取图形.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	bl = ::ReadFile(file, pDIB, dwBitsSize - sizeof(BITMAPFILEHEADER), &len, NULL);
	if (!bl || len != dwBitsSize - sizeof(BITMAPFILEHEADER))
	{
		::GlobalUnlock((HGLOBAL) hDIB);
		::GlobalFree((HGLOBAL) hDIB);
		return NULL;
	}
	::GlobalUnlock((HGLOBAL) hDIB);

	return hDIB;
}

LPSTR WINAPI  FindDIBBits (LPSTR lpbi)
{
   return (lpbi + *(LPDWORD)lpbi + PaletteSize (lpbi));
}

void WINAPI  InitBitmapInfoHeader (LPBITMAPINFOHEADER lpBmInfoHdr,
                                        DWORD dwWidth,
                                        DWORD dwHeight,
                                          int nBPP)
{
   memset (lpBmInfoHdr, 0, sizeof (BITMAPINFOHEADER));

   lpBmInfoHdr->biSize      = sizeof (BITMAPINFOHEADER);
   lpBmInfoHdr->biWidth     = dwWidth;
   lpBmInfoHdr->biHeight    = dwHeight;
   lpBmInfoHdr->biPlanes    = 1;

   if (nBPP <= 1)
      nBPP = 1;
   else if (nBPP <= 4)
      nBPP = 4;
   else if (nBPP <= 8)
      nBPP = 8;
   else
      nBPP = 24;

   lpBmInfoHdr->biBitCount  = nBPP;
   lpBmInfoHdr->biSizeImage = WIDTHBYTES (dwWidth * nBPP) * dwHeight;
}

HANDLE WINAPI  BitmapToDIB (HBITMAP hBitmap, HPALETTE hPal)
{
   BITMAP             Bitmap;
   BITMAPINFOHEADER   bmInfoHdr;
   LPBITMAPINFOHEADER lpbmInfoHdr;
   LPSTR              lpBits;
   HDC                hMemDC;
   HANDLE             hDIB;
   HPALETTE           hOldPal = NULL;

      // Do some setup -- make sure the Bitmap passed in is valid,
      //  get info on the bitmap (like its height, width, etc.),
      //  then setup a BITMAPINFOHEADER.

   if (!hBitmap)
      return NULL;

   if (!GetObject (hBitmap, sizeof (Bitmap), (LPSTR) &Bitmap))
      return NULL;

   InitBitmapInfoHeader (&bmInfoHdr,
                         Bitmap.bmWidth,
                         Bitmap.bmHeight,
                         Bitmap.bmPlanes * Bitmap.bmBitsPixel);


      // Now allocate memory for the DIB.  Then, set the BITMAPINFOHEADER
      //  into this memory, and find out where the bitmap bits go.

   hDIB = GlobalAlloc (GHND, sizeof (BITMAPINFOHEADER) +
             PaletteSize ((LPSTR) &bmInfoHdr) + bmInfoHdr.biSizeImage);

   if (!hDIB)
      return NULL;

   lpbmInfoHdr  = (LPBITMAPINFOHEADER) GlobalLock (hDIB);
   *lpbmInfoHdr = bmInfoHdr;
   lpBits       = FindDIBBits ((LPSTR) lpbmInfoHdr);


      // Now, we need a DC to hold our bitmap.  If the app passed us
      //  a palette, it should be selected into the DC.

   hMemDC       = GetDC (NULL);

   if (hPal)
      {
      hOldPal = SelectPalette (hMemDC, hPal, FALSE);
      RealizePalette (hMemDC);
      }



      // We're finally ready to get the DIB.  Call the driver and let
      //  it party on our bitmap.  It will fill in the color table,
      //  and bitmap bits of our global memory block.

   if (!GetDIBits (hMemDC,
                   hBitmap,
                   0,
                   Bitmap.bmHeight,
                   lpBits,
                   (LPBITMAPINFO) lpbmInfoHdr,
                   DIB_RGB_COLORS))
      {
      GlobalUnlock (hDIB);
      GlobalFree (hDIB);
      hDIB = NULL;
      }
   else
      GlobalUnlock (hDIB);


      // Finally, clean up and return.

   if (hOldPal)
      SelectPalette (hMemDC, hOldPal, FALSE);

   ReleaseDC (NULL, hMemDC);

   return hDIB;
}

int WINAPI  PalEntriesOnDevice (HDC hDC)
{
   int nColors;

      // Find out the number of palette entries on this
      //  defice.

   nColors = GetDeviceCaps (hDC, SIZEPALETTE);


      // For non-palette devices, we'll use the # of system
      //  colors for our palette size.

   if (!nColors)
      nColors = GetDeviceCaps (hDC, NUMCOLORS);

   assert (nColors);

   return nColors;
}

HPALETTE WINAPI  GetSystemPalette (void)
{
   HDC           hDC;
   HPALETTE      hPal = NULL;
   HANDLE        hLogPal;
   LPLOGPALETTE  lpLogPal;
   int           i, nColors;


      // Find out how many palette entries we want.

   hDC = GetDC (NULL);
   if (!hDC)
      {
      DIBError (ERR_GETDC);
      return NULL;
      }

   nColors = PalEntriesOnDevice (hDC);
   ReleaseDC (NULL, hDC);


      // Allocate room for the palette and lock it.

   hLogPal = GlobalAlloc (GHND, sizeof (LOGPALETTE) +
                           nColors * sizeof (PALETTEENTRY));

   if (!hLogPal)
      {
      DIBError (ERR_CREATEPAL);
      return NULL;
      }

   lpLogPal = (LPLOGPALETTE) GlobalLock (hLogPal);

   lpLogPal->palVersion    = PALVERSION;
   lpLogPal->palNumEntries = nColors;

   for (i = 0;  i < nColors;  i++)
      {
      lpLogPal->palPalEntry[i].peBlue  = 0;
      *((LPWORD) (&lpLogPal->palPalEntry[i].peRed)) = i;
      lpLogPal->palPalEntry[i].peFlags = PC_EXPLICIT;
      }



      // Go ahead and create the palette.  Once it's created,
      //  we no longer need the LOGPALETTE, so free it.

   hPal = CreatePalette (lpLogPal);

   GlobalUnlock (hLogPal);
   GlobalFree (hLogPal);

   return hPal;
}

HDIB WINAPI  CopyRectToDIB(HWND hWnd, LPRECT lpRect)
{
	/* check for a valid window handle */
	if (!hWnd)	return NULL;

	RECT rectClient;
	POINT pt1, pt2;

	/* convert client coords to screen coords */
	pt1.x = lpRect->left;
	pt1.y = lpRect->top;
	pt2.x = lpRect->right;
	pt2.y = lpRect->bottom;
	ClientToScreen(hWnd, &pt1);
	ClientToScreen(hWnd, &pt2);
	rectClient.left   = pt1.x;
	rectClient.top    = pt1.y;
	rectClient.right  = pt2.x;
	rectClient.bottom = pt2.y;

	return CopyScreenToDIB(&rectClient);
}

HDIB WINAPI  CopyWindowToDIB(HWND hWnd, WORD fPrintArea)
{
  HDIB hDIB=NULL;  // handle to DIB

  /* check for a valid window handle */
  if (!hWnd)
    return NULL;

  switch (fPrintArea)
  {
    case PW_WINDOW: // copy entire window
    {
      RECT rectWnd;

      /* get the window rectangle */
      GetWindowRect(hWnd, &rectWnd);

      /*  get the DIB of the window by calling
       *  CopyScreenToDIB and passing it the window rect
       */
      hDIB = CopyScreenToDIB(&rectWnd);
    }
    break;

    case PW_CLIENT: // copy client area
    {
      RECT rectClient;
      POINT pt1, pt2;

      /* get the client area dimensions */
      GetClientRect(hWnd, &rectClient);

      /* convert client coords to screen coords */
      pt1.x = rectClient.left;
      pt1.y = rectClient.top;
      pt2.x = rectClient.right;
      pt2.y = rectClient.bottom;
      ClientToScreen(hWnd, &pt1);
      ClientToScreen(hWnd, &pt2);
      rectClient.left   = pt1.x;
      rectClient.top    = pt1.y;
      rectClient.right  = pt2.x;
      rectClient.bottom = pt2.y;

      /*  get the DIB of the client area by calling
       *  CopyScreenToDIB and passing it the client rect
       */
      hDIB = CopyScreenToDIB(&rectClient);
    }
    break;

    default:    // invalid print area
      return NULL;
  }

  /* return the handle to the DIB */
  return hDIB;
}

HDIB WINAPI  CopyScreenToDIB(LPRECT lpRect)
{
  HBITMAP hBitmap;    // handle to device-dependent bitmap
  HPALETTE hPalette;  // handle to palette
  HDIB hDIB=NULL;     // handle to DIB

  /*  get the device-dependent bitmap in lpRect by calling
   *  CopyScreenToBitmap and passing it the rectangle to grab
   */
  hBitmap = CopyScreenToBitmap(lpRect);

  /* check for a valid bitmap handle */
  if (!hBitmap)
    return NULL;

  /* get the current palette */
  hPalette = GetSystemPalette();

  /* convert the bitmap to a DIB */
  hDIB = (HDIB)BitmapToDIB(hBitmap, hPalette);

  /* clean up */
  DeleteObject(hBitmap);
  DeleteObject(hPalette);

  /* return handle to the packed-DIB */
  return hDIB;
}

HBITMAP WINAPI  CopyScreenToBitmap(LPRECT lpRect)
{
  HDC hScrDC, hMemDC;           // screen DC and memory DC
  HBITMAP hBitmap, hOldBitmap;  // handles to deice-dependent bitmaps
  int nX, nY, nX2, nY2;         // coordinates of rectangle to grab
  int nWidth, nHeight;          // DIB width and height
  int xScrn, yScrn;             // screen resolution

  /* check for an empty rectangle */
  if (IsRectEmpty(lpRect))
    return NULL;

  /*  create a DC for the screen and create
   *  a memory DC compatible to screen DC
   */
  hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
  hMemDC = CreateCompatibleDC(hScrDC);

  /* get points of rectangle to grab */
  nX = lpRect->left;
  nY = lpRect->top;
  nX2 = lpRect->right;
  nY2 = lpRect->bottom;

  /* get screen resolution */
  xScrn = GetDeviceCaps(hScrDC, HORZRES);
  yScrn = GetDeviceCaps(hScrDC, VERTRES);

  /* make sure bitmap rectangle is visible */
  if (nX < 0)
    nX = 0;
  if (nY < 0)
    nY = 0;
  if (nX2 > xScrn)
    nX2 = xScrn;
  if (nY2 > yScrn)
    nY2 = yScrn;
  nWidth = nX2 - nX;
  nHeight = nY2 - nY;

  /* create a bitmap compatible with the screen DC */
  hBitmap = CreateCompatibleBitmap(hScrDC, nWidth, nHeight);

  /* select new bitmap into memory DC */
  hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);

  /* bitblt screen DC to memory DC */
  BitBlt(hMemDC, 0, 0, nWidth, nHeight, hScrDC, nX, nY, SRCCOPY) ;

  /*  select old bitmap back into memory DC and get handle to
   *  bitmap of the screen
   */
  hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);

  /* clean up */
  DeleteDC(hScrDC);
  DeleteDC(hMemDC);

  /* return handle to the bitmap */
  return hBitmap;
}

static char *szErrors[] = {"Not a DIB file!",
                           "Couldn't allocate memory!",
                           "Error reading file!",
                           "Error locking memory!",
                           "Error opening file!",
                           "Error creating palette!",
                           "Error getting a DC!",
                           "Error creating MDI Child!",
                           "Error creating Device Dependent Bitmap",
                           "StretchBlt() failed!",
                           "StretchDIBits() failed!",
                           "Paint requires both DDB and DIB!",
                           "SetDIBitsToDevice() failed!",
                           "Printer: StartDoc failed!",
                           "Printing: GetModuleHandle() couldn't find GDI!",
                           "Printer: SetAbortProc failed!",
                           "Printer: StartPage failed!",
                           "Printer: NEWFRAME failed!",
                           "Printer: EndPage failed!",
                           "Printer: EndDoc failed!",
                           "Only one DIB can be animated at a time!",
                           "No timers available for animation!",
                           "Can't copy to clipboard -- no current DIB!",
                           "Clipboard is busy -- operation aborted!",
                           "Can't paste -- no DIBs or DDBs in clipboard!",
                           "SetDIBits() failed!",
                           "File Not Found!",
                           "Error writing DIB file!"
                          };

void WINAPI  DIBError (int ErrNo)
{
   if ((ErrNo < ERR_MIN) || (ErrNo >= ERR_MAX))
   {
      MessageBox (GetFocus (), "Undefined Error!", NULL, MB_OK | MB_ICONHAND);
   }
   else
   {
      MessageBox (GetFocus (), szErrors[ErrNo], NULL, MB_OK | MB_ICONHAND);
   }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -