📄 dwgpreviewbutton.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 + -