- •Раздел 4. Разработка по Тема 4.1. Проектирование интерфейса с пользователем
- •4.1.1. Типы пользовательских интерфейсов.
- •4.1.2. Пользовательская и программная модели интерфейса.
- •4.1.3. Разработка диалогов.
- •4.1.4. Основные компоненты графических пользовательских интерфейсов.
- •Тема 4.2. Реализация графических пользовательских интерфейсов.
- •4.2.1. Диалоги, управляемые пользователем.
- •4.2.2. Диалоги, управляемые системой.
- •4.2.3. Использование метафор.
- •4.2.4. Технология Drag and Drop.
- •4.2.5. Интеллектуальные элементы.
- •4.3.1. Базовые типы данных.
- •Константы
- •Область действия имен
- •4.3.2. Указатели и адресная арифметика.
- •4.3.3. Составные типы данных. Структуры
- •Битовые поля
- •Определение типов
- •Перечислимые типы
- •4.3.4. Выражения и операции.
- •4.3.5. Управляющие конструкции. Условные операторы
- •Операторы циклов
- •4.4.1. Статические одномерные массивы.
- •4.4.2. Статические многомерные массивы.
- •4.4.3. Динамические массивы.
- •4.4.4. Массивы указателей.
- •4.5.1. Стеки.
- •4.5.2. Очереди.
- •4.5.3. Списки.
- •4.5.4. Бинарные деревья.
- •4.6.1. Объявление классов и экземпляров классов.
- •4.6.2. Инкапсуляция данных и методов.
- •4.6.3. Конструкторы классов.
- •Конструктор по умолчанию
- •Конструктор копирования
- •4.6.4. Деструкторы классов.
- •4.7.1. Разделы в описании класса.
- •4.7.2. Friend-конструкции.
- •4.7.3. Статические члены классов.
- •4.7.4. Использование описателя const в классах.
- •4.8.1. Вложенность классов.
- •4.8.2. Наследование данных и методов.
- •4.8.3. Типы наследования.
- •4.9.1. Полиморфизм раннего связывания.
- •4.9.2. Полиморфизм позднего связывания и виртуальные функции.
- •4.9.3. Абстрактные методы и классы.
- •4.10.1. Функции консольного ввода-вывода.
- •4.10.2. Функции файлового ввода-вывода.
- •4.10.3. Использование библиотеки классов потокового ввода-вывода.
- •4.11.1. Перегрузка операций.
- •4.11.2. Шаблоны функций.
- •4.11.3. Шаблоны классов.
- •4.11.4. Обработка исключений.
- •Тема 4.12. Com-технология.
- •4.12.1. Основные понятия.
- •4.12.2. Типы интерфейсов.
- •Свойства интерфейсов
- •Типы интерфейсов
- •4.12.3. Типы com-объектов.
- •4.12.4. Фабрика классов.
- •Тема 4.13. Построение com-сервера.
- •4.13.1. Язык idl.
- •Содержимое файла idl
- •4.13.2. Определение пользовательского интерфейса.
- •4.13.3. Реализация пользовательского интерфейса.
- •4.13.4. Создание тестового клиента.
- •Тема 4.14. Обзор платформы ms .Net.
- •4.14.1. Общая идея архитектуры .Net.
- •4.14.2. Достоинства и недостатки .Net.
- •4.14.3. Схема трансляции программ в .Net.
- •4.14.4. Язык msil.
- •4.14.5. Объектно-ориентированная модель .Net.
4.13.4. Создание тестового клиента.
Как первый сервер, так и наш тестовый клиент будут простыми. Создадим консольное приложение Win32, названное FirstSrvClient (выберите опцию создания пустого приложения), а затем добавим файл C++ (main.cpp). В этом файле мы создадим программный код простой функции main () для создания экземпляров нашего сервера и вызова его метода DoSomething.
Для доступа к интерфейсу IFirstlnterfасе нужен файл firstsrv.h, сгенерированный компилятором MIDL. Для доступа к идентификаторам CLSID и IDD — файл firstsrv_i.с, также сгенерированный компилятором MIDL. Далее мы инициализировали СОМ вызовом функции CoIlnitialize (с которой сопряжена используемая при завершении работы функция CoUnitialize). Затем мы вызвали функцию CoCreateInstance, использовав CLSID_FIRSTComponent в качестве идентификатора CLSID требуемого компонента, и IID_FirstInterfасе в качестве идентификатора IID требуемого интерфейса. Мы ожидаем возврата указателя интерфейса в переменную pFI.
Далее мы проверяем возвращаемое значение типа HRESULT. В случае успеха мы просто вызываем метод DoSomething и освобождаем ссылку на интерфейс (помните: функция CoCreateInstance возвращает указатель интерфейса, добавленный функцией AddRef, так что мы должны предоставить соответствующую операцию Release для его освобождения). Наконец, мы деинициализируем СОМ вызовом функции CoUninitialize. Соответствующий программный код приведен в листинге 2.6.
Листинг 2.6. Тестовый клиент для IFirstInterface (main.cpp)
// main.cpp
#include <windows.h>
#include ". .\FirstSrvDll\firstsrv.h"
#include ". .\FirstSrvDll\firstsrv_i.c"
int main()
{
// Инициализация COM
CoInitialize(NULL);
// Создание экземпляра FirstComponent
// и получение указателя на IFirstInterfасе
IFirstInterface* pFI=NULL;
HRESULT hr=CoCreateInstance(CLSID_FirstComponent,NULL,
CLSCTX_INPROC_SERVER,
IID_IFirstInterface, reinterpret_cast<void**>(&pFI));
if (FAILED(hr))
{
MessageBox(NULL,"Could not create instance (He могу создать интерфейс)", "Error in CoCreatelnstance (Ошибка в CoCreatelnstance) ",
MB_OK + MB_ICONSTOP);
}
else
{
// Использование интерфейса
pFI->DoSomething();
// Освобождение ссылки на интерфейс
pFI->Release(); .
}
CoUninitialize();
return 0;
}
Следующий этап - построение и запуск тестового клиента. Вы должны получить окно сообщения “We did it!”.
Чтобы лучше понять, как эти два компонента работают совместно, пройдем по программному коду строка за строкой, отслеживая ход исполнения программы от клиента к серверу СОМ и назад к клиенту. Выполните код по следующему алгоритму.
1. Выполните построение отладочной версии сервера и клиента.
2. Откройте проект FirstSrv.
3. Выберите команду Project>Settings (Проект>Установки). На вкладке Debug отобразившегося окна в поле Executable for Debug Session (Выполняемый модуль для сеанса отладки) укажите путь к исполняемому клиентскому модулю: FirstSrvCIient.exe.
4. Поместите точку останова в функции DllGetClassObject и DllCanUnloadNow.
5. Откройте файл клиентской программы main.cpp и поместите точку останова на вызове функции CoCreateInstance.
6. Нажмите клавишу F5 и начните отладку.
7. Выполняйте пошаговое перемещение по коду программы с помощью клавиши F10, перешагивая через вызовы функций (например, g_FirstClassFactory QueryInterfасе).
Во время пошагового перемещения по программному коду контролируйте значения счетчиков ссылок и счетчиков фиксаций, чтобы посмотреть, как они себя ведут.