步骤1:添加新类CDIBStatic,类型为MFC Class,基类为CStatic。
步骤2:在工程中加入CPictureObj.h和CPictureObj.cpp,及CIstream.h和CIstream.cpp。
步骤3:在类CDIBStatic加入头文件#include "PictureObj.h",添加变量CPictureObj* m_pPicObj;,用于读取和显示。CPictureObj中封装了IPicture接口。
步骤4:新建一Dialog,加入控件picture,类型为MFC Class,基类为CfileDlg。
部分代码:
CDIBStatic源代码:
OOL CDIBStatic::LoadDib(LPCTSTR lpszFileName)//读取
{
try//利用try语句当文件第一次打开时lpszFileName会出错,在catch中捕获将其设置为NULL
lpszFileName = lpszFileName;
// 确保文件存在并能打开
CFile file(lpszFileName, CFile::modeRead);
file.Close();
// 创建图像显示的对象并读入图像文件
m_pPicObj = new CPictureObj;
if(!m_pPicObj->Load(lpszFileName))
{
// 读入文件失败,清除对象
m_pPicObj = NULL;
delete m_pPicObj;
// 清除显示的图像并显示错误提示
PaintDib(IsValidDib());
return FALSE;
}
PaintDib(IsValidDib());
return TRUE;
}
catch (CFileException* e)
{
m_lpszFileName = NULL;
PaintDib(IsValidDib());
e->Delete();
return FALSE;
}
}
void CDIBStatic::PaintDib(BOOL bDibValid)//显示
{
ASSERT_VALID(this);
ClearDib(); // 清除以前的图像
CRect PaintRect;
// 获得显示区域
GetClientRect(&PaintRect);
PaintRect.InflateRect(-1, -1);
CClientDC dc(this);
if (bDibValid && m_bPreview)
{
CSize size = m_pPicObj->GetSize(&dc);
int nDestX, nDestY, nDestWidth, nDestHeight;
if ((DWORD)size.cx < (DWORD)PaintRect.Width() && (DWORD)size.cy < (DWORD)PaintRect.Height())
{ // 图像尺寸小于显示区域将图像显示在中间
nDestX = PaintRect.left + (PaintRect.Width() - size.cx)/2;
nDestY = PaintRect.top + (PaintRect.Height() - size.cy)/2;
nDestWidth = size.cx;
nDestHeight = size.cy;
}
else
{ // 图像尺寸大于显示区域,进行比例缩放
if ((PaintRect.Width()/(float)size.cx) <= (PaintRect.Height()/(float)size.cy))
{ // 宽度限制
nDestWidth = PaintRect.Width();
nDestHeight = (nDestWidth*size.cy) / size.cx;
nDestX = PaintRect.left;
nDestY = PaintRect.top + (PaintRect.Height() - nDestHeight) /2;
}
else
{ // 高度限制
nDestHeight = PaintRect.Height();
nDestWidth = (nDestHeight*size.cx) / size.cy;
nDestX = PaintRect.left + (PaintRect.Width() - nDestWidth) /2;
nDestY = PaintRect.top;
}
}
// 获得图像的显示位置和大小
CRect RectDest(nDestX, nDestY, nDestX+nDestWidth, nDestY+nDestHeight);
// 显示图像
m_pPicObj->Draw(&dc,&RectDest,&RectDest);
// 给图像加一外框
CBrush* pOldBrush = (CBrush*)dc.SelectStockObject(NULL_BRUSH);
dc.Rectangle(RectDest);
if(NULL != pOldBrush) { dc.SelectObject(pOldBrush); }
}
else
{
// 显示错误提示信息
CString strText = "不能识别的文件格式!";
if( m_lpszFileName == NULL || strlen(m_lpszFileName) <= 0 )
{
strText = "没有选择文件!";
}
if( !m_bPreview )
{
strText = "";
}
dc.DrawText(strText, strText.GetLength(), &PaintRect, DT_SINGLELINE|DT_CENTER|DT_VCENTER|DT_END_ELLIPSIS);
}
return;
}
HBRUSH CDIBSatic::CtlColor(CDC* pDC, UINT nCtlColor)//用于重绘
{
// TODO: Change any attributes of the DC here
PaintDib(IsValidDib());
return (HBRUSH)GetStockObject(NULL_BRUSH);
}
BOOL IsValidDib() const { return (m_pPicObj && m_pPicObj->m_pPict); }
void CDIBSatic::ClearDib()//清除图片
{
ASSERT_VALID(this);
CClientDC dc(this);
CRect rectPaint;
GetClientRect(&rectPaint);
rectPaint.InflateRect(-1,-1);
CBrush* pBrushWhite; //白画刷
pBrushWhite = CBrush::FromHandle((HBRUSH)::GetStockObject(WHITE_BRUSH));
dc.FillRect(&rectPaint, pBrushWhite);
}
void RemoveDib() { m_lpszFileName = NULL; delete m_pPicObj; m_pPicObj = NULL; PaintDib(IsValidDib()); }
void SetPreview(BOOL bPreview) { m_bPreview = bPreview; PaintDib(IsValidDib()); }
CPreviewFileDlg源代码:
BOOL CPreviewFileDlg::OnInitDialog()
{
CFileDialog::OnInitDialog();
m_DIBStaticCtrl.SubclassDlgItem(IDC_IMAGE, this);
CWnd* pParent = GetParent();
CRect rcParent;
pParent->GetClientRect(&rcParent);
CRect rcPrev;
GetDlgItem(IDC_PREVIEW)->GetClientRect(&rcPrev); //复选框
CRect rc;
m_DIBStaticCtrl.GetClientRect(&rc);
int height = rc.Height();
rc.top = rcPrev.bottom - 10;//图像框设置
rc.bottom = rc.top + height ;
rc.left = 50;
rc.right = rcParent.Width() - rc.left;
m_DIBStaticCtrl.MoveWindow(&rc, true);
GetDlgItem(IDC_PREVIEW)->SendMessage(BM_SETCHECK, (m_bPreview) ? 1 : 0);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CPreviewFileDlg::OnFileNameChange()
{
CFileDialog::OnFileNameChange();
if (m_bPreview)
{
m_DIBStaticCtrl.SetPreview(m_bPreview);//显示图片
m_DIBStaticCtrl.LoadDib(GetPathName()); //加载
}
}//当点击文件时调用
void CPreviewFileDlg::OnFolderChange()
{
CFileDialog::OnFolderChange();
m_DIBStaticCtrl.RemoveDib();//清除
}
菜单栏源代码:
void CPreviewDlg::OnPreview()
{
// TODO: Add extra validation here
static char BASED_CODE szFilter[] = "Bitmap(*.bmp)|*.bmp|JPEG(*.jpg)|*.jpg|GIF(*.gif)|*.gif|WMF(*.wmf)|*.wmf|ICON(*.ico)|*.ico||";
CString strDefName;
char szPath[MAX_PATH];//最大目录大小
CPreviewFileDlg FileDlg(TRUE,"*.*",NULL,
OFN_FILEMUSTEXIST|OFN_NONETWORKBUTTON|
OFN_PATHMUSTEXIST,szFilter);
FileDlg.m_ofn.lpstrInitialDir = szPath;
if( FileDlg.DoModal() != IDOK )
return;
// To get the selected file's path and name
CString strFileName;
strFileName = FileDlg.GetPathName();
if(strFileName.IsEmpty())
{
return;
}
}