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

📄 chapter13doc.cpp

📁 单文档中打开图片
💻 CPP
字号:
// Chapter13Doc.cpp : implementation of the CChapter13Doc class
//

#include "stdafx.h"
#include "Chapter13.h"

#include "Chapter13Doc.h"
#include "Chapter13View.h"
#include "math.h"

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

/////////////////////////////////////////////////////////////////////////////
// CChapter13Doc

HBITMAP hpreview = NULL;//预览位图句柄
BOOL m_showpreview = TRUE;//显示预览
CString lpszPathName;//选择的文件名

// Proprietary Hook function for open dialog

UINT APIENTRY OFNHookProc( HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam )
{
	//定义结构    
	LPDRAWITEMSTRUCT lpdis;
	BITMAP bm;
	LPNMHDR pnmh;
	char filename[MAX_PATH];
	CString str;
	int height,height2,width,width2;
	NMHDR nmh;
    
    switch (uiMsg)
    {
        case WM_COMMAND:            
            if (LOWORD(wParam) == IDC_SHOWPREVIEW)
            {
                //检查预览复选项
				m_showpreview = IsDlgButtonChecked(hdlg,IDC_SHOWPREVIEW);
                //如果选中的话则显示预览图
				if (!m_showpreview)
                {                    
                    //清除旧的内容
					if (hpreview)
                        DeleteObject(hpreview);
					//重新初始化
                    hpreview = NULL;
                    //获取显示图像的控件句柄
					HWND wnd = GetDlgItem(hdlg,IDC_PREVIEWBTN);
					//使无效
                    InvalidateRect(wnd,NULL,TRUE);    
					//设置各控件标题
                    SetDlgItemText(hdlg,IDC_WIDTH,"");
                    SetDlgItemText(hdlg,IDC_HEIGHT,"");
                    SetDlgItemText(hdlg,IDC_DEPTH,"");
                    SetDlgItemText(hdlg,IDC_FSIZE,"");
                }
                else
                {
					//选择的文件改变时
                    nmh.code = CDN_SELCHANGE;
                    OFNHookProc(hdlg, WM_NOTIFY, 0, (LPARAM)&nmh);
                }
            }
            break;
        case WM_DRAWITEM:

            if (hpreview)
            {
                lpdis = (LPDRAWITEMSTRUCT)lParam;
                //用位图的信息填充bm结构        
                GetObject(hpreview,sizeof(BITMAP),&bm);
				//设置点
                CPoint size(bm.bmWidth,bm.bmHeight);
				//创建兼容DC
                HDC dcmem = CreateCompatibleDC(lpdis->hDC);
				//选入内存
                HBITMAP old = (HBITMAP)SelectObject(dcmem,hpreview);
				//宽度大于高度,基本思想是将宽度调为适合,高度按比例缩放
                if (bm.bmWidth > bm.bmHeight)
                {
					//自画的高度
                    height = lpdis->rcItem.bottom - lpdis->rcItem.top;
					//比率
                    float ratio = (float)bm.bmHeight/(float)bm.bmWidth;
                    //调整后自画部分(图像)的底部
                    lpdis->rcItem.bottom  = (long) (lpdis->rcItem.top + 
						(lpdis->rcItem.right-lpdis->rcItem.left)*ratio);
					//居中后,上下应该空出的高度
                    height2 = (height - (lpdis->rcItem.bottom -
						lpdis->rcItem.top))/2;
					//自画的实际顶部
                    lpdis->rcItem.top += height2;
					//自画的实际底部
                    lpdis->rcItem.bottom += height2;
                }
                else
                {
                    width = lpdis->rcItem.right - lpdis->rcItem.left;
                    float ratio = (float)bm.bmWidth/(float)bm.bmHeight;       
                    lpdis->rcItem.right  = (long) (lpdis->rcItem.left + (lpdis->rcItem.bottom-lpdis->rcItem.top)*ratio);
                    width2 = (width - (lpdis->rcItem.right - lpdis->rcItem.left))/2;
                    lpdis->rcItem.left += width2;
                    lpdis->rcItem.right += width2;

                }
				//设置拉伸模式
                SetStretchBltMode(lpdis->hDC,HALFTONE);   
                //拉伸图像
				StretchBlt(lpdis->hDC,lpdis->rcItem.left,lpdis->rcItem.top,
					lpdis->rcItem.right-lpdis->rcItem.left,
					lpdis->rcItem.bottom-lpdis->rcItem.top,
					dcmem,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);
				//恢复原来的
                SelectObject(dcmem,old);
				//删除
                DeleteDC(dcmem);
            }
            break;

        case WM_NOTIFY:
        
            pnmh = (LPNMHDR) lParam;

            if (pnmh->code == CDN_FILEOK)
            {
                if (hpreview)
                        DeleteObject(hpreview);
                //下面避免了断言错误,可以由文件对话框类的DoModal函数的实现过程看到这点
//                _AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
//	            pThreadState->m_pAlternateWndInit = NULL;
                //用户选择了OK按钮
				return 0;
            }
			//初始化完毕对话框中的控件后发送
            if (pnmh->code ==  CDN_INITDONE)
            {
               if (hpreview)
                    DeleteObject(hpreview);

			   //改变按钮控件的状态
                CheckDlgButton(hdlg,IDC_SHOWPREVIEW,m_showpreview);
                return 0;
            }
			//列表中的选项改变时发送
            if (pnmh->code == CDN_SELCHANGE)
            {
                if (!IsDlgButtonChecked(hdlg,IDC_SHOWPREVIEW))
                {                
                    if (hpreview)
                        DeleteObject(hpreview);
                    hpreview = NULL;
                    return 0;
                }
                //获取文件名
                SendMessage(GetParent(hdlg),CDM_GETFILEPATH ,MAX_PATH,(LPARAM)filename);
				lpszPathName.Format("%s",filename);
                if (hpreview)
                    DeleteObject(hpreview);
               //加载位图
                hpreview = (HBITMAP)LoadImage(AfxGetInstanceHandle(),filename,
					IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION);
                HWND wnd = GetDlgItem(hdlg,IDC_PREVIEWBTN);
				//使失效
                InvalidateRect(wnd,NULL,TRUE);

                if (hpreview)
                {
                    //获取位图的信息
					GetObject(hpreview,sizeof(BITMAP),&bm);
                    str.Format("宽度: %d 像素",bm.bmWidth);
                    SetDlgItemText(hdlg,IDC_WIDTH,str);

                    str.Format("高度: %d 像素",bm.bmHeight);
                    SetDlgItemText(hdlg,IDC_HEIGHT,str);
                    //颜色
					CString strColor;
					int iColor=(int)pow(2,bm.bmBitsPixel);
					strColor.Format("颜色: %d",iColor);
					SetDlgItemText(hdlg,IDC_DEPTH,strColor);
                    //打开文件,获取文件的大小
					OFSTRUCT o;
					HFILE f = OpenFile(filename,&o,OF_READ);
                    str.Format("大小: %ld Kb",GetFileSize((HANDLE)f,NULL)/1024);
                    SetDlgItemText(hdlg,IDC_FSIZE,str);                   
                    //关闭文件
					_lclose(f);

                }
                else
                {
					//加载失败时则为空
                    SetDlgItemText(hdlg,IDC_WIDTH,"");
                    SetDlgItemText(hdlg,IDC_HEIGHT,"");
                    SetDlgItemText(hdlg,IDC_DEPTH,"");
                    SetDlgItemText(hdlg,IDC_FSIZE,"");
                }
            }

    }
    return 0;
}


