Given that there is pre-existing text on a Windows 11 console, how can all of the text be copied to the clipboard using C or C++?
That is, I want to do the programmatic equivalent of dragging with a mouse across all of the text to select it and then pressing Ctrl-C so that it's captured into the clipboard.
Here is the solution as requested. This code is tested in MS Visual Studio and Windows OS 10 by me just now.
Please note that this is non-portable Windows code because OP has asked for a solution specifically related to the Windows OS and has tagged winapi
.
This program prints a string to the console window, then captures/scrapes the text from the screen/console window via windows API ReadConsoleOutputCharacter().
The text data is then copied to the windows clipboard buffer.
#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;
}