Программирование на Visual C++. Архив рассылки
Шрифт:
Q 1. Есть окно нестандартной формы (например, круглое). Но рамка, появляющаяся вокруг него при перемещении, – строго прямоугольной формы. Как избавиться от такой рамки вообще? Или, может быть, ее можно сделать тоже произвольной формы (по контуру окна)?
2. Как избавиться от пунктирной рамки на кнопке, имеющей фокус? Для кнопки, сделанной из красивого рисунка, такая рамка выглядит лишней…
A 1. Избавиться от рамки можно так. Как известно, в Windows существует настройка, определяющая двигаются ли окна целиком или двигается только рамка, а окно переносится на новое место после отпускания кнопки мыши. Менять эту настройку
О том, что перемещение начинается, окно узнаёт по сообщению WM_SYSCOMMAND (с параметром SC_MOVE). Когда перемещение завершается, окно получает ещё одно сообщение – WM_EXITSIZEMOVE. Обработчики могут выглядеть так:
Переменную 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?
Q. Как в Win9x и WinNT заблокировать клавиши WIN, Alt+Tab, Ctrl+Esc etc.?
А на сегодня это все… До скорого!
Программирование на Visual C++
Выпуск №29 от 24 декабря 2000 г.
Здравствуйте, уважаемые подписчики!
Рад снова приветствовать
СТАТЬЯ
Введение в COM
Часть 2
Автор: michael dunn
Перевод: Илья Простакишин
Источник: The Code Project
Каждый 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:
Значения параметров:
iid | IID интерфейса, который вам нужен. |
ppv | Адрес указателя на интерфейс. QueryInterface возвращает указатель на интерфейс через этот параметр, если не произошло никаких ошибок. |
Продолжим наш пример с ярлыком. CO-класс для создания ярлыков включает интерфейсы IShellLink и IPersistFile. Если у вас уже есть указатель на IShellLink – pISL, то вы можете запросить интерфейс IPersistFile у COM-объекта с помощью следующего кода:
Затем вы тестируете hr с помощью макроса SUCCEEDED. Это нужно, чтобы узнать, сработал ли метод QueryInterface. Если все нормально, то можно использовать новый указатель pIPF, так же как и любой другой интерфейсный указатель. Затем вам нужно вызвать метод pIPF->Release для сообщения COM-объекту, что вы закончили работу с интерфейсом и он вам больше не нужен.
Я хочу остановиться на некоторых моментах, касающихся работы со строками при написании программ в COM.
Всякий раз, когда метод COM возвращает строку, он делает это, используя формат Unicode. Unicode это таблица символов, также как и ASCII, только все символы в ней занимают 2 байта (в ANSI – один байт). Если вы хотите получить строку в более удобном виде, то ее нужно преобразовать в тип TCHAR.
TCHAR и функции, начинающиеся с _t (например, _tcscpy) были разработаны для управления строками Unicode и ANSI с использованием одинакового исходного кода. Наверняка, вы раньше писали программы с использованием ANSI-строк и ANSI-функций, поэтому далее в этой статье я буду обращаться к типу char, вместо TCHAR, чтобы лишний раз вас не смущать. Однако, вы должны знать, что есть такой тип – TCHAR, хотя бы для того, чтобы не задавать лишних вопросов, когда встретите его в программах, написанных другими разработчиками.