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

📄 displaybitmapinsdiview.cpp

📁 VisualC高级编程技术精粹.rar
💻 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 + -