Взаимодействие классов
Класс 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; }