Управление с помощью объекта класса-оболочки
#include "stdafx.h" #include "TestGL.h" #include "TestGLDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = _FILE_; #endif //====== Пустое тело конструктора CTestGLDlg::CTestGLDlg(CWnd* p): CDialog(CTestGLDlg::IDD, p){} void CTestGLDlg::DoDataExchange(CDataExchange* pDX) { //====== Связывание переменной с элементом DDX_Control(pDX, IDCJDPENGL, m_CTRL); CDialog::DoDataExchange(pDX); } //====== Здесь мы убрали ON_WM_PAINT и т. д. BEGIN_MESSAGE_MAP(CTestGLDlg, CDialog) ON_WM_SYSCOMMAND() // } } AFX_MSG_MAP ON_CBN_SELCHANGE(IDC_FILL, OnSelchangeFill) ON_BN_CLICKED(IDC_FILENAME, OnClickedFilename) ON_WM_HSCROLL() ON_BN_CLICKED(IDC_BKCLR, OnClickedBkclr) ON_BN_CLICKED(IDC_QUADS, OnClickedQuads) ON_BN_CLICKED(IDC_STRIPS, OnClickedStrips) END_MESSAGE_MAP() //===== CTestGLDlg message handlers BOOL CTestGLDlg::OnInitDialog() { //====== Добываем адрес меню управления окном CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu) { //====== Добавляем команду About pSysMenu › AppendMenu(MF_SEPARATOR); pSysMenu › AppendMenu(MF_STRING, IDM_ABOUTBOX,"About…"); } //====== Загружаем стандартный значок HICON hMylcon =::LoadIcon(0,(char*)IDI_WINLOGO); Setlcon(hMylcon, TRUE); // Set big icon Setlcon(hMylcon, FALSE); // Set small icon CDialog::OnInitDialog(); //====== Начальная установка элементов CComboBox *pBox = (CComboBox*)GetDlgltem(IDC_FILL); pBox › AddString("Points"); pBox › AddString("Lines"); pBox › AddString("Fill"); pBox › SetCurSel (2); //==== Выясняем состояние режима изображения полигонов m_CTRL.GetQuad(&m_bQuads); WPARAM w = m_bQuads? BST_CHECKED: BST_UNCHECKED; //===== Устанавливаем состояние переключателя GetDlgltem(IDC_QUADS) › SendMessage(BM_SETCHECK, w, 0); w = m_bQuads? BST_UNCHECKED: BST_CHECKED; GetDlgltem(IDC_STRIPS) › SendMessage(BM_SETCHECK, w, 0); return TRUE; } void CTestGLDlg::OnSysCommand(UINT nID, LPARAM iParam) { if ((nID S OxFFFO) == IDM_ABOUTBOX) { CDialog(IDD_ABOUTBOX).DoModal(); } else { CDialog::OnSysCommand(nID, IParam); } } //====== Выбор из списка типа Combo-box void CTestGLDlg::OnSelchangeFill(void) "'* { DWORD sel = ((CComboBox*)GetDlgltem(IDC_FILL)) › GetCurSel(); sel = sel==0? GL_POINT: sel==l? GL_LINE : GL_FILL; m_CTRL.SetFillMode(sel); } //==== Нажатие на кнопку запуска файлового диалога void CTestGLDlg::OnClickedFilename(void) { m_CTRL.ReadData(); } //====== Реакция на сдвиг ползунка void CTestGLDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { //====== Выясняем текущую позицию, которая не во //====== всех случаях отражена в параметре nPos nPos = ((CSliderCTRL*)GetDlgItem(IDC_XPOS)) › GetPos(); m_CTRL.SetLightParam (0, nPos); } //====== Запускаем стандартный диалог void CTestGLDlg::OnClickedBkclr(void) { DWORD clr = m_CTRL.GetFillColor(); CColorDialog dig (clr); dig.m_cc.Flags |= CC_FULLOPEN; if (dlg.DoModal()==IDOK) { m_CTRL.SetFillColor(dlg.m_cc.rgbResult); } } //====== Запоминаем текущее состояние и //====== вызываем метод сервера void CTestGLDlg::OnClickedQuads(void) { m_CTRL.SetQuad(m_bQuads = TRUE); } void CTestGLDlg::OnClickedStrips(void) { m_CTRL.SetQuad(m_bQuads = FALSE); }
В настоящий момент вы можете запустить приложение, которое должно найти и запустить DLL-сервер ATLGL, генерирующий изображение по умолчанию и демонстрирующий его в окне внедренного элемента типа ActiveX. Сервер должен достаточно быстро реагировать на изменение регулировок органов управления клиентского приложения.
Подведем итог. В этом уроке мы научились:
- вносить функциональность окна OpenGL в окно, управляемое ATL-классом CWindow;
- добавлять с помощью Studio .NET новые методы в интерфейс, представляемый ко-классом;
- учитывать особенности обработки сообщений Windows в рамках ATL;
- управлять контекстом передачи OpenGL, связанным с окном внедренного СОМ-объекта;
- создавать приложение-контейнер на базе MFC и пользоваться услугами класса-оболочки для управления СОМ-объектом.