к содержанию |
Операционная система Microsoft WINDOWS имеет чрезвычайно удобное средство обмена информацией между программами - CLIPBOARD. Это средство предназначено для обмена как текстовой, так и графической информацией. Что имеется в виду под обменом информацией?
Например, вы подготавливаете рекламный проспект при помощи текстового редактора Microsoft Word for WINDOWS. В проспект необходимо поместить фотографию рекламируемого изделия. Используя сканер, вы считываете фотографию и записываете изображение в файл. Далее полученное изображение может быть отредактировано любым графическим редактором. Выделив в графическом редакторе прямоугольный участок изображения, вы можете скопировать его в CLIBBOARD (как во временную память). Затем, переключившись на текстовый редактор, вы можете вставить в любое место текста изображение, взятое из CLIPBOARD.
Вы можете также выделить часть текста и скопировать её в CLIPBOARD. Затем этот текст может быть вставлен в другое место того же текста или вообще в другой текст, редактируемый другим редактором.
Если WINDOWS работает в расширенном режиме, запустив обычную DOS-программу в окне, вы можете выделить любую часть экрана и скопировать её в CLIPBOARD. Затем содержимое CLIPBOARD можно вставить в другую DOS-программу, если она ожидает ввода с клавиатуры. Таким образом организуется перенос текстовой информации из одной DOS-программы в другую DOS-программу. Заметьте, что обе эти программы могут не знать о том, что они работают в среде WINDOWS.
Однако DOS-программа, работающая в среде WINDOWS, может и сама работать с CLIPBOARD. При этом возможен обмен информацией (текстовой или графической) между DOS-программами и приложениями WINDOWS.
Зная интерфейс DOS-программы с WINDOWS CLIPBOARD, вы легко сможете создавать DOS-программы, обменивающиеся информацией с приложениями WINDOWS. Расскажем о некоторых, наиболее полезных функциях, которые могут быть использованы для работы с WINDOWS CLIPBOARD.
Операционная система WINDOWS содержит специальные средства, предназначенные для работы под её управлением DOS-программ. В терминологии WINDOWS DOS-программы относятся к так называемым старым приложениям WINDOWS (WINDOWS Old Application). Версию драйвера WINDOWS, поддерживающего работу с приложениями WinOldAp, можно узнать с помощью функции 1700h прерывания INT 2Fh:
Регистры на входе AX 1700h Регистры на выходе: AX 1700h, если данная версия WinOldAp не поддерживает работу с CLIPBOARD. Если AX не равно 1700h, то: AL = верхнее значение весрии (major version); AH = нижнее значение версии (minor version).
Перед выполнением любой операции с CLIPBOARD необходимо открыть CLIPBOARD (по аналогии с обычным файлом):
Регистры на входе AX 1701h Регистры на выходе: AX 0, если CLIPBOARD уже открыт; не равно 0, если операция успешно выполнена.
С помощью этой функции можно удалить данные из CLIPBOARD:
Регистры на входе AX 1702h Регистры на выходе: AX 0, если при выполнении операции произошла ошибка; не равно 0, если операция успешно выполнена.
С помощью этой функции DOS-программа может выполнить запись данных в WINDOWS CLIPBOARD.
Регистры на входе AX 1703h DX Формат данных, записываемых в CLIPBOARD: 01h текст; 02h графика в формате bitmap; 03h графика в формате metafile picture; 04h SYLK; 05h DIF; 06h графика в формате TIFF; 07h текст в кодировке OEM. ES:BX Указатель на записываемые данные SI:CX Длина записываемых данных Регистры на выходе: AX 0, если при выполнении операции произошла ошибка; не равно 0, если операция успешно выполнена.
С помощью этой функции можно записывать как текстовые, так и графические данные.
Операционная система WINDOWS использует отличную от принятой в DOS кодировку символов. Кодировка WINDOWS называется ANSI-кодировкой, кодировка DOS - OEM-кодировкой. Если при записи текстовых данных в CLIPBOARD вы зададите кодировку OEM (записав в регистр DX значение 7), одновременно с записью данных будет автоматически выполняться перекодировка из OEM в ANSI.
Пользуясь следующей таблицей, вы можете записывать в CLIPBOARD
графические данные в формате bitmap:
Таблица 15. Формат CLIPBOARD для BITMAP-файлов.
Смещение, размер | Описание |
00h (2) | тип(0000h) |
02h (2) | ширина bitmap в пикселах |
04h (2) | высота bitmap в пикселах |
06h (2) | количество байт на строку |
08h (1) | количество цветовых планов |
09h (1) | количество цветовых битов в пикселе |
0Ah (4) | указатель на начало данных |
0Eh (2) | ширина в 0.1 mm |
10h (2) | высота в 0.1 mm |
12h | графические данные |
Исчерпывающую информацию о форматах графических файлов WINDOWS вы можете получить из документации, поставляемой Microsoft для разработчиков приложений.
Размер данных, записанных в CLIPBOARD, можно узнать с помощью следующей функции:
Регистры на входе AX 1704h DX Формат данных: 01h текст; 02h графика в формате bitmap; 03h графика в формате metafile picture; 04h SYLK; 05h DIF; 06h графика в формате TIFF; 07h текст в кодировке OEM. Регистры на выходе: DX:AX 0, если CLIPBOARD не содержит данных в указанном формате; размер записанных данных, включая заголовки.
Регистры на входе AX 1705h DX Формат данных, читаемых из CLIPBOARD: 01h текст; 02h графика в формате bitmap; 03h графика в формате metafile picture; 04h SYLK; 05h DIF; 06h графика в формате TIFF; 07h текст в кодировке OEM. ES:BX Указатель на буфер для читаемых данных Регистры на выходе: AX 0, если при выполнении операции произошла ошибка; не равно 0, если операция успешно выполнена.
После выполнения записи необходимо закрыть CLIPBOARD (точно также, как вы закрываете файл). Для того, чтобы закрыть CLIPBOARD, вы можете использовать следующую функцию:
Регистры на входе AX 1708h Регистры на выходе: AX 0, если произошла ошибка; не равно 0, если операция успешно выполнена.
После записи данных в CLIPBOARD программист может ограничить размер CLIPBOARD:
Регистры на входе AX 1709h SI:CX Размер данных в байтах Регистры на выходе: DX:AX Размер максимального доступного участка памяти
DOS-программа, работающая на виртуальной машине WINDOWS, может временно запретить переключение задач, захватив процессор в монопольное пользование. Для этого она должна вызвать функцию 1681h прерывания INT 2Fh. Параметры задавать не надо.
Про программу, захватившую процессор, говорят, что она вошла в критическую секцию.
Для выхода из критической секции и возобновления работы диспетчера задач WINDOWS программа должна вызвать функцию 1682h прерывания INT 2Fh.
Приведённая ниже программа демонстрирует запись в CLIPBOARD из DOS-программы, а также вход в критическую секцию и выход из неё.
Вначале программа убеждается в том, что она запущена под управлением WINDOWS, работающем в расширенном режиме. Только в этом случае доступны функции для работы с CLIPBOARD.
Далее программа демонстрирует блокировку механизма переключения задач при входе в критическую секцию. После этого проверяется доступность CLIPBOARD.
Если CLIPBOARD доступен, программа проверяет, есть ли в нём текстовые данные. Если текстовые данные есть, они читаются из CLIPBOARD и выводятся на экран. Затем CLIPBOARD очищается и в него записывается тестовая строка, состоящая из латинских букв и символов кириллицы (для проверки выполнения перекодировки из OEM в ANSI).
После записи строки программа устанавливает размер CLIPBOARD и закрывает его. Далее вы можете запустить приложение WINDOWS "Clipboard" и посмотреть результат!
Листинг 24. Работа с WINDOWS CLIPBOARD и критической секцией Файл windos.c ----------------------------------------------------------- #include <dos.h> #include <stdio.h> #include <malloc.h> char buf[2048], far *fptr = buf; char msg[] = "String for storing(для записи) to WINDOWS clipboard\n\n\n"; void main(void) { union REGS inregs, outregs; struct SREGS segregs; unsigned long clipbrd_size, i; printf("\n\nРабота с WINDOWS CLIPBOARD и критической секцией\n" "© Frolov A. 1992\n\n"); // Проверяем, работает ли программа под управлением // WINDOWS в расширенном режиме. inregs.x.ax = 0x1600; int86( 0x2f, &inregs, &outregs); if (outregs.h.al == 0) { printf("\nТребуется расширенный режим WINDOWS!\n"); exit(-1); } // Выводим на экран версию WINDOWS printf("Версия WINDOWS - %d.%d\n", outregs.h.al, outregs.h.ah); // Определяем и выводим на экран идентификатор // виртуальной машины, на которой работает // данная программа. inregs.x.ax = 0x1683; int86( 0x2f, &inregs, &outregs); printf("Виртуальная машина - VM%d\n", outregs.x.bx); // Входим в критическую секцию. До выхода из нее // переключение задач в WINDOWS блокировано. inregs.x.ax = 0x1681; int86( 0x2f, &inregs, &outregs); printf("\n\nВошли в критическую секцию.\n" "Попробуйте переключить задачу клавишами <ALT-TAB>,\n" "затем нажмите любую другую клавишу для выхода\n" "из критической секции\n"); // После нажатия на любую клавишу выходим // из критической секции getch(); inregs.x.ax = 0x1682; int86( 0x2f, &inregs, &outregs); printf("Вышли из критической секции\n"); // Проверяем доступность CLIPBOARD. Если доступен, // выводим версию драйвера WINDOWS, использующегося // для поддержки DOS-программ - WINOLDAP. inregs.x.ax = 0x1700; int86( 0x2f, &inregs, &outregs); if(outregs.x.ax == 0x1700) { printf("\nClipboard недоступна"); exit(-1); } else printf("\nВерсия WINOLDAP - %d.%d", outregs.h.al, outregs.h.ah); // Открываем CLIPBOARD inregs.x.ax = 0x1701; int86( 0x2f, &inregs, &outregs); if(outregs.x.ax == 0x0000) { printf("\nОшибка при открытии Clipboard"); exit(-1); } // Получаем объем данных, находящихся в CLIPBOARD. // Регистр DX равен 1, следовательно, мы будем работать с // текстовыми данными. inregs.x.ax = 0x1704; inregs.x.dx = 0x01; int86( 0x2f, &inregs, &outregs); // Вычисляем объем данных clipbrd_size = outregs.x.dx << 16l; clipbrd_size += outregs.x.ax; if(clipbrd_size == 0L) printf("\nClipboard пуст"); else printf("\nОбъем данных в Clipboard: %lu\n", clipbrd_size); // Получаем данные из CLIPBOARD. В регистре DX // задаем значение 7, что соответствует тексту // в кодировке OEM. При этом в процессе передачи // данных выполняется перекодировка из представления // ANSI (используется в WINDOWS) в представление // OEM (используется в DOS) inregs.x.ax = 0x1705; inregs.x.dx = 0x07; segregs.es = FP_SEG(fptr); inregs.x.bx = FP_OFF(fptr); int86x( 0x2f, &inregs, &outregs, &segregs); // Выводим содержимое CLIPBOARD, если // там что-нибудь есть. if(outregs.x.ax == 0) printf("\nВ Clipboard ничего нет!"); else { printf("Содержимое Clipborad:\n"); for(i=0l; i < clipbrd_size; i++) { putch(buf[i]); } } // Очищаем CLIPBOARD inregs.x.ax = 0x1702; int86( 0x2f, &inregs, &outregs); // Записываем в CLIPBOARD текстовые данные // в кодировке OEM inregs.x.ax = 0x1703; inregs.x.dx = 0x07; inregs.x.si = 0x00; inregs.x.cx = strlen(msg); fptr = msg; segregs.es = FP_SEG(fptr); inregs.x.bx = FP_OFF(fptr); int86x( 0x2f, &inregs, &outregs, &segregs); if(outregs.x.ax == 0) { printf("\nОшибка при записи в Clipboard"); exit(-1); } // Устанавливаем размер CLIPBOARD, равный // длине записанной в него строки inregs.x.ax = 0x1709; inregs.x.si = 0x00; inregs.x.cx = strlen(msg); int86( 0x2f, &inregs, &outregs); // Закрываем CLIPBOARD inregs.x.ax = 0x1708; int86( 0x2f, &inregs, &outregs); exit(0); }
к содержанию |