📄 displaybitmapinsdiview.cpp
字号:
// DisplayBitmapInSDIView.cpp : implementation of the CDisplayBitmapInSDIView class
//
#include "stdafx.h"
#include "DisplayBitmapInSDI.h"
#include "DisplayBitmapInSDIDoc.h"
#include "DisplayBitmapInSDIView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDisplayBitmapInSDIView
IMPLEMENT_DYNCREATE(CDisplayBitmapInSDIView, CView)
BEGIN_MESSAGE_MAP(CDisplayBitmapInSDIView, CView)
//{{AFX_MSG_MAP(CDisplayBitmapInSDIView)
// NOTE - the ClassWizard will add and remove mapping macros here.
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_SIZE()
ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDisplayBitmapInSDIView construction/destruction
CDisplayBitmapInSDIView::CDisplayBitmapInSDIView()
{
// TODO: add construction code here
m_pImage = NULL;
m_pImageBack = NULL;
m_bIsFirstStart = TRUE;
}
CDisplayBitmapInSDIView::~CDisplayBitmapInSDIView()
{
if (m_pImage!=NULL)
{
delete[] m_pImage;
}
if (m_pImageBack!=NULL)
{
delete[] m_pImageBack->data;
delete m_pImageBack;
}
}
BOOL CDisplayBitmapInSDIView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CDisplayBitmapInSDIView drawing
void CDisplayBitmapInSDIView::OnDraw(CDC* pDC)
{
CDisplayBitmapInSDIDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
// 显示程序的功能及使用说明信息
pDC->SetBkColor(RGB(0,0,0));
pDC->SetTextColor(RGB(0,255,0));
pDC->TextOut(350, 10, _T("本程序的功能:在SDI中显示位图。"));
pDC->SetBkColor(RGB(255,255,255));
pDC->SetTextColor(RGB(255,0,0));
pDC->TextOut(350, 40, _T("使用说明:你可以点击打开菜单,选择别的位图来显示。"));
if (m_bIsFirstStart)
{
CBitmap bitmap; // 创建一个位图对象
CDC dcMemory;
bitmap.LoadBitmap(IDB_BITMAP_BLISS); // 设置位图内容
dcMemory.CreateCompatibleDC(pDC);
dcMemory.SelectObject(&bitmap);
// 显示位图
pDC->BitBlt(100,100,1024,768,&dcMemory,0,0,SRCCOPY);
m_bIsFirstStart = FALSE;
return;
}
if (!m_bIsFirstStart)
{
// 设置当前绘图设备为OpenGL的设备情景对象
if(m_hglrc)
{
wglMakeCurrent(m_pDC->GetSafeHdc(), m_hglrc);
}
else
{
return;
}
glDrawBuffer(GL_BACK);
// 初始化变换矩阵
glLoadIdentity();
// 清除背景颜色
glClearColor(1.0,1.0,1.0,1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (m_pImage != NULL)
{
// 指定在后台缓存中绘制
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
if(m_nImgWidth>m_iViewWidth && m_nImgHeight>m_iViewHeight)
{
// 根据视口和位图的大小来调整位图的缩放比例,使位图能充满整个视口
glPixelZoom(float(m_iViewWidth)/m_nImgWidth,
float(m_iViewHeight)/m_nImgHeight);
// 指定位图的绘制位置
glRasterPos2i(0,0);
}
else
{
// 按照位图的原始大小输出
glPixelZoom(1,1);
// 指定位图的绘制位置
glRasterPos2i((m_iViewWidth-m_nImgWidth)/2,
(m_iViewHeight-m_nImgHeight)/2);
}
glDrawPixels(m_nImgWidth,m_nImgHeight,GL_RGB,
GL_UNSIGNED_BYTE,m_pImage);
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
}
// 结束整个绘制
glFinish();
// 交换前后缓存
SwapBuffers(wglGetCurrentDC());
// 绘制前景
glDrawBuffer(GL_FRONT);
}
}
/////////////////////////////////////////////////////////////////////////////
// CDisplayBitmapInSDIView printing
BOOL CDisplayBitmapInSDIView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CDisplayBitmapInSDIView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CDisplayBitmapInSDIView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CDisplayBitmapInSDIView diagnostics
#ifdef _DEBUG
void CDisplayBitmapInSDIView::AssertValid() const
{
CView::AssertValid();
}
void CDisplayBitmapInSDIView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CDisplayBitmapInSDIDoc* CDisplayBitmapInSDIView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDisplayBitmapInSDIDoc)));
return (CDisplayBitmapInSDIDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CDisplayBitmapInSDIView message handlers
int CDisplayBitmapInSDIView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
int n;
m_pDC = new CClientDC(this);
ASSERT(m_pDC != NULL);
// 初始化像素格式
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
1, // version number
PFD_DRAW_TO_WINDOW | // support window
PFD_SUPPORT_OPENGL | // support OpenGL
PFD_DOUBLEBUFFER, // double buffered
PFD_TYPE_RGBA, // RGBA type
24, // 24-bit color depth
0, 0, 0, 0, 0, 0, // color bits ignored
0, // no alpha buffer
0, // shift bit ignored
0, // no accumulation buffer
0, 0, 0, 0, // accum bits ignored
32, // 32-bit z-buffer
0, // no stencil buffer
0, // no auxiliary buffer
PFD_MAIN_PLANE, // main layer
0, // reserved
0, 0, 0 // layer masks ignored
};
// 选择像素格式
int pixelformat;
if ((pixelformat = ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd)) == 0 )
{
MessageBox(_T("选择像素格式失败!"));
return -1;
}
// 设置像素格式
if (SetPixelFormat(m_pDC->GetSafeHdc(), pixelformat, &pfd) == FALSE)
{
MessageBox(_T("设置像素格式失败!"));
return -1;
}
n = ::GetPixelFormat(m_pDC->GetSafeHdc());
::DescribePixelFormat(m_pDC->GetSafeHdc(), n, sizeof(pfd), &pfd);
// 创建绘制情景对象
m_hglrc = wglCreateContext(m_pDC->GetSafeHdc());
// 选择绘制情景对象
wglMakeCurrent(m_pDC->GetSafeHdc(), m_hglrc);
return 0;
}
void CDisplayBitmapInSDIView::OnDestroy()
{
// TODO: Add your message handler code here
// 将当前绘图情景对象赋空
::wglMakeCurrent(NULL, NULL);
// 删除当前绘图情景对象并释放所占内存
if (m_hglrc)
{
::wglDeleteContext(m_hglrc);
}
if (m_pDC)
{
delete m_pDC;
}
CView::OnDestroy();
}
void CDisplayBitmapInSDIView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
// 设置当前绘图设备
if (m_hglrc)
{
wglMakeCurrent(m_pDC->GetSafeHdc(), m_hglrc);
}
else
{
return;
}
// 记录窗口大小
m_iViewWidth = cx;
m_iViewHeight = cy;
// 设置视口大小
glViewport(0,0,cx,cy);
// 设置变换模式为投影变换
glMatrixMode(GL_PROJECTION);
// 初始化投影变换矩阵
glLoadIdentity();
// 根据窗口大小设置调整正射投影矩阵
gluOrtho2D(0,m_iViewWidth,0,m_iViewHeight);
// 设置变换模式为模型变换
glMatrixMode(GL_MODELVIEW);
// 初始化模型变换矩阵
glLoadIdentity();
// 刷新绘图区
InvalidateRect(NULL,TRUE);
}
void CDisplayBitmapInSDIView::OnFileOpen()
{
// TODO: Add your command handler code here
static char BASED_CODE szFilter[] = _T("BMP位图文件(*.bmp)|*.bmp||");
CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter);
if (dlg.DoModal() == IDOK)
{
//先释放原来位图所占用的内存
if (m_pImageBack != NULL)
{
delete[] m_pImageBack->data;
delete m_pImageBack;
m_pImageBack = NULL;
}
if (m_pImage != NULL)
{
delete[] m_pImage;
}
// 读入位图文件
m_pImageBack = auxDIBImageLoad(dlg.GetPathName());
if (m_pImageBack == NULL)
{
return;
}
// 记录位图的大小
m_nImgWidth = m_pImageBack->sizeX;
m_nImgHeight = m_pImageBack->sizeY;
// 分配位图数据所占的内存
m_pImage = new BYTE[(2*m_nImgWidth)*(2*m_nImgHeight)*3];
// 将位图的数据按照1:1的比例传送到数组中
gluScaleImage(GL_RGB,m_pImageBack->sizeX,m_pImageBack->sizeY,
GL_UNSIGNED_BYTE,m_pImageBack->data,
m_nImgWidth,m_nImgHeight,GL_UNSIGNED_BYTE,m_pImage);
// 刷新屏幕
InvalidateRect(NULL,TRUE);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -