Защищенный режим процессоров Intel 80286/80386/80486© Александр Фролов, Григорий ФроловТом 4, М.: Диалог-МИФИ, 1993, 234 стр. 7.3. Связь с WINDOWS CLIPBOARDОперационная система 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. Получить версию WinOldApОперационная система 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 необходимо открыть CLIPBOARD (по аналогии с обычным файлом): Регистры на входе AX 1701h Регистры на выходе: AX 0, если CLIPBOARD уже открыт; не равно 0, если операция успешно выполнена. Очистить CLIPBOARDС помощью этой функции можно удалить данные из CLIPBOARD: Регистры на входе AX 1702h Регистры на выходе: AX 0, если при выполнении операции произошла ошибка; не равно 0, если операция успешно выполнена. Записать данные в CLIPBOARDС помощью этой функции 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-файлов.
Исчерпывающую информацию о форматах графических файлов WINDOWS вы можете получить из документации, поставляемой Microsoft для разработчиков приложений. Получить размер CLIPBOARDРазмер данных, записанных в CLIPBOARD, можно узнать с помощью следующей функции:
Регистры на входе
AX 1704h
DX Формат данных:
01h текст;
02h графика в формате bitmap;
03h графика в формате metafile picture;
04h SYLK;
05h DIF;
06h графика в формате TIFF;
07h текст в кодировке OEM.
Регистры на выходе:
DX:AX 0, если CLIPBOARD не содержит данных в указанном формате;
размер записанных данных, включая заголовки.
Прочитать данные из 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 (точно также, как вы закрываете файл). Для того, чтобы закрыть CLIPBOARD, вы можете использовать следующую функцию: Регистры на входе AX 1708h Регистры на выходе: AX 0, если произошла ошибка; не равно 0, если операция успешно выполнена. Установить размер данных, записанных в CLIPBOARDПосле записи данных в CLIPBOARD программист может ограничить размер CLIPBOARD: Регистры на входе AX 1709h SI:CX Размер данных в байтах Регистры на выходе: DX:AX Размер максимального доступного участка памяти Критическая секцияDOS-программа, работающая на виртуальной машине WINDOWS, может временно запретить переключение задач, захватив процессор в монопольное пользование. Для этого она должна вызвать функцию 1681h прерывания INT 2Fh. Параметры задавать не надо. Про программу, захватившую процессор, говорят, что она вошла в критическую секцию. Для выхода из критической секции и возобновления работы диспетчера задач WINDOWS программа должна вызвать функцию 1682h прерывания INT 2Fh. Пример программы для работы с CLIPBOARDПриведённая ниже программа демонстрирует запись в 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);
}
|

