- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания Программирование на Visual C++. Архив рассылки - Алекс Jenter
Шрифт:
Интервал:
Закладка:
Для создания COM-объекта и получения интерфейса из этого объекта (напомню, что COM-объект может содержать несколько интерфейсов) вы должны вызвать библиотечную функцию CoCreateInstance(). Прототип CoCreateInstance():
HRESULT CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID* ppv);
Описание параметров:
rclsid CLSID CO-класса. Например, вы можете передать CLSID_ShellLink при создании COM-объекта, который используется для создания ярлыков. pUnkOuter Этот параметр используется только при агрегации COM-объектов, когда берется существующий CO-класс и в него добавляются новые методы. Для наших целей мы должны передать NULL для указания на то, что агрегация использоваться не будет. dwClsContext Указывает на тип COM-сервера. В этой статье будет использоваться простейший тип сервера – in-process DLL, поэтому в качестве параметра будет передаваться константа CLSCTX_INPROC_SERVER. Предостережение: не используйте CLSCTX_ALL (она установлена в ATL по умолчанию), т.к. это может привести к ошибке в системах Windows 95, где не инсталлирован DCOM. riid Это IID интерфейса, который вы хотите получить. Например, вы должны передать IID_IShellLink для получения указателя на интерфейс IShellLink. ppv Адрес указателя на интерфейс. Библиотека COM возвращает указатель на запрашиваемый интерфейс через этот параметр.Когда вы вызываете CoCreateInstance(), она находит CLSID в реестре, считывает данные о расположении сервера, загружает сервер в память и создает экземпляр CO-класса, который вы запрашивали.
Вот пример, в котором создается объект CLSID_ShellLink и запрашивается указатель на интерфейс IShellLink, которым владеет этот COM-объект.
HRESULT hr;
IShellLink* pISL;
hr = CoCreateInstance (CLSID_ShellLink, // CLSID CO-класса
NULL, // агрегация не используется
CLSCTX_INPROC_SERVER, // тип сервера
IID_IShellLink, // IID интерфейса
(void**)&pISL); // Указатель на наш интерфейсный указатель
if (SUCCEEDED(hr)) {
// Здесь можно вызывать методы, используя pISL.
} else {
// Невозможно создать объект COM. hr присвоен код ошибки.
}
В начале мы объявляем переменную типа HRESULT для хранения значения, возвращаемого CoCreateInstance() и указатель на IShellLink. Затем мы вызываем CoCreateInstance() для создания нового COM-объекта. Макрос SUCCEEDED возвращает TRUE, если hr хранит код успешного завершения, или FALSE, если hr содержит код ошибки. Есть также похожий макрос – FAILED, который проверяет значение на предмет соответствия коду ошибки (т.е. делает все наоборот).
Удаление COM-объектаКак уже было сказано ранее, вам не надо освобождать COM-объекты – достаточно сообщить им, что они больше не нужны. Интерфейс IUnknown, являющийся прародителем всех COM-объектов, содержит метод Release(). Вы должны вызвать этот метод для того, чтобы сообщить COM-объекту, что вы в нем более не нуждаетесь. Однажды вызвав Release(), вы больше нигде не сможете использовать указатель на интерфейс, т.к. COM-объект может исчезнуть из памяти в любое время.
Продолжим предыдущий пример, добавив команду удаления объекта:
// Создаем COM-объект как раньше и…
if (SUCCEEDED(hr)) {
// Вызов методов интерфейса через pISL.
// Сообщим COM-объекту о том, что он нам больше не нужен.
pISL->Release();
}
Интерфейс IUnknown будет детально рассмотрен в следующем разделе.
[Продолжение следует]
ВОПРОС-ОТВЕТQ 1. Есть окно нестандартной формы (например, круглое). Но рамка, появляющаяся вокруг него при перемещении, – строго прямоугольной формы. Как избавиться от такой рамки вообще? Или, может быть, ее можно сделать тоже произвольной формы (по контуру окна)?
2. Как избавиться от пунктирной рамки на кнопке, имеющей фокус? Для кнопки, сделанной из красивого рисунка, такая рамка выглядит лишней…
Максим ЧучуйкоA 1. Избавиться от рамки можно так. Как известно, в Windows существует настройка, определяющая двигаются ли окна целиком или двигается только рамка, а окно переносится на новое место после отпускания кнопки мыши. Менять эту настройку можно либо через панель управления, либо программно – с помощью функции SystemParametersInfo. Таким образом, нужно включить режим перетаскивания окна целиком, когда наше окно начинают перемещать, и вернуть его в первоначальное положение после того, как перемещение закончено.
О том, что перемещение начинается, окно узнаёт по сообщению WM_SYSCOMMAND (с параметром SC_MOVE). Когда перемещение завершается, окно получает ещё одно сообщение – WM_EXITSIZEMOVE. Обработчики могут выглядеть так:
void CMainFrame::OnSysCommand(UINT nID, LPARAM lParam) {
if ((nID & 0xFFF0) == SC_MOVE) {
SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, &m_bDrag, 0);
SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, TRUE, 0, 0);
}
CFrameWnd::OnSysCommand(nID, lParam);
}
LRESULT CMainFrame::OnExitSizeMove(WPARAM wParam, LPARAM lParam) {
if(m_bDrag != -1) {
SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, m_bDrag, 0, 0);
m_bDrag = -1;
}
return Default();
}
Переменную m_bDrag типа int следует добавить с класс главного окна и инициализировать значением -1 в конструкторе.
Обратите внимание, что ClassWizard не умеет вставлять обработчик WM_EXITSIZEMOVE — придётся сделать это вручную, используя макрос ON_MESSAGE.
2. Сперва порекомендую метод, который широко применяют парни из Microsoft – использовать вместо кнопки Tool bar с одной-единственной кнопкой. Нужно только установить такому тулбару стили CCS_NOPARENTALIGN и CCS_NORESIZE, чтобы он не прижимался к верхней кромке окна, а оставался там, где мы его разместили. Этот же способ, кстати, можно использовать, если в приложении требуется "нормальная" плоская кнопка.
Ну а если такой способ не подходит, остаётся прибегнуть к custom draw. Это не должно быть проблемой, так как изображение для кнопки уже нарисовано – осталось добавить к нему выпуклую/вдавленную кромку.
Александр Шаргин ОБРАТНАЯ СВЯЗЬЯ уже давно получаю вашу подписку. Она мне очень нравится. Но у меня всё время возникает вопрос когда я читаю очередной номер подписки. Почему почти все выпуски так или иначе посвещены MFC? Даже если тема к примеру ODBC, то примеры всё равно на MFC? Я не имею ничего против MFC, но сам последний раз писал на ней уже очень давно потому-что MFC больше всё-же desktop-UI-ориентированная. То чем я занимаюсь и надеюсь не только я. Написанием COM, COM+ компонентов с UI обычно на ASP. Компоненты я пишу на ATL с STL, с доступом к базам данных через OLE DB/ADO. По ATL/STL/COM/COM+/OLE DB/ADO довольно мало материала в подписке. Почему? Неужели подавляющее большинство подписчиков пишет только на MFC?
Vladislav Loidap В ПОИСКАХ ИСТИНЫQ. Как в Win9x и WinNT заблокировать клавиши WIN, Alt+Tab, Ctrl+Esc etc.?
Mike KrasnikА на сегодня это все… До скорого!
Алекс Jenter [email protected] Красноярск, 2000.Программирование на Visual C++
Выпуск №29 от 24 декабря 2000 г.
Здравствуйте, уважаемые подписчики!
Рад снова приветствовать вас на страницах рассылки. В этом выпуске вас ожидает вторая часть статьи "Введение в COM" и, конечно же, ответы на вопрос из предыдущего выпуска и кое-что еще.
СТАТЬЯ
Введение в COM
Часть 2
Автор: michael dunn
Перевод: Илья Простакишин
Источник: The Code Project
Базовый интерфейс – IUnknownКаждый COM-интерфейс наследуется от интерфейса IUnknown. Имя выбрано не совсем удачно, поскольку этот интерфейс не является "неизвестным" (unknown). Это имя всего лишь означает, что если вы имеете указатель на интерфейс COM-объекта IUnknown, то вы не можете знать, какой объект им владеет (реализует), поскольку интерфейс IUnknown есть в каждом COM-объекте.
IUnknown включает три метода:
1. AddRef() – заставляет COM-объект увеличивать (инкрементировать) свой счетчик обращений. Вы должны использовать этот метод, если была сделана копия указателя на интерфейс и нужно обеспечить возможность использования двух указателей – копии и оригинала. Мы не будем использовать метод AddRef() в этой статье, т.к. для рассматриваемых здесь задач он не нужен.
2. Release() – сообщает COM-объекту о необходимости уменьшения (декремента) счетчика обращений. Смотрите предыдущий пример, чтобы понять, как нужно использовать Release().
3. QueryInterface() – запрашивает указатель на интерфейс COM-объекта. Используется если CO-класс содержит не один, а несколько интерфейсов.
Вы уже видели пример использования Release(), но как же действует QueryInterface()? Когда вы создаете COM-объект с помощью CoCreateInstance(), вы получаете указатель на интерфейс. Если COM-объект включает более одного интерфейса (не считая IUnknown), вы должны использовать метод QueryInterface() для получения дополнительных указателей на интерфейсы, которые вам нужны. Посмотрим на прототип QueryInterface():