Иллюстрированный самоучитель по Visual Studio .NET

Взаимодействие классов

Класс CPropDlg должен обеспечить реакцию на изменение регулировок, а класс COpenGL должен учесть новые установки и перерисовать изображение. Общение классов, как мы уже отметили, происходит по законам СОМ, то есть с помощью указателя на интерфейс. Здесь нам на помощь приходит шаблон классов CComQiPtr. Литеры "QI" в имени шаблона означают Querylnterface, что обещает нам автоматизацию в реализации запроса указателя на этот интерфейс. В классе переопределены операции выбора (), взятия адреса (&), разадресации (*) и некоторые другие, которые упрощают использование указателей на различные интерфейсы. При создании объекта класса CComQiPtr, например:

CComQIPtr<IOpenGL, &IID_IOpenGL> р(m_ppUnk[i]);

Он настраивается на нужный нам интерфейс, и далее мы работаем с удобствами, не думая о функциях Querylnterface, AddRef и Release. При выходе из области действия объекта р класса CGomQiPtr<lOpenGL, &ilD_iOpenGL> освобождение интерфейса произойдет автоматически.

Для обмена с окном диалоговой вставки введите в protected-секцию класса CPropDlg массив текущих позиций регуляторов и переменную для хранения текущего режима изображения полигонов:

protected:
int m_Pos[11];BOOL m_bQuad;

В конструктор класса добавьте код инициализации массива:

ZeroMemory (m_Pos, sizeof(m_Pos));

Другую переменную следует инициализировать при открытии диалога (вставки). Способом, который вы уже неоднократно применяли, введите в класс реакции на Windows-сообщения WM_INITDIALOG и WM_HSCROLL. Затем перейдите к созданной мастером заготовке метода Onlnit Dialog, которую найдете в файле PropDlg.cpp:

LRESULT CPropDlg::OnInitDialog(UINT uMsg, WPARAM wParam,
LPARAM IParam, BOOL& bHandled)
{
_super::OnInitDialog(uMsg, wParam, IParam, bHandled);
return 1;
}

Здесь вы увидите новое ключевое слово языка _ super, которое является спецификой Microsoft-реализации. Оно представляет собой не что иное, как явный вызов родительской версии функции метода базового или super-класса. Так как классы в ATL имеют много родителей, то _ super обеспечивает выбор наиболее подходящего из них. Теперь введите изменения, которые позволят при открытии вкладки привести наши регуляторы в соответствие со значениями переменных в классе COpenGL. Вы помните, что значения регулировок используются именно там. Там же они и хранятся:

LRESULT CPropDlg::OnInitDialog (UINT uMsg, WPARAM wParam,
LPARAM IParam, BOOL& bHandled)
_super::OnInitDialog(uMsg, wParam, IParam, – bHandled);
//====== Кроим умный указатель по шаблону IQpenGL
CComQIPtr<IOpenGL> p(m_ppUnk[0]);
//=== Пытаемся связаться с классом COpenGL и выяснить
//=== значение переменной m_FillMode
//=== В случае неудачи даем сообщение об ошибке
DWORD mode;
if FAILED (p › GetFillMode(&mode))
{
ShowError();
return 0;
}
//====== Работа с combobox по правилам API
//====== Получаем Windows-описатель окна
HWND hwnd = GetDlgItem(IDC_FILLMODE);
//====== Наполняем список строками текста
SendMessage(hwnd, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)"Points"
SendMessage(hwnd, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)"Lines")
SendMessage(hwnd, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)"Fill");
// Выбираем текущую позицию списка в соответствии
// со значением, полученным из COpenGL WPARAM
w = mode == GL_POINT? 0
: mode == GL_LINE?1:2;
SendMessage(hwnd, CB_SETCURSEL, w, 0);
// Повторяем сеанс связи, выясняя позиции ползунков
if FAILED (p › GetLightParams(m_Pos))
{
ShowError();
return 0;
}
Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.