Конференция "KOL" » "Ошибка" в работе с буфером обмена [Delphi, Windows]
 
  • QAZ (09.02.15 15:08) [0]
    в функциях
    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 за который ты так упорно доказывал
    сразу видно - скопипастил в  разных местах, как попало, а патом и у тебя скопипастят, так и будет круговерть....

    лан забудь и так сойдет
 
Конференция "KOL" » "Ошибка" в работе с буфером обмена [Delphi, Windows]
Есть новые Нет новых   [134427   +35][b:0][p:0.001]