之前,失败了无数次,把我给整疯了,这次终于成功了!

现在将搭建的方法发到博客上。

最终解决的途径

跳出思维局限,不要拘泥于某一个版本,比如vs2019或者vs2017,说不定vs2015就可以呢?

这次vs2015就成功了!

首先安装vs2015社区版

下载的时候记得勾选Visual C++

>>官方下载器地址

现在开始搭建框架

新建MFC应用程序

应用程序类型设置

把文件DIb.h和Dib.cpp拷贝到项目文件夹下

把dib.h添加到项目的“解决方案”下的“头文件”

把dib.cpp文件添加到项目的“解决方案”下的“源文件”

修改代码部分

重要提示:

每一个类都有一个头文件(.h)和源文件(.cpp)

一定要看清楚,不要加错了

----------------------------------Doc.h--------------------------------------------

修改一

找到 #pragma once

在下面添加

#include "Dib.h"

修改二

找到特性和操作,直接替换

// 特性
public:
	CDib m_dib;
// 操作
public:
	HGLOBAL GetHObject() const	//获取Dib对象的句柄
		{ return m_hDIB; }
	CPalette* GetDocPal() const	//获取调色板指针
		{ return m_palDIB; }
	CSize GetDocDimension() const//获取调色板大小
		{ return m_sizeDoc; }
	void UpdateObject(HGLOBAL hDIB);//更新dib对象

修改三

找到实现

// 实现
public:
	void SetDib();				//初始化dib对象
protected:
	HGLOBAL m_hDIB;
	CPalette*  m_palDIB;
	CSize m_sizeDoc;

-----------------------doc类重写函数(打开、保存文件)的添加----------------------------

类视图,打开属性

在此添加Open、Save函数(不可手动复制添加)

-------------------------------------Doc.cpp-----------------------------------------

找到构造函数

// TODO: 在此添加一次性构造代码
	m_hDIB = NULL;// 初始化变量
	m_palDIB = NULL;
	m_sizeDoc = CSize(1,1);

找到析构函数

        if (m_hDIB != NULL)// 判断是否有DIB对象
	{		
		::GlobalFree((HGLOBAL) m_hDIB);
	}
	
	
	if (m_palDIB != NULL)// 判断调色板是否存在
	{
		delete m_palDIB;
	}

找到OnOpenDocument函数

        if (!CDocument::OnOpenDocument(lpszPathName))
		return FALSE;

	// TODO:  在此添加您专用的创建代码
	CFile file;
	if (!file.Open(lpszPathName, CFile::modeRead | 
		CFile::shareDenyWrite))// 打开文件
	{					
		return FALSE;// 返回FALSE
	}	
	DeleteContents();
	m_hDIB=m_dib.LoadFile(file);
	if(m_hDIB==NULL)// 调用LoadFile()读取图象
	{			
		return FALSE;
	}		
	SetDib();// 初始化DIB
	if (m_hDIB == NULL)	// 判断读取文件是否成功
	{		
		AfxMessageBox(L"读取图像时出错");// 提示出错				
		return FALSE;// 返回FALSE
	}		
	SetPathName(lpszPathName);// 设置文件名称		
	SetModifiedFlag(FALSE);// 初始化修改标记为FALSE		
	return TRUE;// 返回TRUE

找到OnSaveDocument函数

        // TODO: 在此添加专用代码和/或调用基类
	CFile file;
	if(!file.Open(lpszPathName, CFile::modeCreate |// 打开文件
	CFile::modeReadWrite | CFile::shareExclusive))
	{
		return FALSE;// 返回FALSE
	}
	BOOL bSuccess = FALSE;	
	bSuccess = m_dib.SaveFile(m_hDIB, file);	// 保存图象	
	file.Close();// 关闭文件	
	SetModifiedFlag(FALSE);// 重置脏标记为FALSE
	if (!bSuccess)
	{			
		AfxMessageBox(L"保存BMP图象时出错");// 提示出错
	}	
	return bSuccess;
	//return CDocument::OnSaveDocument(lpszPathName);

现在检查Doc类是否已经存在SetDib函数和UpdateObject函数

若不存在,则手动添加,随后粘贴代码

若存在,直接复制粘贴如下代码到Doc.cpp文件中,并修改类名部分

类名根据项目名称的不同而不同

void C********Doc::SetDib() //这个函数需要手动添加,前面的类名要与项目一致
{
	LPSTR lpdib = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);	
	
	if (m_dib.GetWidth(lpdib) > INT_MAX ||m_dib.GetHeight(lpdib) > INT_MAX)// 判断图象是否过大
	{
		::GlobalUnlock((HGLOBAL) m_hDIB);				
		::GlobalFree((HGLOBAL) m_hDIB);	// 释放DIB对象			
		m_hDIB = NULL;// 设置DIB为空		
		AfxMessageBox(L"初始化失败"); 		
		return;
	}	
	m_sizeDoc = CSize((int)m_dib.GetWidth(lpdib), (int)m_dib.GetHeight(lpdib));// 设置文档大小	
	::GlobalUnlock((HGLOBAL) m_hDIB);	
	m_palDIB = new CPalette;// 创建新调色板		
	if (m_palDIB == NULL)// 判断是否创建成功
	{		
		::GlobalFree((HGLOBAL) m_hDIB);	// 失败		
		m_hDIB = NULL;// 设置DIB对象为空
		return;
	}	
	// 调用CreateDIBPalette来创建调色板
	if (m_dib.ConstructPalette(m_hDIB, m_palDIB) == NULL)
	{				
		delete m_palDIB;// 删除				
		m_palDIB = NULL;// 设置为空	
		return;// 返回空
	}
}
void C********Doc::UpdateObject(HGLOBAL hDIB)   //这个函数需要手动添加,类名要修改
{
	if (m_hDIB != NULL)               // 判断DIB是否为空
	{		
		::GlobalFree((HGLOBAL) m_hDIB);// 非空,则清除
	}	
	m_hDIB = hDIB;                     // 替换成新的DIB对象	
}

---------------------------View.cpp----------------------------

找到OnDraw函数

看到这里

删去注释,解除封印

看到这一行,在下面添加代码

        // TODO: 在此处为本机数据添加绘制代码
	HGLOBAL hDIB = pDoc->GetHObject();
	
	// 判断DIB是否为空
	if (hDIB != NULL)
	{
		LPSTR lpDibSection = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
		
		// 获取DIB宽度
		int cxDIB = (int) pDoc->m_dib.GetWidth(lpDibSection);
		
		// 获取DIB高度
		 int cyDIB = (int) pDoc->m_dib.GetHeight(lpDibSection);
		::GlobalUnlock((HGLOBAL) hDIB);
		CRect rcDIB;
		rcDIB.top = rcDIB.left = 0;
		rcDIB.right = cxDIB;
		rcDIB.bottom = cyDIB;
		CRect rcDest= rcDIB;	
		// 输出DIB
		pDoc->m_dib.DrawDib(pDC->m_hDC, &rcDest, pDoc->GetHObject(),
			&rcDIB, pDoc->GetDocPal());
	}

在确保项目文件夹下已有stdafx.h”“stdafx.cpp存在时,编译执行

效果

 

 

 

 

posted on 2020-05-20 15:06  海月CSDN  阅读(294)  评论(0编辑  收藏  举报