- •Часть 2 (продолжение): Прикладное программирование в Windows
- •Глава 8. Виртуальное окно: работа с текстом
- •8.1. Оконные координаты, цвета, отображение строк
- •Кодировка rgb-значений
- •Размеры системных метрик
- •8.2. Виртуальное окно
- •Способы заполнения прямоугольной области
- •8.3. Изменение шрифтов
- •Макроимена распространенных шрифтов
- •8.4. Создание собственных шрифтов
- •Глава 9. Программирование графики
- •9.1. Логическая система координат
- •Рекомендуемый самый яркий состав цветов
- •9.2. Пиксели, линии, дуги, прямоугольники, эллипсы и секторы
- •9.3. Работа с перьями и кистями
- •Типы линий, создаваемых пером
- •9.4. Технология виртуального окна
- •9.5. Режимы отображения и области вывода
- •Текущий режим отображения (mappind mode)
- •Глава 10. Работа с панелями инструментов
- •10.1. Общие элементы управления
- •Общие элементы управления
- •10.2. Подключение и инициализация общих элементов управления
- •10.3. Работа с панелью инструментов
- •Начальные состояния кнопок панели инструментов
- •Стиль кнопки определяется (значения поля fsStyle)
- •Сообщения к панели инструментов
- •10.4. Создание растрового изображения для панели инструментов
- •10.5. Включение подсказок
- •Глава 11. Спины, ползунки и индикаторы процессов
- •11.1. Работа со спином
- •Стили «up-down control»
- •Сообщения, которые можно посылать спину
- •11.2. Создание спина с «приятельским» окном
- •11.3. Работа с ползунком
- •Значения стилей для ползунка
- •Перечень сообщений, которые можно посылать ползунку
- •Перечень нотификационных сообщения ползунка
- •11.4. Индикатор процесса
- •Управляющие сообщения индикатору
- •Глава 12. Многозадачность: процессы и потоки
- •12.1. Создание нового процесса (отдельной задачи)
- •Разрешенные значения поля dwFlags
- •12.2. Многопотоковые программы
- •12.3. Работа с несколькими потоками
- •12.4. Синхронизация процессов и потоков: семафоры
- •12.5. Обработка событий
- •Глава 13. Приемы программного управления вычислительным процессом
- •13.1. Использование функций Проводника Explorer для работы в файловой системе
- •Управляющая информация Проводника
- •Режимы обработки файлов
- •13.2. Создание собственных динамических библиотек (dll-файлов)
- •13.3. Работа с буфером обмена Clipboard
- •Функции подсистемы Clipboard
- •Свойства выделяемого блока памяти
- •Форматы и типы данных
- •Литература
13.3. Работа с буфером обмена Clipboard
Буфер обмена (Clipboard) в Windows выполняет две основные функции. Во-первых, он служит буфером памяти для кратковременного хранения данных: чтобы в текстовом редакторе переместить фрагмент текста документа, необходимо скопировать текст в буфер обмена, а затем уже вставить в новое место своего документа. Второй функцией буфера обмена является поддержка простейшей формы информационного межпроцессного взаимодействия для различных приложений Windows. Эта функция поддерживает наиболее популярный до сих пор способ копирования данных из одного приложения в другое. Причем и при кратковременном хранении данных, и при обмене данными между приложениями буфер обмена действует одинаково.
Буфер обмена представляет собой область памяти, к которой имеют доступ все приложения, работающие в системе. Программа может взаимодействовать с буфером обмена, записывая в него информацию либо читая ее оттуда, или же выполняя и то и другое. Более того, одна программа может записать данные в буфер обмена, а другая – прочесть их. Обе эти ситуации продемонстрированы в приведенном ниже примере.
Подсистема работы с буфером обмена. Работа с буфером обмена осуществляется при помощи подсистемы API, состоящей из 16 функций (чаще всего Вам могут потребоваться далеко не все из них). Имена этих функций и их назначение приводятся в табл. 13.3.
Таблица 13.3
Функции подсистемы Clipboard
№ |
Функция |
Назначение |
1 |
ChangeClipboardChain |
Удалить окно из списка окон просмотра буфера обмена |
2 |
CloseClipboard |
Закрыть доступ к буферу обмена |
3 |
CountClipboardFormats |
Получить количество форматов данных, хранимых в буфере обмена на текущий момент |
4 |
EmptyClipboard |
Очистить буфер обмена |
5 |
EnumClipboardFormats |
Перечислить форматы данных, доступные на текущий момент в буфере обмена |
6 |
GetClipboardData |
Получить дескриптор памяти, в которой хранятся данные буфера обмена |
7 |
GetClipboardFormatName |
Получить имя пользовательского формата данных |
8 |
GetClipboardOwner |
Получить дескриптор окна, работающего с буфером обмена в настоящий момент |
9 |
GetClipboardViewer |
Получить дескриптор первого из окон просмотра буфера обмена в списке таких окон |
10 |
GetOpenClipboardWindow |
Получить дескриптор окна, открывшего буфер обмена |
11 |
GetPriorityClipboardFormat |
Получить наиболее подходящий формат для данных |
12 |
IsClipboardFormatAvailable |
Определить, является ли заданный формат доступным в буфере обмена на текущий момент |
13 |
OpenClipboard |
Открыть буфер обмена |
14 |
RegisterCHpboardFormat |
Зарегистрировать собственный формат данных в буфере обмена |
15 |
SetClipboardData |
Записать данные в буфер обмена |
16 |
SetClipboardViewer |
Добавить новое окно в список окон просмотра буфера обмена |
В нашем примере используются только функции OpenClipboard(), EmptyClipboard(), SetClipboardData(), GetClipboardData() и CloseClipboard(). И нужно отметить, что это весьма распространенная ситуация: из множества функций, содержащихся в каждой подсистеме API, как правило, используются лишь некоторые из них. Большинство же применяются только в особых, редко возникающих ситуациях. Что касается подсистемы работы с буфером обмена, то программа может, например, отслеживать содержимое последнего. Такие программы называются программами просмотра буфера обмена (clipboard viewer). Из вышеприведенной таблицы видно, что некоторые функции поддерживают создание таких программ и их работу. Если же Ваша программа не преследует таких целей, эти функции Вам не нужны. Таким образом, каждая подсистема APIпредоставляет столько функций, сколько требуется для полного использования соответствующей возможности Windows, а программист выбирает те из них, которые ему нужны для решения конкретной задачи.
Буфер обмена представляет собой одну из простейших возможностей Windows, поскольку требует всего лишь двух основных операций: поместить данные в буфер обмена и прочесть данные из него. В следующих разделах рассматривается, как эти операции выполняются.
Запись данных в буфер обмена. Общая процедура записи данных в буфер обмена состоит из следующих шагов:
1) выделить блок глобальной памяти, достаточный для того, чтобы хранить в нем данные, которые необходимо поместить в буфер обмена;
2) скопировать данные в выделенный блок памяти;
3) открыть буфер обмена;
4) очистить буфер обмена;
5) настроить буфер обмена на выделенный блок памяти;
6) закрыть буфер обмена.
Эти шаги выполняются в следующем фрагменте программы:
// Выделить блок глобальной памяти и получить
// его дескриптор
hGout=GlobalAlloc(GHND|GMEM_DDESHARE,
(DWORD)MAXSIZE);
р=(char*)GlobalLock(hGout);
//
// Операторы копирования текста
// в глобальную память
//
GlobalUnlock(hGout);
if(OpenClipboard(hwnd))
{
EmptyClipboard();
SetClipboardData(CF_TEXT,hGout);
CloseClipboard();
}
Здесь hGout представляет собой дескриптор глобальной памяти, а переменная р – указатель. Давайте подробно рассмотрим этот фрагмент. В первой его строке выделяется блок глобальной памяти при помощи функции GlobalAlloc(), прототип которой имеет следующий вид:
HGLOBAL GlobalAlloc(UINT How, DWORD dwSize);
Функция GlobalAlloc() выделяет память и возвращает дескриптор выделенного блока. Если память не может быть выделена, эта функция возвращает значение NULL. Размер выделяемого блока в байтах задается параметром dwSize. Если система не имеет достаточного количества свободной памяти, функция также возвращает NULL. Свойства выделяемого блока памяти задаются параметром How, который может быть любой из имеющих смысл комбинаций макросов, приведенных в таблице 13.4.
Таблица 13.4