IMPLEMENT_DYNCREATE(CChapter13Doc, CDocument)

BEGIN_MESSAGE_MAP(CChapter13Doc, CDocument)
	//{{AFX_MSG_MAP(CChapter13Doc)
	ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CChapter13Doc construction/destruction

CChapter13Doc::CChapter13Doc()
{
	// TODO: add one-time construction code here
}

CChapter13Doc::~CChapter13Doc()
{

}

BOOL CChapter13Doc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

	// TODO: add reinitialization code here
	// (SDI documents will reuse this document)

	return TRUE;
}



/////////////////////////////////////////////////////////////////////////////
// CChapter13Doc serialization

void CChapter13Doc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		// TODO: add storing code here
	}
	else
	{
		// TODO: add loading code here
	}
}

/////////////////////////////////////////////////////////////////////////////
// CChapter13Doc diagnostics

#ifdef _DEBUG
void CChapter13Doc::AssertValid() const
{
	CDocument::AssertValid();
}

void CChapter13Doc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CChapter13Doc commands
void CChapter13Doc::OnFileOpen() 
{
	//获取视图的指针,以便刷新视图
	POSITION pos = GetFirstViewPosition();
	CChapter13View* pView =(CChapter13View*) GetNextView(pos);	
	// TODO: Add your command handler code here
	OPENFILENAME m_ofn;
	ZeroMemory(&m_ofn,sizeof(m_ofn));
	m_ofn.lpstrFilter = "Bitmaps (*.bmp)\0*.bmp\0"\
		"All Files (*.*)\0*.*\0\0";                            
	
    m_ofn.Flags=OFN_HIDEREADONLY |OFN_ENABLEHOOK|OFN_EXPLORER
		|OFN_ENABLETEMPLATE;
//	m_ofn.Flags=OFN_HIDEREADONLY |OFN_EXPLORER;//|OFN_ENABLETEMPLATE;
	m_ofn.lStructSize=sizeof(OPENFILENAME);
    m_ofn.hInstance = AfxGetInstanceHandle();
    m_ofn.lpTemplateName = MAKEINTRESOURCE(IDC_PREVIEW);
    m_ofn.lpfnHook = OFNHookProc; 
	//选择OK时,函数返回非0
	if(GetOpenFileName(&m_ofn))
	{
		//打开文件
		CFile file;
		if (!file.Open(lpszPathName, CFile::modeRead|
			CFile::shareDenyWrite))
		{	// 返回				
			return ;
		}	
		DeleteContents();
		//删除当前文档后立即刷新
		UpdateAllViews(NULL);
		m_dib.m_hDib=m_dib.LoadFile(file);
		// 判断读取文件是否成功
		if (m_dib.m_hDib == NULL)	
		{		
			AfxMessageBox("读取图象时出错");				
			return ;
		}		
		// 初始化DIB,并且构建调色板
		CSize m_sizeDoc;
		LPSTR lpdib = (LPSTR) ::GlobalLock((HGLOBAL) m_dib.m_hDib);
		// 设置文档大小	
		m_sizeDoc = CSize((int)m_dib.GetWidth(lpdib), (int)m_dib.GetHeight(lpdib));
		::GlobalUnlock((HGLOBAL)m_dib.m_hDib);	
		// 创建新调色板
		m_dib.m_palDIB = new CPalette;	
		// 判断是否创建成功,如果失败则
		if (m_dib.m_palDIB == NULL)
		{		
			::GlobalFree((HGLOBAL) m_dib.m_hDib);
			// 设置DIB对象为空
			m_dib.m_hDib = NULL;
			return;
		}	
		// 调用ConstructPalette来创建调色板
		if (m_dib.ConstructPalette(m_dib.m_hDib, m_dib.m_palDIB) == NULL)
		{	// 删除			
			delete m_dib.m_palDIB;	
			// 设置为空
			m_dib.m_palDIB = NULL;	
			return;
		}
		// 设置文件名称
		SetPathName(lpszPathName);		
		while (pos != NULL)
		{
			//使视图失效
			pView->Invalidate();
			//更新视图
			pView->UpdateWindow();
		} 
		//或者只使用如下语句
		//UpdateAllViews(NULL);				
		pView->SetScrollSizes(MM_TEXT, m_sizeDoc);
	}
	return ;
}

BOOL CChapter13Doc::OnSaveDocument(LPCTSTR lpszPathName) 
{
	// TODO: Add your specialized code here and/or call the base class
	CFile file;
	// 打开文件
	if(!file.Open(lpszPathName, CFile::modeCreate |
		CFile::modeReadWrite | CFile::shareExclusive))
	{// 返回FALSE
		return FALSE;
	}
	BOOL bSuccess = FALSE;	
	// 保存图象
	bSuccess = m_dib.SaveFile(m_dib.m_hDib, file);		
	// 关闭文件
	file.Close();	
	if (!bSuccess)
	{// 提示出错		
		AfxMessageBox("保存BMP图象时出错");
	}	
	return bSuccess;
}

⌨️ 快捷键说明

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