к содержанию

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-файлов.

Смещение, размерОписание
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

Размер данных, записанных в 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);
}
к содержанию
Hosted by uCoz