MFC-приложение - MFC AppWizard
Этот тип приложения обладает всеми достоинствами и недостатками WinAPI-приложения, рассмотренного выше, так как MFC - это библиотека классов С++, т.е. надстройка над WinAPI. Кто-нибудь, конечно, скажет, что приложение на плюсах немеряно большое, работает медленно и MFC для ленивых. В общем, тут у каждого свое мнение. Каждый по-своему прав. Тем не менее, я считаю, что для каждой задачи требуется свой инструмент. Где-то лучше использовать MFC, где-то WinAPI. Кричать, что первое или второе является незаменимым средством на все случаи жизни было бы неверным. У MFC есть свои особенности, отнести которые к достоинствам или недостаткам однозначно нельзя. В зависимости от решаемой задачи они идут в плюс или минус. Согласитесь, что глупо забивать сапожный гвоздь кувалдой или же скобу сапожным молотком.
Создаем проект:
- Запустите MSVisualC++6.0
- Щелкните меню File->New->MFC AppWizard(exe).
- Выберете каталог и имя проекта задайте mfc, щелкните OK.
- Step1: Поставьте переключатель на Single document, далее OK.
- Step3: Уберите флажок ActiveX Controls, далее OK.
- Щелкните Finish.
- Щелкните Build->Set Active Configuration и установите тип проекта MFC - Win32 Release
- Далее щелкаете Project->Settings->Link->Object/library modules: и добавьте туда opengl32.lib, glu32.lib и glaux.lib
В CMFCView объявите закрытую(private) переменную hGLRC типа HGLRC. Там же объявите функцию int SetWindowPixelFormat(HDC) и открытую(public) функцию display. Вот, что должно получиться:
class CMFCView : public CView { private: CClientDC *pdc; HGLRC hGLRC; int SetWindowPixelFormat(HDC); public: void display(); ...
Вставьте код этой функции в файл MFCView.cpp. Код возьмите из предыдущего раздела. Отредактируйте функцию CMFCView::PreCretaeWindow следующим образом:
BOOL CMFCView::PreCreateWindow(CREATESTRUCT& cs) { // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs cs.style |= (WS_CLIPCHILDREN | WS_CLIPSIBLINGS); return CView::PreCreateWindow(cs); }
Добавьте также функцию display сюда:
void CMFCView::display() { glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glTranslated(0.01,0,0); glColor3d(1,0,0); auxSolidSphere( 1 ); glFinish(); SwapBuffers(wglGetCurrentDC()); }
Теперь запустите View->Class Wizard и добавьте обработчик WM_CREATE,WM_DESTROY и WM_SIZE в класс CMFCView. Отредактируйте их следующим образом:
int CMFCView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CView::OnCreate(lpCreateStruct) == -1) return -1; pdc = new CClientDC(this); if(SetWindowPixelFormat(pdc->m_hDC)==FALSE) return -1; hGLRC = wglCreateContext(pdc->m_hDC); if(hGLRC == NULL) return -1; if(wglMakeCurrent(pdc->m_hDC, hGLRC)==FALSE) return -1; glEnable(GL_ALPHA_TEST); glEnable(GL_DEPTH_TEST); glEnable(GL_COLOR_MATERIAL); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); float pos[4] = {3,3,3,1}; float dir[3] = {-1,-1,-1}; glLightfv(GL_LIGHT0, GL_POSITION, pos); glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, dir); return 0; } void CMFCView::OnDestroy() { if(wglGetCurrentContext()!=NULL) wglMakeCurrent(NULL, NULL) ; if(hGLRC!=NULL) { wglDeleteContext(hGLRC); hGLRC = NULL; } delete pdc; CView::OnDestroy(); } void CMFCView::OnSize(UINT nType, int cx, int cy) { CView::OnSize(nType, cx, cy); glViewport(0,0,cx,cy); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); glOrtho(-5,5, -5,5, 2,12); gluLookAt( 0,0,5, 0,0,0, 0,1,0 ); glMatrixMode( GL_MODELVIEW ); }
Пояснения смотри в предыдущих разделах. В StdAfx.h включите заголовочные файлы, после строчки #include <afxext.h>
#include <gl/gl.h> #include <gl/glu.h> #include <gl/glaux.h>
Запустите еще раз Class Wizard и добавьте функцию OnIdle в класс CMFCApp. Эта функция вызывается всякий раз, когда очередь сообщений окна пуста. Отредактируйте ее:
BOOL CMFCApp::OnIdle(LONG lCount) { ( (CMFCView*) ((CMainFrame*)m_pMainWnd)->GetActiveView() )->display(); return 1;//CWinApp::OnIdle(lCount); }
Исходный файл смотрите . Исполняемый файл .