Программное перемещение текста консоли в буфер обмена на C или C++

Учитывая, что на консоли Windows 11 уже существует текст, как можно скопировать весь текст в буфер обмена с помощью C или C++?

То есть я хочу сделать программный эквивалент перетаскивания мышью по всему тексту, чтобы выделить его, а затем нажать Ctrl-C, чтобы он был захвачен в буфер обмена.

🤔 А знаете ли вы, что...
C++ был разработан в начале 1980-х годов Бьярном Страуструпом в Bell Labs.


76
1

Ответ:

Решено

Вот решение, как просили. Этот код я только что протестировал в MS Visual Studio и Windows OS 10.

Обратите внимание, что это непереносимый код Windows, поскольку OP запросил решение, конкретно связанное с ОС Windows, и отметил winapi.

Эта программа выводит строку в окно консоли, затем захватывает/удаляет текст из окна экрана/консоли через Windows API ReadConsoleOutputCharacter().

Текстовые данные затем копируются в буфер обмена Windows.

#include <windows.h>
#include <stdio.h>
#include <conio.h>

/*-------------------------------------------------------------------------

  copy_to_clipboard()

  Adapted from https://stackoverflow.com/a/1264179/3130521
  Credits: Judge Maygarden
*--------------------------------------------------------------------------*/
BOOL copy_to_clipboard(char *pBuff)
{
    size_t size = strlen(pBuff)+1;
    if (size > 1)
    {
        HGLOBAL hMem =  GlobalAlloc(GMEM_MOVEABLE, size);
        memcpy(GlobalLock(hMem), pBuff, size);
        GlobalUnlock(hMem);
        OpenClipboard(0);
        EmptyClipboard();
        SetClipboardData(CF_TEXT, hMem);
        CloseClipboard();
        return TRUE;
    }
    return FALSE;
}

int main() 
{
    /* Get the handle to the console window*/
    HANDLE hConOut = GetStdHandle(STD_OUTPUT_HANDLE);
    CONSOLE_SCREEN_BUFFER_INFO CSBI;
    int win_w,win_h,size;
    char *tbuff;
    DWORD num_chars_read;
    COORD   dwReadCoord = {0,0}; /* Read from screen top, left (0,0) */

    if (hConOut == INVALID_HANDLE_VALUE)
    {
        printf("STDOUT not available.\n");
        return 0;
    }

    /* Put some text to the screen */
    printf("This text should match the contents of the clipboard buffer on completion.\n");

    /* Get console window dims, potential text size, allocate buffer to that size */
    GetConsoleScreenBufferInfo( hConOut, &CSBI );
    win_w=CSBI.srWindow.Right - CSBI.srWindow.Left+1;
    win_h=CSBI.srWindow.Bottom - CSBI.srWindow.Top+1;
    size = win_w*win_h;
    tbuff = malloc(size+1);
    if (!tbuff)
    {
        printf("malloc() failed!\n");
        return 0;
    }

    /* Capture the text from the console window*/
    if (!ReadConsoleOutputCharacter( hConOut, tbuff, size,dwReadCoord, &num_chars_read))
    {
        free(tbuff);
        printf("ReadConsoleOutputCharacter() failed!\n");
        return 0;
    }

    /* Strip trailing whitepace (there should be a lot!)*/
    while(num_chars_read && tbuff[num_chars_read-1] == ' ')
        tbuff[--num_chars_read] = '\0';

    /* Copy text to the clipboard*/
    if (!copy_to_clipboard(tbuff))
    {
        free(tbuff);
        printf("copy_to_clipboard() failed!\n");
        return 0;
    }

    free(tbuff);  /* Always free() */

    /* Notify user done */
    printf("All done. Success. Open notepad and paste from clipboard.\n");
    _getch(); /* wait key press */

    return 0;
}