Вставка текста из буфера обмена

Тема в разделе "WASM.BEGINNERS", создана пользователем hunt, 12 ноя 2009.

  1. hunt

    hunt New Member

    Публикаций:
    0
    Регистрация:
    7 ноя 2009
    Сообщения:
    16
    Здравствуйте! Никак не могу найти реализацию стандартной вставки текста из буфера обмена, т.е. не могу - как windows вставляет текст в разные приложения из буфера обмена в заданое положение курсора, какие при этом использует winapi функции.
    Подскажите пожалуйста.
    Я это спросил, т.к. эмуляция нажатия клавиш (ctrl+v) почему-то не работает в windows 7.
     
  2. Valentin

    Valentin Member

    Публикаций:
    0
    Регистрация:
    2 ноя 2007
    Сообщения:
    128
    invoke keybd_event,VK_CONTROL, 0, 0, 0
    invoke keybd_event,56h, 0, 0, 0
    invoke keybd_event,56h, 0, KEYEVENTF_KEYUP, 0
    invoke keybd_event,VK_CONTROL, 0, KEYEVENTF_KEYUP, 0
     
  3. krid24

    krid24 Member

    Публикаций:
    0
    Регистрация:
    17 авг 2004
    Сообщения:
    88
  4. hunt

    hunt New Member

    Публикаций:
    0
    Регистрация:
    7 ноя 2009
    Сообщения:
    16
    Valentin keybd_event работает, но ... можно ли как-нибудь приаттачить нажатия клавиш в определенное окно?

    krid24 посмотрел там код, но не нашёл то, что нужно. Там за функцию вставки отвечает функция "ReplaceSelection", которая задаётся приложением.
     
  5. Valentin

    Valentin Member

    Публикаций:
    0
    Регистрация:
    2 ноя 2007
    Сообщения:
    128
    Фокус на окно SetFocus
     
  6. maksim_

    maksim_ New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2009
    Сообщения:
    263
    Код (Text):
    1. VOID WINAPI EditPaste(VOID)
    2. {
    3.     PLABELBOX pbox;
    4.     HGLOBAL   hglb;
    5.     LPTSTR    lptstr;
    6.     PLABELBOX pboxCopy;
    7.     int cx, cy;
    8.     HWND hwnd;
    9.  
    10.     pbox = hwndSelected == NULL ? NULL :
    11.         (PLABELBOX) GetWindowLong(hwndSelected, 0);
    12.  
    13.     // If the application is in edit mode,
    14.     // get the clipboard text.
    15.  
    16.     if (pbox != NULL && pbox->fEdit)
    17.     {
    18.         if (!IsClipboardFormatAvailable(CF_TEXT))
    19.             return;
    20.         if (!OpenClipboard(hwndMain))
    21.             return;
    22.  
    23.         hglb = GetClipboardData(CF_TEXT);
    24.         if (hglb != NULL)
    25.         {
    26.             lptstr = GlobalLock(hglb);
    27.             if (lptstr != NULL)
    28.             {
    29.                 // Call the application-defined ReplaceSelection
    30.                 // function to insert the text and repaint the
    31.                 // window.
    32.  
    33.                 ReplaceSelection(hwndSelected, pbox, lptstr);
    34.                 GlobalUnlock(hglb);
    35.             }
    36.         }
    37.         CloseClipboard();
    38.  
    39.         return;
    40.     }
    41.  
    42.     // If the application is not in edit mode,
    43.     // create a label window.
    44.  
    45.     if (!IsClipboardFormatAvailable(uLabelFormat))
    46.         return;
    47.     if (!OpenClipboard(hwndMain))
    48.         return;
    49.  
    50.     hglb = GetClipboardData(uLabelFormat);
    51.     if (hglb != NULL)
    52.     {
    53.         pboxCopy = GlobalLock(hglb);
    54.         if (pboxCopy != NULL)
    55.         {
    56.             cx = pboxCopy->rcText.right + CX_MARGIN;
    57.             cy = pboxCopy->rcText.top * 2 + cyText;
    58.  
    59.             hwnd = CreateWindowEx(
    60.                 WS_EX_NOPARENTNOTIFY | WS_EX_TRANSPARENT,
    61.                 atchClassChild, NULL, WS_CHILD, 0, 0, cx, cy,
    62.                 hwndMain, NULL, hinst, NULL
    63.             );
    64.             if (hwnd != NULL)
    65.             {
    66.                 pbox = (PLABELBOX) GetWindowLong(hwnd, 0);
    67.                 memcpy(pbox, pboxCopy, sizeof(LABELBOX));
    68.                 ShowWindow(hwnd, SW_SHOWNORMAL);
    69.                 SetFocus(hwnd);
    70.             }
    71.             GlobalUnlock(hglb);
    72.         }
    73.     }
    74.     CloseClipboard();
    75. }
    найти этот пример было чрезвычайно сложно.
     
  7. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    SendMessage(hwnd,WM_PASTE,0,0);
     
  8. iZzz32

    iZzz32 Sergey Sfeli

    Публикаций:
    0
    Регистрация:
    3 сен 2006
    Сообщения:
    355
    Код (Text):
    1. SendPasteMsg:
    2.         call    [GetCurrentThreadId]
    3.         push    eax                     ;For later usage.
    4.         call    [GetForegroundWindow]
    5.         push    0                       ;GetWindowThreadProcessId.lpdwProcessId.
    6.         push    eax                     ;GetWindowThreadProcessId.hWnd.
    7.         call    [GetWindowThreadProcessId]
    8.         pop     edx                     ;CurrentThreadId.
    9.  
    10.         push    0                       ;AttachThreadInput(b).fAttach.
    11.         push    edx                     ;AttachThreadInput(b).idAttachTo.
    12.         push    eax                     ;AttachThreadInput(b).idAttach.
    13.  
    14.         push    1                       ;AttachThreadInput.fAttach.
    15.         push    edx                     ;AttachThreadInput.idAttachTo.
    16.         push    eax                     ;AttachThreadInput.idAttach.
    17.         call    [AttachThreadInput]
    18.         call    [GetFocus]              ;Gotcha!
    19.  
    20.         push    0                       ;SendMessage.lParam.
    21.         push    0                       ;SendMessage.wParam.
    22.         push    WM_PASTE                ;SendMessage.uMsg.
    23.         push    eax                     ;SendMessage.hWnd.
    24.         call    [SendMessage]
    25.  
    26.         call    [AttachThreadInput]     ;(Detach).
    27.         ret
    Вот такая штука есть ещё. Писал много лет назад для плагина, который вставляет в по хоткею в текущее окно трек из винампа (сначала в буфер обмена копирует, а потом дёргает эту функцию).
     
  9. hunt

    hunt New Member

    Публикаций:
    0
    Регистрация:
    7 ноя 2009
    Сообщения:
    16
    Valentin
    Попробовал в блокнот отправить, но отправляется только в текущее окно (код на автоите):
    Код (Text):
    1. $PID=ProcessExists("notepad.exe")
    2. $current_thread_id=_WinAPI_GetCurrentThreadId()
    3. $notepad_thread_id=_WinAPI_GetWindowThreadProcessId(WinGetHandle("[CLASS:Notepad]"), $PID)
    4. _WinAPI_AttachThreadInput($current_thread_id, $notepad_thread_id, 1)
    5. _WinAPI_SetFocus(WinGetHandle("[CLASS:Notepad]"))
    6.  
    7. _keybd_event(0x11,0,0,0)
    8. _keybd_event(0x56,0,0,0)
    9. _keybd_event(0x56,0,0x2,0)
    10. _keybd_event(0x11,0,0x2,0)
    Может что-то не так сделал? Или SetFocus и keybd_event не связаны?

    maksim_ я смотрел этот код, и выше написал своё мнение про него. в этом коде я заметил только основные функции вставки и чтения текста из буфера обмена, функцию вставки текста из буфера обмена в какое-либо приложение не заметил, единственно что заметил - это функцию ReplaceSelection, которую как я понял нужно написать самому.

    leo До этого тоже такое пробовал, но не в любое приложение можно вставить текст. В консоль counter-strike не вставляет. В msdn написано, что вставить можно вроде только в edit и сомбо.

    iZzz32 пробовал, SendMessage с WM_PASTE не хочет отправлять туда, куда нужно.
     
  10. Valentin

    Valentin Member

    Публикаций:
    0
    Регистрация:
    2 ноя 2007
    Сообщения:
    128
    Попробуйте послать окну SetForegroundWindow -поверх всех окон, а потом сделать вставку.
     
  11. hunt

    hunt New Member

    Публикаций:
    0
    Регистрация:
    7 ноя 2009
    Сообщения:
    16
    Valentin Спасибо большое :)