| 许多介绍OpenGL与MFC结合使用的文章中都指出,OpenGL只能使用在单文档应用程序中。 |
| 然而在应用中,有时希望对一个数据能用多种表现方式同时表示,用SDI应用程序就无 法实现这一需求;而用MDI应用,则可同时打开多个视图,每个视图中显示数据的不同属性。 |
| 2、正确的设备上下文(DC:Device Context)与绘制上下文(RC:Rendering Context)的 关联,每个视图管理着一个设备上下文,而绘制上下文在整个程序运行期间只有一个,因此必须正确关联,才能将绘制的场景正确显示在各个视图中。 |
| 下面以一个简单的实例(TestMdi)来说明这两点。该例子的功能是对打开的视图进行计 数,在奇数号的视图中显示一个圆,偶数号的视图中显示一个正方形。计数器m_iCount定义 在应用程序类CTestMdiApp中,初始化为0。因为应用程序类管理整个程序,包括程序的初始 化,所以全局数据应该定义在这里。CTestMdiApp中还需要增加一个消息响应函数OnFileNew(): |
| void CTestMdiApp::OnFileNew() |
| 这是由MFC的消息处理机制将消息按CView- >CDoc- >CMainFrame- >CWndApp的顺序依次发送给各 对象,由第一个有对就消息响应的对象来处理。OnFileNew()在CWndApp中的实现是生成新的文 档,该例中文档类没有自己的变量,在实际应用中通常是有一些控制视图属性的参数。 |
| 对视图对象CTestMdiView进行如下的改变: |
| int m_iID; 视图ID,该应用中创建的第几个视图; |
| 2) 对OnCreate(LPCREATESTRUCT lpCreateStruct)进行修改: |
| int CTestmdiView::OnCreate |
| (LPCREATESTRUCT lpCreateStruct) |
| // TODO: Add your specialized creation code here |
| // OpenGL rendering context creation |
| PIXELFORMATDESCRIPTOR pfd; |
| // initialize the private member |
| m_pCDC= new CClientDC(this); |
| // bSetupPixelFormat()建立应用所需的像素格式, |
| if (!bSetupPixelFormat()) return 0; |
| n=::GetPixelFormat(m_pCDC- >GetSafeHdc()); |
| ::DescribePixelFormat(m_pCDC- > |
| GetSafeHdc(),n,sizeof(pfd),&pfd); |
| // link the Win Device Context |
| with the OGL Rendering Context |
| // specify the target DeviceContext (window) |
| of the subsequent OGL calls |
| wglMakeCurrent(m_pCDC- >GetSafeHdc(), m_hRC); |
| //注意:在SDI应用中不需要此名,而对MDI则必不可少 |
| wglMakeCurrent(NULL,NULL); |
| CTestmdiApp *pApp=(CTestmdiApp*)AfxGetApp(); |
| void CTestmdiView::OnDestroy() |
| wglMakeCurrent(m_pCDC- >GetSafeHdc(), m_hRC); |
| ::wglDeleteContext(m_hRC); |
| // destroy Win Device Context |
| void CTestmdiView::OnDraw() |
| wglMakeCurrent(m_pCDC- >GetSafeHdc(), m_hRC); |
| if (pApp- >m_iCount%2==0) |
| wglMakeCurrent(NULL, NULL); |
| 5)PreCreateWindow(CREATESTRUCT &cs)函数: |
| BOOL CTestmdiView::PreCreateWindow(CREATESTRUCT& cs) |
| // TODO: Modify the Window |
| class or styles here by modifying |
| cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN; |
| cs.lpszClass = AfxRegisterWndClass(CS_OWNDC | |
| CS_HREDRAW | CS_VREDRAW); |
| return CView::PreCreateWindow(cs); |
|