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

📄 dwgpreviewbutton.cpp

📁 DWG 文件 预览图片 格式及显示预览图片 格式及显示
💻 CPP
字号:
// DWGPreviewButton.cpp : implementation file
//

#include "stdafx.h"
#include "SHOWDWG.h"
#include "DWGPreviewButton.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CDWGPreviewButton

CDWGPreviewButton::CDWGPreviewButton()
{
	bDisplayFlag=0;
}

CDWGPreviewButton::~CDWGPreviewButton()
{
	bDisplayFlag=0;
	FreeDCMem();
}


BEGIN_MESSAGE_MAP(CDWGPreviewButton, CButton)
	//{{AFX_MSG_MAP(CDWGPreviewButton)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDWGPreviewButton message handlers


void CDWGPreviewButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
{
	// TODO: Add your code to draw the specified item
	if(lpDrawItemStruct->itemAction&ODA_DRAWENTIRE)
	{
		DrawButton();
	}	
}

void CDWGPreviewButton::FreeDCMem()
{
	cdMem.DeleteDC();
	MyBmp.DeleteObject();
}

void CDWGPreviewButton::DisplayPreviewFromDwg(CString szFileName)
{
	if(bDisplayFlag==1)
	{//已有显示,先释放资源
		FreeDCMem();
		bDisplayFlag=0;
	}
	GetClientRect(&reButton);
	CDC *pdc;
	pdc=GetDC();
	MyBmp.CreateCompatibleBitmap(pdc,reButton.right,reButton.bottom);
	cdMem.CreateCompatibleDC(pdc);
	cdMem.SelectObject(MyBmp);
	cdMem.SelectStockObject(BLACK_BRUSH);
	cdMem.FillRect(reButton,cdMem.GetCurrentBrush());
	m_FileName=szFileName;
 	ReadDWGPreviewImageData(&cdMem);
	DrawButton();
	bDisplayFlag=1;
	ReleaseDC(pdc);
}

void CDWGPreviewButton::DrawButton()
{
	CDC *pdc;
	pdc=GetDC();
	pdc->BitBlt(0,0,reButton.right,reButton.bottom,&cdMem,0,0,SRCCOPY);
	ReleaseDC(pdc);
}

