VS2008中MFC单文档显示位图

 

1.创建一个MFC单文档应用程序Myvs.

2.编写自己的CDib类

下面是我自己编写的DIB类代码:

CDib.h文件

class CDib : public CObject
{
public:
    RGBQUAD* m_pRGB;
    BYTE* m_pData;
    UINT m_numberOfColors;
 BOOL m_valid;
    BITMAPFILEHEADER bitmapFileHeader;

    BITMAPINFOHEADER* m_pBitmapInfoHeader;
    BITMAPINFO* m_pBitmapInfo;
    BYTE* pDib;
 DWORD size;
public:
    CDib();
    ~CDib();

 char m_fileName[256];
    char* GetFileName();
    BOOL IsValid();
    DWORD GetSize();
    UINT GetWidth();
    UINT GetHeight();
    UINT GetNumberOfColors();
    RGBQUAD* GetRGB();
    BYTE* GetData();
    BITMAPINFO* GetInfo();

 WORD PaletteSize(LPBYTE lpDIB);
 WORD DIBNumColors(LPBYTE lpDIB);
    void SaveFile(const CString filename);

public:
    void LoadFile(const char* dibFileName);
};

CDib.cpp文件

#include "stdafx.h"
#include "cdib.h"
#include "windowsx.h"
#include "math.h"
#define WIDTHBYTES(bits)    (((bits) + 31) / 32 * 4)

CDib::CDib()
{
 size=0;
}

CDib::~CDib()
{
    GlobalFreePtr(m_pBitmapInfo);
}

void CDib::LoadFile(const char* dibFileName)
{
   strcpy(m_fileName,dibFileName);
    CFile dibFile(m_fileName, CFile::modeRead);
    dibFile.Read((void*)&bitmapFileHeader,sizeof(BITMAPFILEHEADER));
    if (bitmapFileHeader.bfType == 0x4d42)
    {
        DWORD fileLength = dibFile.GetLength();   
         size = fileLength -sizeof(BITMAPFILEHEADER);
         pDib =(BYTE*)GlobalAllocPtr(GMEM_MOVEABLE, size);
        dibFile.Read((void*)pDib, size);
        dibFile.Close();
        m_pBitmapInfo = (BITMAPINFO*) pDib;
        m_pBitmapInfoHeader = (BITMAPINFOHEADER*) pDib;
        m_pRGB = (RGBQUAD*)(pDib +
   m_pBitmapInfoHeader->biSize);
        int m_numberOfColors = GetNumberOfColors();
        if (m_pBitmapInfoHeader->biClrUsed == 0)
            m_pBitmapInfoHeader->biClrUsed =
       m_numberOfColors;
        DWORD colorTableSize = m_numberOfColors *
            sizeof(RGBQUAD);
        m_pData = pDib + m_pBitmapInfoHeader->biSize
            + colorTableSize;
  if (m_pRGB == (RGBQUAD*)m_pData) // No color table
   m_pRGB = NULL;
        m_pBitmapInfoHeader->biSizeImage = GetSize();
  m_valid = TRUE;
    }   
    else
    {
        m_valid = FALSE;
        AfxMessageBox("This isn't a bitmap file!");
    }
}

BOOL CDib::IsValid()
{
    return m_valid;
}
       
char* CDib::GetFileName()
{
    return m_fileName;
}
       
UINT CDib::GetWidth()
{
    return (UINT) m_pBitmapInfoHeader->biWidth;
}
       
UINT CDib::GetHeight()
{
    return (UINT) m_pBitmapInfoHeader->biHeight;
}
       
DWORD CDib::GetSize()
{
    if (m_pBitmapInfoHeader->biSizeImage != 0)
        return m_pBitmapInfoHeader->biSizeImage;
 else
    {
        DWORD height = (DWORD) GetHeight();
        DWORD width = (DWORD) GetWidth();
        return height * width;
    }
}

