Мастера DELPHI, Delphi programming community Рейтинг@Mail.ru Титульная страница Поиск, карта сайта Написать письмо 
| Новости |
Новости сайта
Поиск |
Поиск по лучшим сайтам о Delphi
FAQ |
Огромная база часто задаваемых вопросов и, конечно же, ответы к ним ;)
Статьи |
Подборка статей на самые разные темы. Все о DELPHI
Книги |
Новинки книжного рынка
Новости VCL
Обзор свежих компонент со всего мира, по-русски!
|
| Форумы
Здесь вы можете задать свой вопрос и наверняка получите ответ
| ЧАТ |
Место для общения :)
Орешник
Коллекция курьезных вопросов из форумов
Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / rsdn.org

 
Чтобы не потерять эту дискуссию, сделайте закладку « предыдущая ветвь | форум | следующая ветвь »

"Ошибка" в работе с буфером обмена [Delphi, Windows]


QAZ   (09.02.15 15:08

в функциях
Text2Clipboard
WText2Clipboard
используется константа GMEM_DDESHARE, а должна быть GMEM_MOVEABLE


QAZ   (09.02.15 15:37[1]

также в функциях
Clipboard2Text
Clipboard2WText
зачем то сначала вызывается OpenClipboard, а потом проверяется IsClipboardFormatAvailable
хотя по логике (и "оптимизации" кода), надо сначала проверить наличие формата, а потом уже открывать\закрывать буфер


QAZ   (11.02.15 10:34[2]


> Clipboard2Text
> Clipboard2WText

так же
ClipboardHasText
TBitmap.PasteFromClipboard


QAZ   (11.02.15 11:06[3]


> ClipboardHasText

в этой функции вообще не надо открывать\закрывать буфер
и она сводится к виду
function ClipboardHasText: Boolean;
begin
 Result := IsClipboardFormatAvailable( CF_TEXT );
end;

т.е. фактически вообще не нужна, если только как затычка из серии "вдруг кто-то пользовался"


QAZ   (11.02.15 12:25[4]


> ClipboardHasText

для UNICODE_CTRLS думаю логичен такой вариант
function ClipboardHasText: Boolean;begin  Result := IsClipboardFormatAvailable( CF_UNICODETEXT );end;


QAZ   (11.02.15 12:26[5]

при наличии любого управляющего элемента из ComCtl32.dll на форме, например ListView (а по сути после вызова функции InitCommonControls)+ включенного в ресурсы или лежащего рядом файла манифеста
любой Label на форме, при двойном клике мышью, копирует свой текст в буфер обмена!
это нормальное поведение (хотя 99.9% программистов про это не знают) Label , начиная с Windows Vista
возможно, стоит этот момент как то обыграть в KOL, например добавить свойство или директиву компиляции, блокирующую данную "фишку" (Mouse.StopHandling:=True; в обработчике MouseDblClk)


QAZ   (11.02.15 14:09[6]


> Text2Clipboard
> WText2Clipboard

также в данных функциях некорректно использовать OpenClipboard с параметром 0 !
0 - это нормально для чтения из буфера, для записи должен быть хэндл окна, хотя бы временно созданного если нет других

вот например в TBitmap.PasteFromClipboard, почему-то стоит хэндл, хотя можно было и 0, а там где нужен хэндл - наоборот 0....


Vladimir Kladov ©   (18.02.15 11:38[7]

GMEM_DDESHARE позволяет не освобождать дескриптор. В остальном разницы нет.

OpenClipboard делается для того, чтобы между проверкой наличия текста и получением текста\картинки никто не успел в буфер всунуть что-нибудь другое. Если у кого-то ничего плохого не случается, то это не значит, что не случалось ничего плохого у других.

Насчет параметра 0 - читайте MSDN. Использование 0 допускается, в этом случае буфер связывается со всей программой, а не с окном.


QAZ   (18.02.15 16:13[8]


> Насчет параметра 0 - читайте MSDN. Использование 0 допускается,
>  в этом случае буфер связывается со всей программой, а не с окном.

так ято какраз и читаю MSDN :)
If an application calls OpenClipboard with hwnd set to NULL, EmptyClipboard sets the clipboard owner to NULL; this causes SetClipboardData to fail.


> GMEM_DDESHARE позволяет не освобождать дескриптор. В остальном  разницы нет.

дык опять же читая MSDN...
The following values are obsolete, but are provided for compatibility with 16-bit Windows. They are ignored.

GMEM_DDESHARE
GMEM_DISCARDABLE
GMEM_LOWER
GMEM_NOCOMPACT
GMEM_NODISCARD
GMEM_NOT_BANKED
GMEM_NOTIFY
GMEM_SHARE



> OpenClipboard делается для того, чтобы между проверкой наличия  текста ...

ок, ток смысл это делать в той же ClipboardHasText ?
когда содержимое может измениться между ее вызовом и например Clipboard2Text :)


Vladimir Kladov ©   (19.02.15 08:09[9]


> так ято какраз и читаю MSDN :)If an application calls OpenClipboard
> with hwnd set to NULL, EmptyClipboard sets the clipboard
> owner to NULL; this causes SetClipboardData to fail.

Неправильный у Вас MSDN. Вот правильный: https://msdn.microsoft.com/ru-RU/library/windows/desktop/ms649048(v=vs.85).aspx
hWndNewOwner [in, optional]

Type: HWND

A handle to the window to be associated with the open clipboard. If this pa
rameter is NULL, the open clipboard is associated with the current task.



> The following values are obsolete, but are provided for
> compatibility with 16-bit Windows. They are ignored.GMEM_DDESHARE

Да, ignored. Но ведь provided. А в документации по 16-битному есть, что освобождение не требуется. Экономим код.


> смысл это делать в той же ClipboardHasText ?
Здесь смысла нет, согласен.


QAZ   (19.02.15 10:16[10]


> Неправильный у Вас MSDN. Вот правильный

гы :) , ну так надо не только Parameters читать, но и Remarks !

> Да, ignored. Но ведь provided. А в документации по 16-битному
> есть, что освобождение не требуется. Экономим код.

для GMEM_MOVEABLE тоже не требуется :)
а все что "для совместимости", рано или поздно не сработает
и раз выложили ссылку на "правильный" MSDN, то там (именно на этой ссылке\странице) есть еще пунктик Examples, где все наглядно показано


Vladimir Kladov ©   (20.02.15 13:45[11]


> там (именно на этой ссылке\странице) есть еще пунктик Examples,
>  где все наглядно показано

А еще ниже сообщение от пользователя  
Michele Salvador, который утверждает, что утверждение про fail неверно.

SetClipboardData successfully accomplishes its job after OpenClipboard(NULL)

This documentation ambiguously states that OpenClipboard(NULL)
 1. associates open clipboard to current task
 2. makes EmptyClipboard succeed but set the clipboard owner to NULL, that causes SetClipboardData to fail

In my experience first statement is true, the second is false.

This works for me:
  OpenClipboard( NULL );                       // hwnd is set to NULL
  EmptyClipboard();                                // sets clipboard ownership to someone don't know
  SetClipboardData( CF_TEXT, hMem );  // successfully data to clipboard!


Собственно, сколько раз пользовался Text2Clipboard, фэйлов не бьло. Bitmap2Clipboard открывает с хэндлом окна.


QAZ   (20.02.15 15:24[12]

мистер Сальвадор упорот, ибо он не знает (не читает MSDN) что кроме тупого копирования текста в буфер, есть еще отложенный рендер данных в буфер, для которого и нужен хэндл
а посему не надо плодить говнокод по интернетам. копируя друг у друга из серии "работает и ладно"
глянь хотябы релиз в VCL метода опен класса клипборд
procedure TClipboard.Open;
begin
 if FOpenRefCount = 0 then
 begin
   FClipboardWindow := Application.Handle;
   if FClipboardWindow = 0 then
   begin
{$IFDEF MSWINDOWS}
     FClipboardWindow := Classes.AllocateHWnd(MainWndProc);<<<<<<
{$ENDIF}
{$IFDEF LINUX}
     FClipboardWindow := WinUtils.AllocateHWnd(MainWndProc);
{$ENDIF}      
     FAllocated := True;
   end;
   if not OpenClipboard(FClipboardWindow) then
     raise Exception.CreateRes(@SCannotOpenClipboard);
   FEmptied := False;
 end;
 Inc(FOpenRefCount);
end;


Vladimir Kladov ©   (20.02.15 16:25[13]

Давайте говорить конкретно, и без оскорблений. Где в конкретной процедуре Text2Clipboard отложенный рендеринг?


QAZ   (20.02.15 19:37[14]


> Где в конкретной процедуре Text2Clipboard отложенный рендеринг

его и в TBitmap.CopyToClipboard нет, однако хэндл есть и GMEM_MOVEABLE там стоит, а не  GMEM_DDESHARE за который ты так упорно доказывал
сразу видно - скопипастил в  разных местах, как попало, а патом и у тебя скопипастят, так и будет круговерть....

лан забудь и так сойдет


версия для печати

Написать ответ

Ваше имя (регистрация  E-mail 







Разрешается использование тегов форматирования текста:
<b>жирный</b> <i>наклонный</i> <u>подчеркнутый</u>,
а для выделения текста программ, используйте <code> ... </code>
и не забывайте закрывать теги! </b></i></u></code> :)


Наверх

  Рейтинг@Mail.ru     Титульная страница Поиск, карта сайта Написать письмо