| к содержанию |
Операционная система 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);
}
| к содержанию |