void CDWGPreviewButton::ReadDWGPreviewImageData(CDC *pDC)
{
	unsigned char ucSpecialCode[16];
							//预览图片特征字段16字节
	unsigned char ucNotSpecialCode[16];//反码16字节
	unsigned long lFileOffset;		//文件指针偏移,
	unsigned long lAllPreviewSize;	//预览图片大小
	BYTE iBlockNumber;		//预览图片数量
	BYTE DB_Type;			//图片类型
	unsigned long DB_Offset;//图片的其实位置
	unsigned long DB_Size;	//图片的大小
	CFile file;
	long i;

	if(!file.Open(m_FileName,CFile::modeRead|CFile::shareDenyNone,NULL))
		return;//当DWG文件正在使用时,必须使用CFile::shareDenyNone才能正确打开
	file.Seek(13L,CFile::begin);//文件指针设在第13字节处
	file.Read(&lFileOffset,sizeof(long));//读取预览图片位置
	file.Seek(lFileOffset,CFile::begin);//设置文件指针,读取预览图片特征字段
	file.Read(ucSpecialCode,16*sizeof(unsigned char));
	if(ucSpecialCode[0]!=0x1F||ucSpecialCode[1]!=0x25||
	   ucSpecialCode[2]!=0x6D||ucSpecialCode[3]!=0x07||
	   ucSpecialCode[4]!=0xD4||ucSpecialCode[5]!=0x36||
	   ucSpecialCode[6]!=0x28||ucSpecialCode[7]!=0x28||
	   ucSpecialCode[8]!=0x9D||ucSpecialCode[9]!=0x57||
	   ucSpecialCode[10]!=0xCA||ucSpecialCode[11]!=0x3F||
	   ucSpecialCode[12]!=0x9D||ucSpecialCode[13]!=0x44||
	   ucSpecialCode[14]!=0x10||ucSpecialCode[15]!=0x2B)
	{
		return;//预览图片的特征字段错误,返回;
	}
	file.Read(&lAllPreviewSize,sizeof(long));
		//读取预览图片大小
	file.Seek(lAllPreviewSize,CFile::current);
	file.Read(ucNotSpecialCode,16*sizeof(unsigned char));
		//读取图片结束后的特征字段反码
	if((~ucNotSpecialCode[0]&0xff)!=0x1F||
	   (~ucNotSpecialCode[1]&0xff)!=0x25||
	   (~ucNotSpecialCode[2]&0xff)!=0x6D||
	   (~ucNotSpecialCode[3]&0xff)!=0x07||
	   (~ucNotSpecialCode[4]&0xff)!=0xD4||
	   (~ucNotSpecialCode[5]&0xff)!=0x36||
	   (~ucNotSpecialCode[6]&0xff)!=0x28||
	   (~ucNotSpecialCode[7]&0xff)!=0x28||
	   (~ucNotSpecialCode[8]&0xff)!=0x9D||
	   (~ucNotSpecialCode[9]&0xff)!=0x57||
	   (~ucNotSpecialCode[10]&0xff)!=0xCA||
	   (~ucNotSpecialCode[11]&0xff)!=0x3F||
	   (~ucNotSpecialCode[12]&0xff)!=0x9D||
	   (~ucNotSpecialCode[13]&0xff)!=0x44||
	   (~ucNotSpecialCode[14]&0xff)!=0x10||
	   (~ucNotSpecialCode[15]&0xff)!=0x2B)
	{
		return;//预览图片结束后的特征字段反码错误,返回;
	}
	file.Seek(-16-lAllPreviewSize,CFile::current);
		//设置文件指针,回到数据段	
	file.Read(&iBlockNumber,sizeof(BYTE));//读取文件预览图片数量
	for(i=0;i<iBlockNumber;i++)
	{
		file.Read(&DB_Type,sizeof(BYTE));
		file.Read(&DB_Offset,sizeof(long));
		file.Read(&DB_Size,sizeof(long));
		if(DB_Type==0x2)break;//预览图片类型为BMP图像,退出
	}
	if(i==iBlockNumber)return;
	file.Seek(DB_Offset,CFile::begin);//移至BMP图片数据区
	BYTE *pDib=new BYTE[DB_Size];//申请图片大小存储空间
	if(pDib==NULL)return;
	file.Read(pDib,DB_Size);//读取BMP图片数据
	file.Close();

	LPBITMAPINFO m_lpBmpInfo;
	LPBITMAPINFOHEADER m_lpBmpInfoHeader;
	LPRGBQUAD m_lpColorTable;//逻辑调色板指针
	LPBYTE m_lpImageData;	//图像数据指针
	int m_ColorNumber=256;	//颜色数为256色
	m_lpBmpInfo=(LPBITMAPINFO)pDib;
	m_lpBmpInfoHeader=(LPBITMAPINFOHEADER)pDib;
	m_lpColorTable=(LPRGBQUAD)(pDib+m_lpBmpInfoHeader->biSize);
	m_lpImageData=(LPBYTE)m_lpColorTable+m_ColorNumber*sizeof(RGBQUAD);
	int bmpWidth=m_lpBmpInfoHeader->biWidth;	//图像宽度
	int bmpHeight=m_lpBmpInfoHeader->biHeight;	//图像高度
	//下面设置逻辑调色板
	LPRGBQUAD pDibQuad;
	HPALETTE hPal,hOldPal;
	LPLOGPALETTE pLogPal=(LPLOGPALETTE)new char[2*sizeof(WORD)+m_ColorNumber*sizeof(PALETTEENTRY)];
	pLogPal->palVersion=0x300;
	pLogPal->palNumEntries=m_ColorNumber;
	pDibQuad=(LPRGBQUAD)m_lpColorTable;
	for(i=0;i<m_ColorNumber;i++)
	{
		pLogPal->palPalEntry[i].peRed=pDibQuad->rgbRed;
		pLogPal->palPalEntry[i].peGreen=pDibQuad->rgbGreen;
		pLogPal->palPalEntry[i].peBlue=pDibQuad->rgbBlue;
		pLogPal->palPalEntry[i].peFlags=0;
		pDibQuad++;
	}

	hPal=::CreatePalette((LPLOGPALETTE)pLogPal);
	hOldPal=::SelectPalette(pDC->m_hDC,hPal,FALSE);
	::RealizePalette(pDC->m_hDC);

	int offx,offy;//偏移值,使图像居中显示
	offx=(reButton.right-bmpWidth)/2;
	offy=(reButton.bottom-bmpHeight)/2;
	if(offx<0)offx=0;//当按钮宽度小于BMP宽度,x轴不偏移
	if(offy<0)offy=0;//当按钮高度小于BMP高度,y轴不偏移

	HBITMAP bmMask,bmMaskOld;
	HBITMAP bmNegative,bmNegativeOld;
	HBITMAP bmPositive,bmPositiveOld;
	HDC m_hDC,hdcMask,hdcNegative,hdcPositive;

	m_hDC=pDC->GetSafeHdc();
	hdcMask=CreateCompatibleDC(m_hDC);
	hdcNegative=CreateCompatibleDC(m_hDC);
	hdcPositive=CreateCompatibleDC(m_hDC);

	bmMask=CreateBitmap(bmpWidth,bmpHeight,1,1,NULL);//黑白色图像
	bmNegative=CreateCompatibleBitmap(m_hDC,bmpWidth,bmpHeight);
	bmPositive=CreateCompatibleBitmap(m_hDC,bmpWidth,bmpHeight);

	bmMaskOld=(HBITMAP)SelectObject(hdcMask,bmMask);
	bmNegativeOld=(HBITMAP)SelectObject(hdcNegative,bmNegative);
	bmPositiveOld=(HBITMAP)SelectObject(hdcPositive,bmPositive);

	StretchDIBits(hdcPositive,0,0,bmpWidth,bmpHeight,
		0,0,bmpWidth,bmpHeight,(void*)m_lpImageData,m_lpBmpInfo,
		DIB_RGB_COLORS,SRCCOPY);//取得原图
	BitBlt(hdcMask,0,0,bmpWidth,bmpHeight,hdcPositive,0,0,NOTSRCCOPY);
		//拷贝一个原图的反单色图
	BitBlt(hdcPositive,0,0,bmpWidth,bmpHeight,hdcMask,0,0,SRCAND);
		//与原图and合并,将两图中白变黑
	StretchDIBits(hdcNegative,0,0,bmpWidth,bmpHeight,
		0,0,bmpWidth,bmpHeight,(void*)m_lpImageData,m_lpBmpInfo,
		DIB_RGB_COLORS,NOTSRCCOPY);
		//取得原图的反图
	BitBlt(hdcMask,0,0,bmpWidth,bmpHeight,hdcNegative,0,0,NOTSRCCOPY);
		//拷贝一个原图的反图的反单色图
	BitBlt(hdcNegative,0,0,bmpWidth,bmpHeight,hdcMask,0,0,NOTSRCCOPY);
		//以上图中黑线变白线,同时白底变黑底

	BitBlt(m_hDC,offx,offy,bmpWidth,bmpHeight,hdcPositive,0,0,SRCCOPY);
	BitBlt(m_hDC,offx,offy,bmpWidth,bmpHeight,hdcNegative,0,0,SRCPAINT);
		//“或”合并两图

	DeleteObject(SelectObject(hdcMask,bmMaskOld));
	DeleteObject(SelectObject(hdcNegative,bmNegativeOld));
	DeleteObject(SelectObject(hdcPositive,bmPositiveOld));
	DeleteDC(hdcMask);
	DeleteDC(hdcNegative);
	DeleteDC(hdcPositive);

	::SelectPalette(pDC->m_hDC,hOldPal,FALSE);
	::DeleteObject(hPal);
	delete pDib;
	delete pLogPal;
}

⌨️ 快捷键说明

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