www.pudn.com > OpenGL实现三维绘图.rar > Test1View.cpp
// Test1View.cpp : implementation of the CTest1View class
//
#include "stdafx.h"
#include "Test1.h"
#include "Test1Doc.h"
#include "Test1View.h"
#include "MainFrm.h"
#include "ControlWnd.h"
#include "ProjectView.h"
#include "math.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
GLfloat Databuf[ArrayOne][ArrayTwo];
GLfloat xrof,yrof,zrof;//各坐标轴倾角
/////////////////////////////////////////////////////////////////////////////
// CTest1View
extern bool gbIsGetData;
extern bool gbDataIsEmpty;
IMPLEMENT_DYNCREATE(CTest1View, CView)
BEGIN_MESSAGE_MAP(CTest1View, CView)
//{{AFX_MSG_MAP(CTest1View)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_SIZE()
ON_COMMAND(IDC_TURNX, OnTurnx)
ON_COMMAND(IDC_TURNY, OnTurny)
ON_COMMAND(IDC_TURNZ, OnTurnz)
ON_WM_ERASEBKGND()
ON_COMMAND(IDC_RESUME, OnResume)
ON_WM_MOUSEWHEEL()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_CONTEXTMENU()
ON_WM_KILLFOCUS()
//}}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()
/////////////////////////////////////////////////////////////////////////////
// CTest1View construction/destruction
CTest1View::CTest1View()
{
m_pDC = NULL;
nWithy = 0;
m_Prox = 60;
m_Proy = 5;
m_Proz = 10;
m_First = 1;
m_Second = 2;
m_Third = 3;
m_bDown = false;
m_bIsMove = true;
m_bGetFileSuccess = true;
m_pFr = NULL;
m_FileName = "data/t56a.3DSF";
m_nMinDepth = 520.00f;
m_nMaxDepth = 3299.875 ;
m_bMoveSel = false;
m_SelType = 0;
m_Zoom = 0;
m_xMove = m_yMove = m_zMove = 0;
m_bLighting = false;
}
CTest1View::~CTest1View()
{
if (m_pDC)
{
delete m_pDC;
m_pDC = NULL;
}
}
BOOL CTest1View::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CTest1View drawing
void CTest1View::OnDraw(CDC* pDC)
{
CTest1Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
//清除颜色缓冲和深度缓冲
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//用单位矩阵替换当前矩阵
glLoadIdentity();
//旋转角度
glRotatef(xrof,1.0f,0.0f,0.0f);//x轴
glRotatef(yrof,0.0f,1.0f,0.0f);//y轴
glRotatef(zrof,0.0f,0.0f,1.0f);//z轴
//选择框
if( this->m_pFr->m_pCtrlWnd->m_bShowConsult)
this->Draw3DRect();
//画点
this->PutPoint();
//坐标系和文字
if (this->m_pFr->m_pCtrlWnd->m_bShowCoordinate)
{
this->DrawLines();
this->DrawText();
}
//强制绘图完成
glFinish();
//交换缓冲区数据
SwapBuffers(wglGetCurrentDC());
//画选中区域
this->DrawSelArea(pDC);
}
/////////////////////////////////////////////////////////////////////////////
// CTest1View printing
BOOL CTest1View::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CTest1View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CTest1View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CTest1View diagnostics
#ifdef _DEBUG
void CTest1View::AssertValid() const
{
CView::AssertValid();
}
void CTest1View::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CTest1Doc* CTest1View::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTest1Doc)));
return (CTest1Doc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CTest1View message handlers
int CTest1View::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
return 0;
}
//在此释放OpenGL使用的设备环境
void CTest1View::OnDestroy()
{
CView::OnDestroy();
HGLRC hrc;
hrc = ::wglGetCurrentContext();
::wglMakeCurrent(NULL, NULL);
if (hrc)
::wglDeleteContext(hrc);
}
//设置视口
void CTest1View::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
SetViewPort(cx,cy);
}
void CTest1View::SetViewPort(int cx, int cy)
{
this->m_xRect = cx;
this->m_yRect = cy;
//避免除数为0
if(m_yRect==0)
m_yRect=1;
glViewport(0,0,m_xRect,m_yRect);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(m_xRect>=m_yRect)
{
glOrtho(-20.0,20.0,-20.0*(GLfloat)m_yRect/(GLfloat)m_xRect, 20.0*(GLfloat)m_yRect/(GLfloat)m_xRect,-50.0,50.0);
}
else
{
glOrtho(-20.0*(GLfloat)m_xRect/(GLfloat)m_yRect,20.0*(GLfloat)m_xRect/(GLfloat)m_yRect,-20.0,20.0,-50.0,50.0);
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
//从文件中读取数据
bool CTest1View::GetFileData(CString filename)
{
::gbIsGetData = true;
::gbDataIsEmpty = true;
::SendMessage(this->m_pFr->m_pCtrlWnd->m_hWnd,MESSAGE_DISABLEBTN,0,0);
this->ZeroArray();
this->m_pFr->InvalidateAllWnd();//Invalidate();
FILE *stream;
GLfloat Num;
if( (stream = fopen( filename, "r+t" )) != NULL )
{
int n = 0,m = 0;
for (int i=0; im_pFr->m_hWnd,MESSAGE_STEPPRO,m,0);
n = 0;
}
n++;
for(int j=0; jm_pFr->m_pCtrlWnd->m_hWnd,MESSAGE_ENABLEBTN,0,0);
::SendMessage(this->m_pFr->m_pCtrlWnd->m_hWnd,MESSAGE_GETDATAFINISHED,0,0);
}
else
m_bGetFileSuccess = false;
return m_bGetFileSuccess;
}
//设置适于OpenGL使用的像素格式
bool CTest1View::bSetPixelFormat()
{
//定义一种像素格式
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
1, // version number
PFD_DRAW_TO_WINDOW |// support window
PFD_SUPPORT_OPENGL | // support OpenGL 支持OpenGL
PFD_DOUBLEBUFFER, // double buffered 支持又缓冲
PFD_TYPE_RGBA, // RGBA type使用RGBA模式,不用调色板
24, // 24-bit color depth 使用24位真彩色
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 32位Z轴缓冲
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)) == FALSE )
{
AfxMessageBox("ChoosePixelFormat failed");
return false;
}
//用上面取到的格式设置设备环境
if (SetPixelFormat(m_pDC->GetSafeHdc(), pixelformat, &pfd) == FALSE)
{
AfxMessageBox("SetPixelFormat failed");
return false;
}
return true;
}
//初始化OpenGL环境
void CTest1View::IniOpenGL()
{
m_pDC = new CClientDC(this);
PIXELFORMATDESCRIPTOR pfd;
int n;
//定义一个绘制上下文的句柄
HGLRC hrc;
//初始化过程中主要就是初始化了一个客户区的设备环境指针
ASSERT(m_pDC != NULL);
//建立应用所需的像素格式,并与当前设备上下文相关连
if (!bSetPixelFormat())
return;
//得到指定设备环境的象素模式索引
n = ::GetPixelFormat(m_pDC->GetSafeHdc());
//根据上面得到的索引值来声明一个象素模式
::DescribePixelFormat(m_pDC->GetSafeHdc(), n, sizeof(pfd), &pfd);
//创建一个上下文设备环境
hrc = wglCreateContext(m_pDC->GetSafeHdc());
//将刚生成的设备上下文指针设为当前环境
wglMakeCurrent(m_pDC->GetSafeHdc(), hrc);
//置黑背景
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glShadeModel(GL_SMOOTH);
// 设置混色函数取得半透明效果
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
glEnable(GL_BLEND);
//平滑线条
glEnable (GL_LINE_SMOOTH);
glEnable (GL_BLEND);
//初始化反走样为 RGBA 模式,同时包括 alpha 混合、提示的设置
// glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// glEnable (GL_BLEND);
// 真正精细的透视修正
// glHint (GL_POLYGON_SMOOTH_HINT|GL_LINE_SMOOTH_HINT, GL_NICEST);
//充许深度测试
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
}
//设为绕X轴旋转
void CTest1View::OnTurnx()
{
nWithy = 0;
CButton *btn = (CButton*)this->m_pFr->m_pCtrlWnd->GetDlgItem(IDC_RADIOTURNX);
btn->SetCheck(1);
btn = (CButton*)this->m_pFr->m_pCtrlWnd->GetDlgItem(IDC_RADIOTURNY);
btn->SetCheck(0);
btn = (CButton*)this->m_pFr->m_pCtrlWnd->GetDlgItem(IDC_RADIOTURNZ);
btn->SetCheck(0);
}
//设为绕Y轴旋转
void CTest1View::OnTurny()
{
nWithy = 1;
CButton *btn = (CButton*)this->m_pFr->m_pCtrlWnd->GetDlgItem(IDC_RADIOTURNX);
btn->SetCheck(0);
btn = (CButton*)this->m_pFr->m_pCtrlWnd->GetDlgItem(IDC_RADIOTURNY);
btn->SetCheck(1);
btn = (CButton*)this->m_pFr->m_pCtrlWnd->GetDlgItem(IDC_RADIOTURNZ);
btn->SetCheck(0);
}
//设为绕Z轴旋转
void CTest1View::OnTurnz()
{
nWithy = 2;
CButton *btn = (CButton*)this->m_pFr->m_pCtrlWnd->GetDlgItem(IDC_RADIOTURNX);
btn->SetCheck(0);
btn = (CButton*)this->m_pFr->m_pCtrlWnd->GetDlgItem(IDC_RADIOTURNY);
btn->SetCheck(0);
btn = (CButton*)this->m_pFr->m_pCtrlWnd->GetDlgItem(IDC_RADIOTURNZ);
btn->SetCheck(1);
}
//不重画背景
BOOL CTest1View::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
void CTest1View::OnResume()
{
xrof = 0;
yrof = 0;
zrof = 0;
m_Prox = 60;
m_Proy = 5;
m_Proz = 10;
this->m_pFr->InvalidateAllWnd();
}
//处理鼠标滚轴消息
BOOL CTest1View::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
if (this->m_bIsMove)
{
switch (nWithy)
{
case 0:
{
xrof -= zDelta/20;
if (xrof > -360 || xrof < 360)
xrof = ::xrof;
else
xrof = (int)xrof%360;
}
break;
case 1:
{
yrof -= zDelta/20;
if (yrof >= -360 || yrof < 360)
yrof = ::yrof;
else
yrof = (int)yrof%360;
}
break;
case 2:
{
zrof -= zDelta/20;
if (zrof >=-360 || zrof< 360)
zrof = ::zrof;
else
zrof = (int)zrof%360;
}
break;
default:
break;
}
::SendMessage(this->m_pFr->m_pProView->m_hWnd, MESSAGE_ANGLECHANGING, 0, 0);
this->Invalidate();
}
return CView::OnMouseWheel(nFlags, zDelta, pt);
}
//画坐标系
void CTest1View::DrawLines()
{
//Draw Lines
glBegin(GL_LINES);
//X
glColor3f(0.0f,1.0f,0.0f);
glVertex3f(-10.0f-m_Zoom,0.0f,0.0f);
glVertex3f(10.0f+m_Zoom,0.0f,0.0f);
//Arrow
glVertex3f(9.60f+m_Zoom,0.3f,0.0f);
glVertex3f(10.0f+m_Zoom,0.0f,0.0f);
glVertex3f(9.60f+m_Zoom,-0.3f,0.0f);
glVertex3f(10.0f+m_Zoom,0.0f,0.0f);
glVertex3f(9.60f+m_Zoom,0.0f,0.3f);
glVertex3f(10.0f+m_Zoom,0.0f,0.0f);
glVertex3f(9.60f+m_Zoom,0.0f,-0.3f);
glVertex3f(10.0f+m_Zoom,0.0f,0.0f);
//Y
glColor3f(1.0f,0.0f,0.0f);
glVertex3f(0.0f,-10.0f-m_Zoom,0.0f);
glVertex3f(0.0f,10.0f+m_Zoom,0.0f);
//Arrow
glVertex3f(-0.3f,9.6f+m_Zoom,0.0f);
glVertex3f(0.0f,10.0f+m_Zoom,0.0f);
glVertex3f(0.3f,9.6F+m_Zoom,0.0f);
glVertex3f(0.0f,10.0f+m_Zoom,0.0f);
glVertex3f(0.0f,9.6f+m_Zoom,-0.3f);
glVertex3f(0.0f,10.0f+m_Zoom,0.0f);
glVertex3f(0.0f,9.6F+m_Zoom,0.3f);
glVertex3f(0.0f,10.0f+m_Zoom,0.0f);
//Z
glColor3f(0.0f,0.0f,1.0f);
glVertex3f(0.0f,0.0f,-10.0f-m_Zoom);
glVertex3f(0.0f,0.0f,10.0f+m_Zoom);
//Arrow
glVertex3f(0.3f,0.0f,9.60f+m_Zoom);
glVertex3f(0.0f,0.0f,10.0f+m_Zoom);
glVertex3f(-0.3f,0.0f,9.60f+m_Zoom);
glVertex3f(0.0f,0.0f,10.0f+m_Zoom);
glVertex3f(0.0f,0.3f,9.60f+m_Zoom);
glVertex3f(0.0f,0.0f,10.0f+m_Zoom);
glVertex3f(0.0f,-0.3f,9.60f+m_Zoom);
glVertex3f(0.0f,0.0f,10.0f+m_Zoom);
glEnd();
glBegin(GL_POINTS);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(6.5f,0.0f,0.0f);
glVertex3f(-6.5f,0.0f,0.0f);
glVertex3f(0.0f,6.5f,0.0f);
glVertex3f(0.0f,-6.5f,0.0f);
glVertex3f(0.0f,0.0f,6.5f);
glVertex3f(0.0f,0.0f,-6.5f);
glEnd();
}
//画点
void CTest1View::PutPoint()
{
if (::gbIsGetData)
return;
if (::gbDataIsEmpty)
return;
//为了将点移到坐标中间向各个方向平移坐标系
glTranslatef(-5.0f/*-m_Zoom*/,0.0f,0.0f);
glTranslatef(0.0f,-5.0f-2*m_Zoom,0.0f);
glTranslatef(0.0f,0.0f,-22.0f-2*m_Zoom);
//Put Points
glBegin(GL_POINTS);
for (int i=0; i= this->m_nMinDepth && (GLfloat)Databuf[i][0] <= this->m_nMaxDepth )
glVertex3f((GLfloat)(Databuf[i][m_First]/(m_Prox-m_Zoom)),
(GLfloat)(Databuf[i][m_Second]/(m_Proy-m_Zoom)),
(GLfloat)(Databuf[i][m_Third]*(m_Proz+m_Zoom)));
}
glEnd();
//将坐标系移回原点
glTranslatef(5.0f/*+m_Zoom*/,0.0f,0.0f);
glTranslatef(0.0f,5.0f+2*m_Zoom,0.0f);
glTranslatef(0.0f,0.0f,22.0f+2*m_Zoom);
}
//将取到的数据进行重新排序,当前系统中没有调用该函数
void CTest1View::ResortData()
{
//重排声波
GLfloat t;
for(int j=0;jDatabuf[i+1][1])
{
t = Databuf[i][1];
Databuf[i][1] = Databuf[i+1][1];
Databuf[i+1][1] = t;
}
}
}
//重排中子
for( j=0;jDatabuf[i+1][2])
{
t = Databuf[i][2];
Databuf[i][2] = Databuf[i+1][2];
Databuf[i+1][2] = t;
}
}
}
//重排密度
for( j=0;jDatabuf[i+1][3])
{
t = Databuf[i][3];
Databuf[i][3] = Databuf[i+1][3];
Databuf[i+1][3] = t;
}
}
}
}
void CTest1View::OnLButtonDown(UINT nFlags, CPoint point)
{
this->m_bDown = true;
this->m_xM = point.x;
this->m_yM = point.y;
m_MouseDown = point;
CView::OnLButtonDown(nFlags, point);
}
void CTest1View::OnLButtonUp(UINT nFlags, CPoint point)
{
this->m_bDown = false;
CRect rect = m_SelRect;
rect.left = rect.left+5;
rect.top = rect.top+64;
rect.bottom = rect.bottom+62;
//将选中的区域做成位图
m_hBmp = CopySelArearToBitmap(rect);
::SendMessage(this->m_pFr->m_pProView->m_hWnd,MESSAGE_BMPHASBECOPIED,0,0);
CView::OnLButtonUp(nFlags, point);
}
void CTest1View::OnMouseMove(UINT nFlags, CPoint point)
{
if (!m_bDown)
return;
m_MouseMove = point;
if (!this->IsMouseInWndRect(point))
this->m_bDown = false;
if (this->m_bIsMove )
{
m_bMoveSel = false;
//设置一个范围,保证能正常的上下或左右转动坐标系5个像素
if (this->m_yM - point.y > 5 || this->m_yM - point.y < -5)
::xrof = xrof - (this->m_yM - point.y)/20;
if (::xrof >=-360 || ::xrof< 360)
::xrof = ::xrof;
else
::xrof = (int)::xrof%360;
if ( this->m_xM - point.x > 5 || this->m_xM - point.x < -5 )
::yrof = yrof - (this->m_xM - point.x)/20;
if (::yrof > -360 || ::yrof< 360)
::yrof = ::yrof;
else
::yrof = (int)::yrof%360;
::SendMessage(this->m_pFr->m_pProView->m_hWnd, MESSAGE_ANGLECHANGING, 0, 0);
this->Invalidate();
}
else
{
m_bMoveSel = true;
m_SelRect = CRect(m_MouseDown, m_MouseMove);
this->Invalidate();
}
CView::OnMouseMove(nFlags, point);
}
void CTest1View::ZeroArray()
{
for (int i=0; iGetFileData(pThis->m_FileName);
return 0L;
}
void CTest1View::OnInitialUpdate()
{
CView::OnInitialUpdate();
m_pFr = (CMainFrame*)AfxGetApp()->m_pMainWnd;
this->IniOpenGL();
//启动加载数据的线程
// AfxBeginThread(CTest1View::ReadFile,this);
}
//判断当前鼠标是否在客户区中
bool CTest1View::IsMouseInWndRect(CPoint point)
{
bool bInWnd = true;
if ( point.x <= 10 || point.x >= this->m_xRect-10 || point.y <= 10 || point.y >= this->m_yRect-10 )
bInWnd = false;
return bInWnd;
}
GLfloat CTest1View::GetMaxDepth()
{
GLfloat glfMaxDepth = 0.0f;
glfMaxDepth = Databuf[0][0];
for(int i=0; i= glfMaxDepth)
{
glfMaxDepth = Databuf[i][0];
}
else
NULL;
}
return glfMaxDepth;
}
GLfloat CTest1View::GetMinDepth()
{
GLfloat glfMinDepth = 0.0f;
glfMinDepth = Databuf[0][0];
for(int i=0; im_bMoveSel)
{
if (this->m_SelType == 0)
{
pDC->Draw3dRect(this->m_SelRect,BLUE,BLUE);
//pDC->InvertRect(this->m_SelRect);
}
if (this->m_SelType == 1)
pDC->Ellipse(this->m_SelRect);
}
}
void CTest1View::DrawText()
{
glPushMatrix();
glColor3f(1.0f,1.0f,1.0f);
wglUseFontBitmaps(wglGetCurrentDC(),0,255,100);
glListBase(100);
glRasterPos3f(10.20f+m_Zoom,-0.5f,0.0f);
glCallLists(2,GL_UNSIGNED_BYTE,_T("+x"));
glRasterPos3f(-0.5,10.2f+m_Zoom,0.0f);
glCallLists(2,GL_UNSIGNED_BYTE,_T("+y"));
glRasterPos3f(-0.5,0.0f,10.2f+m_Zoom);
glCallLists(2,GL_UNSIGNED_BYTE,_T("+z"));
glRasterPos3f(0.0,0.0f,0.0f);
glCallLists(6,GL_UNSIGNED_BYTE,_T("Center"));
glPopMatrix();
}
//画参照立方体
void CTest1View::Draw3DRect()
{
//特别注意该函数
glColor3f(1.0f,1.0f,1.0f);
//加入光照
glEnable (GL_LIGHTING);
glEnable(GL_LIGHT0);
glPushMatrix ();
//设置立方体大小
auxWireCube(13.0+m_Zoom);
//取消光照
if (!m_bLighting)
{
glDisable(GL_LIGHTING);
glDisable(GL_LIGHT0);
}
//将当前矩阵出栈
glPopMatrix ();
}
void CTest1View::OnContextMenu(CWnd* pWnd, CPoint point)
{
CMenu m_XpMenu;
//电话本
m_XpMenu.LoadMenu(IDR_MYMENU);
CMenu *psub = (CMenu *)m_XpMenu.GetSubMenu(0);
psub->TrackPopupMenu(TPM_LEFTALIGN,point.x,point.y,this);
m_XpMenu.DestroyMenu();
}
//lpRect 代表选定区域
HBITMAP CTest1View::CopySelArearToBitmap(LPRECT lpRect)
{
HDC hScrDC, hMemDC;
// 屏幕和内存设备描述表
HBITMAP hBitmap, hOldBitmap;
// 位图句柄
int nX, nY, nX2, nY2;
// 选定区域坐标
int nWidth, nHeight;
// 位图宽度和高度
int xScrn, yScrn;
// 屏幕分辨率
// 确保选定区域不为空矩形
if (IsRectEmpty(lpRect))
return NULL;
//为屏幕创建设备描述表
hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
//为屏幕设备描述表创建兼容的内存设备描述表
hMemDC = CreateCompatibleDC(hScrDC);
// 获得选定区域坐标
nX = lpRect->left;
nY = lpRect->top;
nX2 = lpRect->right;
nY2 = lpRect->bottom;
// 获得屏幕分辨率
xScrn = GetDeviceCaps(hScrDC, HORZRES);
yScrn = GetDeviceCaps(hScrDC, VERTRES);
//确保选定区域是可见的
if (nX < 0)
nX = 0;
if (nY < 0)
nY = 0;
if (nX2 > xScrn)
nX2 = xScrn;
if (nY2 > yScrn)
nY2 = yScrn;
nWidth = (nX2 - nX);
nHeight = (nY2 - nY);
//创建一个与屏幕设备描述表兼容的位图
hBitmap = CreateCompatibleBitmap(hScrDC, nWidth, nHeight);
//把新位图选到内存设备描述表中
hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
// 把屏幕设备描述表拷贝到内存设备描述表中
BitBlt(hMemDC, 0, 0, nWidth, nHeight,hScrDC, nX, nY, SRCCOPY);
//得到屏幕位图的句柄
hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);
//清除
DeleteDC(hScrDC);
DeleteDC(hMemDC);
// 返回位图句柄
return hBitmap;
}
//将选中区域保存成位图
BOOL CTest1View::SaveBitmapToFile(HBITMAP hBitmap, LPSTR lpFileName)
{
//lpFileName 为位图文件名
HDC hDC;
//设备描述表
int iBits;
//当前显示分辨率下每个像素所占字节数
WORD wBitCount;
//位图中每个像素所占字节数
//定义调色板大小, 位图中像素字节大小 ,位图文件大小 , 写入文件字节数
DWORD dwPaletteSize=0, dwBmBitsSize, dwDIBSize, dwWritten;
BITMAP Bitmap;
//位图属性结构
BITMAPFILEHEADER bmfHdr;
//位图文件头结构
BITMAPINFOHEADER bi;
//位图信息头结构
LPBITMAPINFOHEADER lpbi;
//指向位图信息头结构
HANDLE fh, hDib, hPal,hOldPal=NULL;
//定义文件,分配内存句柄,调色板句柄
//计算位图文件每个像素所占字节数
hDC = CreateDC("DISPLAY",NULL,NULL,NULL);
iBits = GetDeviceCaps(hDC, BITSPIXEL) *
GetDeviceCaps(hDC, PLANES);
DeleteDC(hDC);
if (iBits <= 1)
wBitCount = 1;
else if (iBits <= 4)
wBitCount = 4;
else if (iBits <= 8)
wBitCount = 8;
else if (iBits <= 24)
wBitCount = 24;
//计算调色板大小
if (wBitCount <= 8)
dwPaletteSize = (1 << wBitCount) * sizeof(RGBQUAD);
//设置位图信息头结构
GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = Bitmap.bmWidth;
bi.biHeight = Bitmap.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = wBitCount;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
dwBmBitsSize = ((Bitmap.bmWidth *
wBitCount+31)/32)* 4
*Bitmap.bmHeight ;
//为位图内容分配内存
hDib = GlobalAlloc(GHND,dwBmBitsSize+
dwPaletteSize+sizeof(BITMAPINFOHEADER));
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
*lpbi = bi;
// 处理调色板
hPal = GetStockObject(DEFAULT_PALETTE);
if (hPal)
{
hDC = ::GetDC(NULL);
hOldPal = SelectPalette(hDC, (HPALETTE)hPal, FALSE);
RealizePalette(hDC);
}
// 获取该调色板下新的像素值
GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight,
(LPSTR)lpbi + sizeof(BITMAPINFOHEADER) +dwPaletteSize,
(BITMAPINFO *)lpbi, DIB_RGB_COLORS);
//恢复调色板
if (hOldPal)
{
SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);
RealizePalette(hDC);
::ReleaseDC(NULL, hDC);
}
//创建位图文件
fh = CreateFile(lpFileName, GENERIC_WRITE,
0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (fh == INVALID_HANDLE_VALUE)
return FALSE;
// 设置位图文件头
bmfHdr.bfType = 0x4D42; // "BM"
dwDIBSize = sizeof(BITMAPFILEHEADER)
+ sizeof(BITMAPINFOHEADER)
+ dwPaletteSize + dwBmBitsSize;
bmfHdr.bfSize = dwDIBSize;
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
bmfHdr.bfOffBits = (DWORD)sizeof
(BITMAPFILEHEADER)
+ (DWORD)sizeof(BITMAPINFOHEADER)
+ dwPaletteSize;
// 写入位图文件头
WriteFile(fh, (LPSTR)&bmfHdr, sizeof
(BITMAPFILEHEADER), &dwWritten, NULL);
// 写入位图文件其余内容
WriteFile(fh, (LPSTR)lpbi, dwDIBSize,
&dwWritten, NULL);
//清除
GlobalUnlock(hDib);
GlobalFree(hDib);
CloseHandle(fh);
return TRUE;
}
void CTest1View::OnKillFocus(CWnd* pNewWnd)
{
CView::OnKillFocus(pNewWnd);
this->m_bDown = false;
}
GLfloat CTest1View::GetMidXPoint()
{
GLfloat glMid,glMin,glMax;
glMax = glMin = glMid =Databuf[0][1];
for(int i=0; i glMax)
glMax = Databuf[i][1];
if (Databuf[i][1] < glMin)
glMin = Databuf[i][1];
}
if (glMax < 0.0f)
glMax = -glMax;
if (glMin > 0.0f)
glMin = -glMin;
return (glMax + glMin)/2;
}
GLfloat CTest1View::GetMidYPoint()
{
GLfloat glMid,glMin,glMax;
glMax = glMin = glMid =Databuf[0][2];
for(int i=0; i glMax)
glMax = Databuf[i][2];
if (Databuf[i][2] < glMin)
glMin = Databuf[i][2];
}
if (glMax < 0.0f)
glMax = -glMax;
if (glMin > 0.0f)
glMin = -glMin;
return (glMax + glMin)/2;
}
GLfloat CTest1View::GetMidZPoint()
{
GLfloat glMid,glMin,glMax;
glMax = glMin = glMid =Databuf[0][3];
for(int i=0; i glMax)
glMax = Databuf[i][3];
if (Databuf[i][3] < glMin)
glMin = Databuf[i][3];
}
if (glMax < 0.0f)
glMax = -glMax;
if (glMin > 0.0f)
glMin = -glMin;
return (glMax + glMin)/2;
}
bool CTest1View::IsMouseinSelRect(CRect rect,CPoint point)
{
bool bIn = false;
int cx = point.x;
int cy = point.y;
if (cx >= rect.left && cx <= rect.right && cy >= rect.top && cy <= rect.bottom)
bIn = true;
return bIn;
}