Chapter 7
Инициализация или как написать приложение с нуля
7.4 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);
}
Исходный файл смотрите здесь.
Исполняемый файл здесь.
|