WTL基础: 显示图片(JPG, BMP, PNG等)
2016-07-01 10:58
183 查看
使用ATL 的Cimage类,图片文件大掉入和显示,变的十分简单。
具体做法是,在stdafx.h 中包含头文件, #include <atlimage.h>
定义一个CImage 对象, 如果要循环显示的话,定义成指针更简明。
下面是一个完整的显示图片的控件代码。如果需要显示更多种类的图片,定义一下即可。
#pragma once
#include "stdafx.h"
#include "atlframe.h"
#include "atlctrls.h"
#include "atlimage.h"
enum { SOURCE_DIRECTORY, SOURCE_TEXT, SOURCE_DATA, SOURCE_BMP, SOURCE_PNG, SOURCE_JPG, SOURCE_KNOWN };
class CFileObjLooker : public CWindowImpl<CFileObjLooker, CStatic>,
public COwnerDraw<CFileObjLooker>
{
protected:
TCHAR m_curSrcFile[MAX_PATH];
CImage *m_pImage;
UINT m_nType; // 资源目标类型
public:
CFileObjLooker(void) : m_pImage(NULL)
{
memset(m_curSrcFile, 0, sizeof(m_curSrcFile));
}
~CFileObjLooker()
{
if (!m_pImage)
{
delete m_pImage;
m_pImage = NULL;
}
}
void SetSourceFile(LPCTSTR tempPath)
{
m_nType = SOURCE_KNOWN;
lstrcpy(m_curSrcFile, tempPath);
if (::PathIsDirectory(m_curSrcFile))
{
m_nType = SOURCE_DIRECTORY;
return;
}
LPCTSTR pExt = ::PathFindExtension(m_curSrcFile);
if (pExt)
{
CString strExt = pExt;
strExt.MakeLower();
if (strExt == _T(".txt"))
m_nType = SOURCE_TEXT;
else if (strExt == _T(".dat"))
m_nType = SOURCE_DATA;
else if (strExt == _T(".bmp"))
m_nType = SOURCE_BMP;
else if (strExt == _T(".jpg"))
m_nType = SOURCE_JPG;
else if (strExt == _T(".png"))
m_nType = SOURCE_PNG;
}
if (m_nType >= SOURCE_BMP && m_nType <= SOURCE_JPG)
{
if (!m_pImage)
delete m_pImage;
m_pImage = new CImage();
m_pImage->Load(m_curSrcFile);
}
this->Invalidate();
}
void DrawToCenter(CDCHandle dc, LPCRECT lpRect)
{
if (!m_pImage)
return;
RECT rect, rect1;
int boxWidth = lpRect->right - lpRect->left;
int boxHeight = lpRect->bottom - lpRect->top;
int imgWidth = m_pImage->GetWidth();
int imgHeight = m_pImage->GetHeight();
::SetRect(&rect, 0, 0, imgWidth, imgHeight);
if (boxWidth >= imgWidth && boxHeight >= m_pImage->GetHeight())
{
::OffsetRect(&rect, (boxWidth - imgWidth) / 2, (boxHeight - imgHeight) / 2);
m_pImage->Draw(dc.m_hDC, rect);
return;
}
FLOAT xScale = (FLOAT)imgWidth / boxWidth;
FLOAT yScale = (FLOAT)imgHeight / boxHeight;
FLOAT maxScale = max(xScale, yScale);
imgWidth = (int)((FLOAT)imgWidth / maxScale);
imgHeight = (int)((FLOAT)imgHeight / maxScale);
::SetRect(&rect1, 0, 0, imgWidth, imgHeight);
::OffsetRect(&rect1, (boxWidth - imgWidth) / 2, (boxHeight - imgHeight) / 2);
//dc.SetStretchBltMode(COLORONCOLOR);
dc.SetStretchBltMode( HALFTONE);
m_pImage->StretchBlt(dc.m_hDC, rect1, rect);
}
BEGIN_MSG_MAP(CFileObjLooker)
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
CHAIN_MSG_MAP_ALT(COwnerDraw<CFileObjLooker>, 1)
DEFAULT_REFLECTION_HANDLER()
END_MSG_MAP()
public:
LRESULT OnEraseBkgnd(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
return 1;
}
void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CDCHandle dc = lpDrawItemStruct->hDC;
RECT rcItem = lpDrawItemStruct->rcItem;
dc.FillRect(&rcItem, 0); //21
if (m_nType >= SOURCE_BMP && m_nType <= SOURCE_JPG)
{
DrawToCenter(dc, &rcItem);
}
else
{
dc.MoveTo(rcItem.left, rcItem.top);
dc.LineTo(rcItem.right, rcItem.bottom);
}
}
};
当使用StretchBlt 函数显示缩小的图片的时候, 显示会很奇怪。 这时候需要设置模式。就是下面这行:
dc.SetStretchBltMode(COLORONCOLOR);
要使用上面的控件, 在对话框上拉一个Picture控件, 设置为自绘模式,然后再对话框里面定义一个变量。
然后在 OnInitDialog 中进行初始化,
最后再提醒一下,要在对话框的消息映射模板最后添加消息反射。
具体做法是,在stdafx.h 中包含头文件, #include <atlimage.h>
定义一个CImage 对象, 如果要循环显示的话,定义成指针更简明。
下面是一个完整的显示图片的控件代码。如果需要显示更多种类的图片,定义一下即可。
#pragma once
#include "stdafx.h"
#include "atlframe.h"
#include "atlctrls.h"
#include "atlimage.h"
enum { SOURCE_DIRECTORY, SOURCE_TEXT, SOURCE_DATA, SOURCE_BMP, SOURCE_PNG, SOURCE_JPG, SOURCE_KNOWN };
class CFileObjLooker : public CWindowImpl<CFileObjLooker, CStatic>,
public COwnerDraw<CFileObjLooker>
{
protected:
TCHAR m_curSrcFile[MAX_PATH];
CImage *m_pImage;
UINT m_nType; // 资源目标类型
public:
CFileObjLooker(void) : m_pImage(NULL)
{
memset(m_curSrcFile, 0, sizeof(m_curSrcFile));
}
~CFileObjLooker()
{
if (!m_pImage)
{
delete m_pImage;
m_pImage = NULL;
}
}
void SetSourceFile(LPCTSTR tempPath)
{
m_nType = SOURCE_KNOWN;
lstrcpy(m_curSrcFile, tempPath);
if (::PathIsDirectory(m_curSrcFile))
{
m_nType = SOURCE_DIRECTORY;
return;
}
LPCTSTR pExt = ::PathFindExtension(m_curSrcFile);
if (pExt)
{
CString strExt = pExt;
strExt.MakeLower();
if (strExt == _T(".txt"))
m_nType = SOURCE_TEXT;
else if (strExt == _T(".dat"))
m_nType = SOURCE_DATA;
else if (strExt == _T(".bmp"))
m_nType = SOURCE_BMP;
else if (strExt == _T(".jpg"))
m_nType = SOURCE_JPG;
else if (strExt == _T(".png"))
m_nType = SOURCE_PNG;
}
if (m_nType >= SOURCE_BMP && m_nType <= SOURCE_JPG)
{
if (!m_pImage)
delete m_pImage;
m_pImage = new CImage();
m_pImage->Load(m_curSrcFile);
}
this->Invalidate();
}
void DrawToCenter(CDCHandle dc, LPCRECT lpRect)
{
if (!m_pImage)
return;
RECT rect, rect1;
int boxWidth = lpRect->right - lpRect->left;
int boxHeight = lpRect->bottom - lpRect->top;
int imgWidth = m_pImage->GetWidth();
int imgHeight = m_pImage->GetHeight();
::SetRect(&rect, 0, 0, imgWidth, imgHeight);
if (boxWidth >= imgWidth && boxHeight >= m_pImage->GetHeight())
{
::OffsetRect(&rect, (boxWidth - imgWidth) / 2, (boxHeight - imgHeight) / 2);
m_pImage->Draw(dc.m_hDC, rect);
return;
}
FLOAT xScale = (FLOAT)imgWidth / boxWidth;
FLOAT yScale = (FLOAT)imgHeight / boxHeight;
FLOAT maxScale = max(xScale, yScale);
imgWidth = (int)((FLOAT)imgWidth / maxScale);
imgHeight = (int)((FLOAT)imgHeight / maxScale);
::SetRect(&rect1, 0, 0, imgWidth, imgHeight);
::OffsetRect(&rect1, (boxWidth - imgWidth) / 2, (boxHeight - imgHeight) / 2);
//dc.SetStretchBltMode(COLORONCOLOR);
dc.SetStretchBltMode( HALFTONE);
m_pImage->StretchBlt(dc.m_hDC, rect1, rect);
}
BEGIN_MSG_MAP(CFileObjLooker)
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
CHAIN_MSG_MAP_ALT(COwnerDraw<CFileObjLooker>, 1)
DEFAULT_REFLECTION_HANDLER()
END_MSG_MAP()
public:
LRESULT OnEraseBkgnd(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
return 1;
}
void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CDCHandle dc = lpDrawItemStruct->hDC;
RECT rcItem = lpDrawItemStruct->rcItem;
dc.FillRect(&rcItem, 0); //21
if (m_nType >= SOURCE_BMP && m_nType <= SOURCE_JPG)
{
DrawToCenter(dc, &rcItem);
}
else
{
dc.MoveTo(rcItem.left, rcItem.top);
dc.LineTo(rcItem.right, rcItem.bottom);
}
}
};
当使用StretchBlt 函数显示缩小的图片的时候, 显示会很奇怪。 这时候需要设置模式。就是下面这行:
dc.SetStretchBltMode(COLORONCOLOR);
要使用上面的控件, 在对话框上拉一个Picture控件, 设置为自绘模式,然后再对话框里面定义一个变量。
private: CFileObjLooker m_objFrame;
然后在 OnInitDialog 中进行初始化,
m_objFrame.SubclassWindow(this->GetDlgItem(IDC_PICTURE)); m_objFrame.SetSourceFile(_T("appicon3.jpg"));
最后再提醒一下,要在对话框的消息映射模板最后添加消息反射。
// 添加消息反射, ObjectDisp REFLECT_NOTIFICATIONS() END_MSG_MAP()
相关文章推荐
- android studio for android learning (九) android之Adapter用法
- [思考汇聚]杨小凯:后发劣势
- Redis优化总结
- 在asp.net WebAPI 中 使用Forms认证和ModelValidata(模型验证)
- 解决NSTimer存在的内存泄漏的问题
- 邓白氏回访要填的信息
- android:configChanges属性
- Android Activity和Adapter通过接口交互
- 调用webservice服务(二) 学习笔记/cxf拦截器
- Android 自定义View (三部曲)
- 单链表的插入排序
- android textView跑马灯效果
- javascript ES 6 class 详解
- NDK与Cygwin配置
- 通过单例模式去加载可配置的常量
- 与、或、非、异或、运算
- 刷机
- 使用redis避免客户端频繁提交数据
- bzoj 3312: [Usaco2013 Nov]No Change
- 设计模式C++实现(8)——代理模式