📄 dibprocessdoc.cpp
字号:
// DibProcessDoc.cpp : implementation of the CDibProcessDoc class
//
#include "stdafx.h"
#include "DibProcess.h"
#include "DibProcessDoc.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define DIB_MARKER ((WORD)('M'<<8) | 'B') //DIB文件头标志(字符串"BM")
/////////////////////////////////////////////////////////////////////////////
// CDibProcessDoc
IMPLEMENT_DYNCREATE(CDibProcessDoc, CDocument)
BEGIN_MESSAGE_MAP(CDibProcessDoc, CDocument)
//{{AFX_MSG_MAP(CDibProcessDoc)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDibProcessDoc construction/destruction
CDibProcessDoc::CDibProcessDoc()
{
// 成员变量初始化
m_hDib=NULL;
lpbmihrd=NULL; // 指向BITMAPINFO结构的指针
lpdib=NULL;
lpDIBBits=NULL;
dwDIBSize=0;
lpRgbQuag=NULL;
m_palDIB = NULL;
m_sizeDoc = CSize(1,1);
}
CDibProcessDoc::~CDibProcessDoc()
{
if(m_hDib!=NULL)
::GlobalFree(m_hDib);
lpbmihrd=NULL; // 指向BITMAPINFO结构的指针
lpdib=NULL;
dwDIBSize=0;
lpRgbQuag=NULL;
dwDIBSize=0;
if(m_palDIB != NULL)
{
delete m_palDIB;
}
}
BOOL CDibProcessDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
// TODO: add reinitialization code here
// (SDI documents will reuse this document)
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CDibProcessDoc serialization
void CDibProcessDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: add storing code here
}
else
{
// TODO: add loading code here
}
}
/////////////////////////////////////////////////////////////////////////////
// CDibProcessDoc diagnostics
#ifdef _DEBUG
void CDibProcessDoc::AssertValid() const
{
CDocument::AssertValid();
}
void CDibProcessDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CDibProcessDoc commands
BOOL CDibProcessDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
if (!CDocument::OnOpenDocument(lpszPathName))
return FALSE;
// TODO: Add your specialized creation code here
//读取BMP文件到file对象
CFile file;
if(!file.Open(lpszPathName,CFile::modeRead | CFile::shareDenyWrite))
{
return FALSE;
}
DeleteContents(); //删除文档数据
//////////////////////////////////////////
//将指定的文件中的DIB对象读到内存区域中
/////////////////////////////////////////
DWORD dwFileSize;
dwFileSize= file.GetLength();// 获取文件大小
if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))// 读取DIB文件头
{
return NULL;// 大小不一致,返回NULL。
}
if (bmfHeader.bfType != DIB_MARKER)// 判断是否是DIB对象
{
return NULL;// 如果不是则返回NULL。
}
m_hDib= (HGLOBAL) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwFileSize-sizeof(BITMAPFILEHEADER));// 分配DIB内存
if (m_hDib== 0)
{
return NULL;// 分配失败,返回NULL
}
/////////////////////////////////////////////////////////////////////////
//给位图相关变量赋值
lpdib = (LPSTR) ::GlobalLock((HGLOBAL) m_hDib);// 锁定
lpbminfo=(BITMAPINFO*)lpdib;
lpbmihrd=(BITMAPINFOHEADER*)lpdib;
lpRgbQuag=(RGBQUAD*)(lpdib+lpbmihrd->biSize);
int m_numberOfColors =GetColorNum((LPSTR)lpbmihrd);
if (lpbmihrd->biClrUsed == 0)
lpbmihrd->biClrUsed =m_numberOfColors;
DWORD colorTableSize = m_numberOfColors *sizeof(RGBQUAD);
lpDIBBits=lpdib+lpbmihrd->biSize+colorTableSize;
/////////////////////////////////////////////////////////////////////////
if (file.ReadHuge(lpdib, dwFileSize - sizeof(BITMAPFILEHEADER)) !=// 读像素
dwFileSize - sizeof(BITMAPFILEHEADER) )//大小不一致
{
::GlobalUnlock((HGLOBAL) m_hDib); // 解除锁定
::GlobalFree((HGLOBAL) m_hDib); // 释放内存
return NULL;
}
::GlobalUnlock((HGLOBAL) m_hDib);// 解除锁定
return TRUE;
}
WORD CDibProcessDoc::GetColorNum(LPSTR lpdib)
{
long dwClrUsed = ((LPBITMAPINFOHEADER)lpdib)->biClrUsed; // 读取dwClrUsed值
if (dwClrUsed != 0)
{
return (WORD)dwClrUsed;// 如果dwClrUsed不为0,直接返回该值
}
WORD wBitCount = ((LPBITMAPINFOHEADER)lpdib)->biBitCount;// 读取biBitCount值
switch (wBitCount)// 按照像素的位数计算颜色数目
{
case 1:
return 2;
case 4:
return 16;
case 8:
return 256;
default:
return 0;
}
}
HGLOBAL CDibProcessDoc::GetHObject() const
{
return m_hDib;
}
DWORD CDibProcessDoc::GetWidth(LPSTR lpdib)
{
return ((LPBITMAPINFOHEADER)lpdib)->biWidth;//返回DIB宽度
}
DWORD CDibProcessDoc::GetHeight(LPSTR lpdib)
{
return ((LPBITMAPINFOHEADER)lpdib)->biHeight;//返回DIB高度
}
BOOL CDibProcessDoc::DrawDib(HDC hDC,
LPRECT lpDCRect,
HGLOBAL hDIB,
LPRECT lpDIBRect,
CPalette* pPal)
{
BOOL bSuccess=FALSE; // 重画成功标志
HPALETTE hOldPal=NULL; // 以前的调色板
if (hDIB == NULL)// 判断是否是有效的DIB对象
{
return FALSE;// 不是,则返回
}
lpdib = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);// 锁定DIB
lpDIBBits = GetBits(lpdib);// 找到DIB图象像素起始位置
if (pPal != NULL)// 获取DIB调色板,并选取到设备环境中它
{
HPALETTE hPal = (HPALETTE) pPal->m_hObject;
hOldPal = ::SelectPalette(hDC, hPal, TRUE);
}
::SetStretchBltMode(hDC, COLORONCOLOR);// 设置显示模式
bSuccess = ::StretchDIBits(hDC, // 设备环境句柄
lpDCRect->left, //目标X坐标
lpDCRect->top, // 目标Y坐标
GetRectWidth(lpDCRect), // 目标宽度
GetRectHeight(lpDCRect), // 目标高度
lpDIBRect->left, // 源X坐标
lpDIBRect->top, // 源Y坐标
GetRectWidth(lpDIBRect), // 源宽度
GetRectHeight(lpDIBRect), // 源高度
lpDIBBits, // 指向dib像素的指针
(LPBITMAPINFO)lpdib, // 指向位图信息结构的指针
DIB_RGB_COLORS, // 使用的颜色数目
SRCCOPY); // 光栅操作类型
::GlobalUnlock(hDIB); // 解除锁定
if (hOldPal != NULL)// 恢复系统调色板
{
::SelectPalette(hDC, hOldPal, TRUE);
}
return bSuccess;
}
CPalette* CDibProcessDoc::GetDocPal() const
{
return m_palDIB;
}
LPSTR CDibProcessDoc::GetBits(LPSTR lpdib)
{
return (lpdib + ((LPBITMAPINFOHEADER)lpdib)->biSize+GetPalSize(lpdib));
}
WORD CDibProcessDoc::GetPalSize(LPSTR lpdib)
{
return (WORD)(GetColorNum(lpdib) * sizeof(RGBQUAD));// 计算DIB中调色板的大小
}
long CDibProcessDoc::GetRectWidth(LPCRECT lpRect)
{
long nWidth=lpRect->right - lpRect->left;
return nWidth;
}
long CDibProcessDoc::GetRectHeight(LPCRECT lpRect)
{
long nHeight=lpRect->bottom - lpRect->top;
return nHeight;
}
void CDibProcessDoc::InitMembers()
{
m_hDib=NULL;
lpbmihrd=NULL; // 指向BITMAPINFO结构的指针
lpdib=NULL;
lpDIBBits=NULL;
dwDIBSize=0;
lpRgbQuag=NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -