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

📄 atldib.h

📁 这是一本学习 window编程的很好的参考教材
💻 H
字号:
#ifndef __ATLDIB_H__
#define __ATLDIB_H__

/////////////////////////////////////////////////////////////////////////////
// DIB (Device Independant Bitmap) class
//
// Written by Bjarke Viksoe (bjarke@viksoe.dk)
// Copyright (c) 2001 Bjarke Viksoe.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed by any means PROVIDING it is 
// not sold for profit without the authors written consent, and 
// providing that this notice and the authors name is included. 
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability if it causes any damage to you or your
// computer whatsoever. It's free, so don't hassle me about it.
//
// Beware of bugs.
//

#pragma once


/////////////////////////////////////////////////////////////////////////////
// CDib

class CDib
{
public:
   LPVOID m_hDib;
   BITMAPINFOHEADER m_bi;
   DWORD m_dwLineWidth;
   DWORD m_dwPixelWidth;
   WORD m_nColors;

   CDib() : m_hDib(NULL), m_nColors(0), m_dwLineWidth(0UL), m_dwPixelWidth(0UL)
   {
      ::ZeroMemory(&m_bi, sizeof(m_bi));
   }
   ~CDib()
   {
      if( !IsEmpty() ) DeleteObject();
   }
   CDib& operator=(const CDib& src)
   {
      src.CopyTo(this);
      return *this;
   }
   void DeleteObject()
   {
      ATLASSERT(!IsEmpty());
      free(m_hDib);
      m_hDib = NULL;
   }
   BOOL IsEmpty() const
   {
      return m_hDib==NULL;
   }
   BOOL CopyTo(CDib *pDst) const
   {
      ATLASSERT(pDst);
      if( !pDst->IsEmpty() ) pDst->DeleteObject();
      DWORD dwSize = GetByteSize();
      pDst->m_hDib = malloc(dwSize); // Allocate memory block to store our bitmap
      ATLASSERT(pDst->m_hDib);
      if( pDst->m_hDib==NULL ) return FALSE;
      ::CopyMemory(&pDst->m_bi, &m_bi, sizeof(m_bi));
      ::CopyMemory(pDst->m_hDib, m_hDib, dwSize);
      pDst->m_dwLineWidth = m_dwLineWidth;
      pDst->m_dwPixelWidth = m_dwPixelWidth;
      pDst->m_nColors = m_nColors;
      return TRUE;
   }
   BOOL LoadBitmap(LPCTSTR lpszPathName)
   {
      ATLASSERT(!::IsBadStringPtr(lpszPathName,-1));
      HBITMAP hBitmap = (HBITMAP) ::LoadImage(NULL, lpszPathName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
      ATLASSERT(hBitmap);
      if( hBitmap==NULL ) return FALSE;
      BOOL res = Create(hBitmap);
      ::DeleteObject(hBitmap);
      return res;
   }
   BOOL LoadBitmap(UINT nRes)
   {
      HBITMAP hBitmap = (HBITMAP) ::LoadImage(_Module.GetResourceInstance(), MAKEINTRESOURCE(nRes), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
      ATLASSERT(hBitmap);
      if( hBitmap==NULL ) return FALSE;
      BOOL res = Create(hBitmap);
      ::DeleteObject(hBitmap);
      return res;
   }
   BOOL Create(HBITMAP hBitmap)
   {
      ATLASSERT(::GetObjectType(hBitmap)==OBJ_BITMAP);
      BITMAP bm;
      ::GetObject(hBitmap, sizeof(BITMAP), &bm);
      if( Create(bm.bmWidth, bm.bmHeight, 24)==FALSE ) return FALSE;
      CWindowDC dc(HWND_DESKTOP); // Need a DC; any DC will do!
      int lines = ::GetDIBits(dc, hBitmap, 0, bm.bmHeight, GetBits(), (BITMAPINFO*) &m_bi, DIB_RGB_COLORS);
      ATLASSERT(lines==bm.bmHeight);
      if( lines != bm.bmHeight ) return FALSE;
      return TRUE;
   }
   BOOL Create(DWORD dwWidth, DWORD dwHeight, WORD wBitCount)
   {
      #define WIDTHBYTES(bits)  (((bits) + 31) / 32 * 4)
      if( !IsEmpty() ) DeleteObject();

      // Make sure bits per pixel is valid
      if( wBitCount<=1 ) wBitCount = 1;
      else if( wBitCount<=4 ) wBitCount = 4;
      else if( wBitCount<=8 ) wBitCount = 8;
      else wBitCount = 24;
      switch( wBitCount ){
      case 1:
         m_nColors = 2;
         break;
      case 4:
         m_nColors = 16;
         break;
      case 8:
         m_nColors = 256;
         break;
      default:
         // A 24/32 bit DIB has no color table
         m_nColors = 0;
      }
      m_dwLineWidth = WIDTHBYTES(wBitCount * dwWidth);
      m_dwPixelWidth = wBitCount / 8;

      // Initialize BITMAPINFOHEADER
      m_bi.biSize = sizeof(BITMAPINFOHEADER);
      m_bi.biWidth = dwWidth;         // Fill in width from parameter
      m_bi.biHeight = dwHeight;       // Fill in height from parameter
      m_bi.biPlanes = 1;              // Must be 1
      m_bi.biBitCount = wBitCount;
      m_bi.biCompression = BI_RGB;    
      m_bi.biSizeImage = m_dwLineWidth * dwHeight;
      m_bi.biXPelsPerMeter = 0;
      m_bi.biYPelsPerMeter = 0;
      m_bi.biClrUsed = 0;
      m_bi.biClrImportant = 0;

      // Calculate size of memory block required to store the DIB.  This
      // block should be big enough to hold the BITMAPINFOHEADER, the color
      // table, and the bits
      m_hDib = malloc(GetByteSize()); // Allocate memory block to store our bitmap
      if( m_hDib==NULL ) return FALSE;

      // Use our bitmap info structure to fill in first part of
      // our DIB with the BITMAPINFOHEADER
      LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER) m_hDib;
      *lpbi = m_bi;
      return TRUE;
   }
   DWORD GetByteSize() const
   {
      return m_bi.biSize + m_bi.biSizeImage + GetPaletteSize();
   }
   inline LPBYTE GetBits() const
   {
      ATLASSERT(!IsEmpty());
      return( (BYTE*) m_hDib + ( *(LPDWORD) m_hDib ) + GetPaletteSize() ); 
   }
   inline DWORD GetWidth() const
   {
      ATLASSERT(!IsEmpty());
      return m_bi.biWidth;
   }
   inline DWORD GetHeight() const
   {
      ATLASSERT(!IsEmpty());
      return m_bi.biHeight;
   }
   inline DWORD GetLineWidth() const
   {
      ATLASSERT(!IsEmpty());
      return m_dwLineWidth;
   }
   inline DWORD GetPixelWidth() const
   {
      ATLASSERT(!IsEmpty());
      return m_dwPixelWidth;
   }
   WORD GetColorCount() const
   {
      return m_nColors;
   }
   WORD GetPaletteSize() const
   {
      WORD wNumColors = GetColorCount();
      if( m_bi.biSize==sizeof(BITMAPCOREHEADER) )
         return (WORD) (wNumColors * sizeof(RGBTRIPLE));
      else
         return (WORD) (wNumColors * sizeof(RGBQUAD));
   }
   WORD GetBitCount() const
   {
      ATLASSERT(!IsEmpty());
      return m_bi.biBitCount;
   }

   COLORREF GetPixel(int x, int y) const
   {
      ATLASSERT(!IsEmpty());
      if( x<0 || x>=m_bi.biWidth || y<0 || y>=m_bi.biHeight ) return RGB(0,0,0);
      LPBYTE lp = GetBits() + (y * m_dwLineWidth) + (x * m_dwPixelWidth);
      return RGB(lp[0], lp[1], lp[2]);
   }
   void SetPixel(int x, int y, COLORREF rgb)
   {
      ATLASSERT(!IsEmpty());
      if( x<0 || x>=m_bi.biWidth || y<0 || y>=m_bi.biHeight ) return;
      LPBYTE lp = GetBits() + (y * m_dwLineWidth) + (x * m_dwPixelWidth);
      *lp++ = GetRValue(rgb);
      *lp++ = GetGValue(rgb);
      *lp++ = GetBValue(rgb);
   }

   BOOL Draw(HDC hDC, long xoffset, long yoffset) const
   {
      if( (m_hDib==NULL) || (hDC==NULL) ) return FALSE;
      ::SetStretchBltMode(hDC,COLORONCOLOR);   
      ::SetDIBitsToDevice(hDC, xoffset, yoffset,
         m_bi.biWidth, m_bi.biHeight, 0, 0, 
         0, m_bi.biHeight, GetBits(),
         (BITMAPINFO*) m_hDib, DIB_RGB_COLORS);
      return TRUE;
   }
   BOOL Stretch(HDC hDC, long xoffset, long yoffset, long xsize, long ysize) const
   {
      if( (m_hDib == NULL) || (hDC == NULL) ) return FALSE;
      ::SetStretchBltMode(hDC,COLORONCOLOR);   
      ::StretchDIBits(hDC, xoffset, yoffset,
         xsize, ysize, 0, 0, m_bi.biWidth, m_bi.biHeight,
         GetBits(), (BITMAPINFO*) m_hDib, DIB_RGB_COLORS, SRCCOPY);
      return TRUE;
   }
   BOOL Stretch(HDC hDC, RECT rc) const
   {
      return Stretch(hDC, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top);
   }

};

typedef CDib CDib24;


#endif // __ATLDIB_H__

⌨️ 快捷键说明

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