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