Операционные системы. Учебное пособие. Марапулец Ю.В. - 170 стр.

UptoLike

Составители: 

GetClassName( hwndCBOwner, SszClassName, 16 );
Теперь значение переменной szClassName можно сравнить с именем класса теку-
щего приложения или списком имен классов связанных приложений и таким образом
выяснить источник информации, записанной в буфере обмена.
Передача копии исходной информации в буфер обмена подразумевает дополни-
тельный расход памяти из-за необходимости дублировать блоки данных. При некоторых
обстоятельствах этот фактор может сыграть весьма существенную роль, особенно если
копируемые блоки достаточно велики. Одно из возможных решений, заключается в том,
чтобы передавать данные в буфер обмена, не сохраняя их копию, что полностью снима-
ет проблему.
Но есть и другое решение, которое применяется, в частности, при передаче боль-
ших объемов информации: отложенное копирование. В этом случае в буфер обмена не-
посредственно записывается только спецификация формата, а вместо дескриптора гло-
бального блока памяти соответствующему параметру присваивается значение NULL:
SetClipboardData( wFormat, NULL );
Когда приложение запрашивает данные, которые идентифицируются значением
NULL, а не дескриптором блока, Windows расценивает это как запрос отложенного ко-
пирования и вызывает владельца буфера обмена (приложение, поместившее в него дан-
ные) с помощью сообщения WM_RENDERFORMAT, в котором запрашиваемый формат
задан посредством параметра wParam.
В ответ на сообщение WM_RENDERFORMAT приложение вызывает функцию
SetClipboardData(), которой передается дескриптор глобального блока памяти и иденти-
фикатор формата (вместо вызова функций OpenClipboard() и EmptyClipboard()). Таким
образом, реальные данные передаются только тогда, когда получатель готов принять их.
В буфер обмена можно поместить несколько элементов в виде комбинации обыч-
ных и отложенных данных.
Когда приложение перестает быть владельцем буфера обмена, Windows посылает
ему сообщение WM_DESTROYCLIPBOARD,
констатирующее этот факт. В ответ на это
сообщение приложение может вернуть себе право на владение буфером обмена и снова
передать в него те же самые данные, однако такой способ рекомендуется применять
лишь в исключительных ситуациях.
Кроме того, если приложение готово завершить свою работу, но является владель-
цем буфера обмена, который содержит дескрипторы данных со значением NULL, Win-
dows посылает сообщение WM_RENDERALLFORMATS
без указания каких-либо спе-
цификаций формата. В ответ на это сообщение приложение-владелец должно либо
полностью очистить буфер обмена, либо завершить отложенные вызовы.
Но в этом случае, в отличие от реакции на сообщение WM_RENDERFORMAT,
приложение, прекращающее свою работу, не будет вызывать функцию
SetClipboardData(), а просто очистит буфер обмена и целиком запишет в него новые дан-
ные, как если бы отложенные вызовы вообще не существовали.
Еще один частный формат данных буфера обмена объявляется следующим обра-
зом:
SetClipboardData( CF_OWNERDISPLAY, NULL ) ;
Данные типа CF_OWNERDISPLAY всегда передаются с глобальным дескриптором
памяти, имеющим значение NULL (по аналогии с форматом отложенного копирования).
172
      GetClassName( hwndCBOwner, SszClassName, 16 );

     Теперь значение переменной szClassName можно сравнить с именем класса теку-
щего приложения или списком имен классов связанных приложений и таким образом
выяснить источник информации, записанной в буфере обмена.
     Передача копии исходной информации в буфер обмена подразумевает дополни-
тельный расход памяти из-за необходимости дублировать блоки данных. При некоторых
обстоятельствах этот фактор может сыграть весьма существенную роль, особенно если
копируемые блоки достаточно велики. Одно из возможных решений, заключается в том,
чтобы передавать данные в буфер обмена, не сохраняя их копию, что полностью снима-
ет проблему.
     Но есть и другое решение, которое применяется, в частности, при передаче боль-
ших объемов информации: отложенное копирование. В этом случае в буфер обмена не-
посредственно записывается только спецификация формата, а вместо дескриптора гло-
бального блока памяти соответствующему параметру присваивается значение NULL:

      SetClipboardData( wFormat, NULL );

     Когда приложение запрашивает данные, которые идентифицируются значением
NULL, а не дескриптором блока, Windows расценивает это как запрос отложенного ко-
пирования и вызывает владельца буфера обмена (приложение, поместившее в него дан-
ные) с помощью сообщения WM_RENDERFORMAT, в котором запрашиваемый формат
задан посредством параметра wParam.
     В ответ на сообщение WM_RENDERFORMAT приложение вызывает функцию
SetClipboardData(), которой передается дескриптор глобального блока памяти и иденти-
фикатор формата (вместо вызова функций OpenClipboard() и EmptyClipboard()). Таким
образом, реальные данные передаются только тогда, когда получатель готов принять их.
     В буфер обмена можно поместить несколько элементов в виде комбинации обыч-
ных и отложенных данных.
     Когда приложение перестает быть владельцем буфера обмена, Windows посылает
ему сообщение WM_DESTROYCLIPBOARD, констатирующее этот факт. В ответ на это
сообщение приложение может вернуть себе право на владение буфером обмена и снова
передать в него те же самые данные, однако такой способ рекомендуется применять
лишь в исключительных ситуациях.
     Кроме того, если приложение готово завершить свою работу, но является владель-
цем буфера обмена, который содержит дескрипторы данных со значением NULL, Win-
dows посылает сообщение WM_RENDERALLFORMATS без указания каких-либо спе-
цификаций формата. В ответ на это сообщение приложение-владелец должно либо
полностью очистить буфер обмена, либо завершить отложенные вызовы.
     Но в этом случае, в отличие от реакции на сообщение WM_RENDERFORMAT,
приложение, прекращающее свою работу, не будет вызывать функцию
SetClipboardData(), а просто очистит буфер обмена и целиком запишет в него новые дан-
ные, как если бы отложенные вызовы вообще не существовали.
     Еще один частный формат данных буфера обмена объявляется следующим обра-
зом:

      SetClipboardData( CF_OWNERDISPLAY, NULL ) ;

     Данные типа CF_OWNERDISPLAY всегда передаются с глобальным дескриптором
памяти, имеющим значение NULL (по аналогии с форматом отложенного копирования).


                                        172