UINT CDib::GetNumberOfColors()
{
 int numberOfColors;

    if ((m_pBitmapInfoHeader->biClrUsed == 0) &&
          (m_pBitmapInfoHeader->biBitCount < 9))
 {
  switch (m_pBitmapInfoHeader->biBitCount)
  {
      case 1: numberOfColors = 2; break;
      case 4: numberOfColors = 16; break;
      case 8: numberOfColors = 256;
  }
 }
    else
  numberOfColors = (int) m_pBitmapInfoHeader->biClrUsed;

    return numberOfColors;
}
   
BYTE* CDib::GetData()
{
    return m_pData;
}

RGBQUAD* CDib::GetRGB()
{
    return m_pRGB;
}

BITMAPINFO* CDib::GetInfo()
{
    return m_pBitmapInfo;
}

WORD CDib::PaletteSize(LPBYTE lpDIB)
{
    return (DIBNumColors(lpDIB) * sizeof(RGBTRIPLE));
}

WORD CDib::DIBNumColors(LPBYTE lpDIB)
{
    WORD wBitCount;  // DIB bit count
    wBitCount = ((LPBITMAPCOREHEADER)lpDIB)->bcBitCount;
    switch (wBitCount)
    {
        case 1:
            return 2;
        case 4:
            return 16;
        case 8:
            return 256;
        default:
            return 0;
    }
}

void CDib::SaveFile(const CString filename)
{
    strcpy(m_fileName,filename);
    CFile dibFile(m_fileName, CFile::modeCreate|CFile::modeWrite);
    dibFile.Write((void*)&bitmapFileHeader,sizeof(BITMAPFILEHEADER));
    dibFile.Write((void*)pDib, size);
    dibFile.Close();

}

3.将CDib类添加到自己的工程中。

将CDib类的两个文件放到项目目录下面,鼠标右键点击工程项目名,选择“添加”→“现有项”,将CDib类添加进项目。

4.切换到资源视图标签,选择“Menu”选项下面的选项,打开菜单编辑窗口,为“打开”添加消息响应,具体操作见下图。

VS2008中MFC单文档显示位图
点右键,选择“添加事件处理程序” →“添加编辑”(如下图);
VS2008中MFC单文档显示位图
添加如下代码:
void CMyvsDoc::OnFileOpen()
{
 // TODO: 在此添加命令处理程序代码
 CFileDialog fileDlg(TRUE);
 fileDlg.m_ofn.lpstrTitle = "打开图片对话框";
 fileDlg.m_ofn.lpstrFilter = "BMP File(*.bmp)\0*.bmp\0\0";
 if (IDOK == fileDlg.DoModal())
 {
  filename.Format("%s",fileDlg.GetPathName());
 }
 CDib.LoadFile(filename);
}
5.同样的方法在View类中添加“显示原图”菜单项及相应消息处理函数
void CMyvsView::OnYuantu()
{
 // TODO: 在此添加命令处理程序代码
 CMyvsDoc* pDoc = GetDocument();
 ASSERT_VALID(pDoc);
 filename = pDoc->filename;
 state1=1;
 Invalidate();
}
6.在CMyvsView类中的OnDraw函数下面添加如下代码
void CMyvsView::OnDraw(CDC* pDC)
{
 CMyvsDoc* pDoc = GetDocument();
 ASSERT_VALID(pDoc);
 if (!pDoc)
  return;
 // TODO: 在此处为本机数据添加绘制代码
 if(state1==1)
 {
  CBitmap m_bitmap;
  HBITMAP hBitmap=(HBITMAP)LoadImage(NULL,_T(filename),IMAGE_BITMAP,
   0,0,LR_CREATEDIBSECTION|LR_DEFAULTSIZE|LR_LOADFROMFILE);
  m_bitmap.Attach (hBitmap);
  CDC dcImage;
  if(!dcImage.CreateCompatibleDC (pDC))
   return;
  BITMAP bm;
  m_bitmap.GetBitmap (&bm);
  dcImage.SelectObject (&m_bitmap);
  pDC->BitBlt (0,0,bm.bmWidth ,bm.bmHeight ,&dcImage,0,0,SRCCOPY);
 }
}
7.在CMyvsView类下添加变量CString filename和int state1;
在CMyvsDoc类下下添加变量CString filename和CDib CDib;
编译运行即可。

你可能感兴趣的:(VS2008中MFC单文档显示位图)