NO

Author Topic: Select text for clipboard  (Read 7975 times)

Offline DonnyDave

  • Member
  • *
  • Posts: 9
Select text for clipboard
« on: March 05, 2024, 11:43:27 AM »
I'm trying to replicate the standard Win10 Cut/Copy/Paste.
In the code below all of pString goes into the clipboard.
How do I select part of on screen text using  left mouse/drag ?
I've searched Petzold and Google and found nothing useful.

  char* pGlobal;
  char* hGlobal;
  char pString[] = "Testing, Testing 123";
  char* pStringptr;
  int i;
 
hGlobal = GlobalAlloc(GHND | GMEM_SHARE, 50);
  if(hGlobal == 0)
    ErrorMessage("1");

  pGlobal = GlobalLock(hGlobal);
  if(pGlobal == 0)
    ErrorMessage("2");

  pStringptr = pString;
  for(i=0 ; i < 20 ; i++)
    *pGlobal++ = *pStringptr++;  //  Copy text to global mem.

  GlobalUnlock(hGlobal);
  OpenClipboard(hwnd);
  EmptyClipboard();

  SetClipboardData(CF_TEXT, hGlobal);
  CloseClipboard();

Offline John Z

  • Member
  • *
  • Posts: 860
Re: Select text for clipboard
« Reply #1 on: March 07, 2024, 12:06:55 PM »
Hi DonnyDave,

Welcome to the forum.

To try to answer your question a clarification is needed.
How do I select part of on screen text using  left mouse/drag ?

Can you clarify this?  What text from the 'screen', from some user open program, from the windows display, from your own windows program text display?

for example for a edit box you might use
Code: [Select]
  lHWND = GetDlgItem(gHWND, idCtrl);
  long long int tsize = SendMessageW(lHWND, WM_GETTEXTLENGTH, 0, 0);
  if (tsize > 0)
  {
    wchar_t *p_buffer = malloc((tsize * 4 * sizeof(wchar_t)) + 20);
    RetVal = SendMessageW(lHWND, WM_GETTEXT, tsize + 1, (LPARAM)p_buffer);
Now text is in p_buffer which can then be sent to the clipboard. 

You can also limit selection by asking for or setting selected text by SendMessage..to the control for example
Code: [Select]
SendMessage(lHWND, EM_GETSEL, (WPARAM)&Cstart, (LPARAM)&Cend);



John


Offline DonnyDave

  • Member
  • *
  • Posts: 9
Re: Select text for clipboard
« Reply #2 on: March 07, 2024, 01:00:04 PM »
Hi John,
"Text from screen" could be any text on anything ( eg. https://forum.pellesc.de/index.php?action=post;topic=11150.0;last_msg=39148 )
LH Mouse anywhere in any text,
LH Mouse drag to anywhere else in the text, (selected portion goes to inverse video),
Ctrl C to copy selected to clipboard.

Dave

Offline John Z

  • Member
  • *
  • Posts: 860
Re: Select text for clipboard
« Reply #3 on: March 08, 2024, 11:10:56 AM »
Hi DonnyDave,

Checking for understanding  -
You are envisioning that a program you wrote is running on a windows system.  This programs purpose is to allow the highlighting of any text displayed on the window screen from anything that is open and displaying some text in its own program?  It does this by first allowing the highlighting of the text using the mouse, then Ctrl+C is executed to copy to the clipboard.....

So -   Several huge hurdles to overcome, imo.

As an initial thing there is the fact that everything shown on the windows screen is only a picture composed of pixels.  There is actually no 'text' available on the screen there are only pictures of text shown.  It is the underlying program that retains/creates the text in 'characters' that are then transformed into pixels and drawn in the programs window display space. This is unlike days of old where the screen was actually a character map of say 24 x 80 that was actually filled with the 'character' to be displayed ie an 'A' in row 1 column 1 was a value of 65 which is capital A.  The underlying screen map could be accessed by any program.

So for your program to use the mouse to highlight some text in my program window you would need to have access to the underlying programs storage of the text being displayed so that character could be retrieved instead of a picture of the characters.

The next hurdle is the once the mouse is over a programs windows space that program controls what the mouse can do.  If hovering over my program and I don't have a routine to do highlighting, or changed the action of the mouse buttons, then there is no way for your program to do that highlighting without developing a hook or other method to intercept the mouse and do your task before sending the mouse to the underlying program. It is the same with the keyboard btw.  When over a programs window the keystrokes go to that window, so there would need to be a hook for that too...

There are intricate ways of doing some of the above but they are very involved. 

It would be a lot easier to program a screen capture program (there are many already) then send the screen picture through an OCR program to recover the 'text' as characters.

Hopefully I've not misunderstood your intention and just went on and on for nothing  ;D

John Z


Offline DonnyDave

  • Member
  • *
  • Posts: 9
Re: Select text for clipboard
« Reply #4 on: March 08, 2024, 05:55:57 PM »
John,
That's correct, I want to incorporate into a win10 prog. I'm about to write (using Pelles C).
Dave

Offline WiiLF23

  • Member
  • *
  • Posts: 89
Re: Select text for clipboard
« Reply #5 on: March 08, 2024, 06:38:55 PM »
I don't really understand the request here, but I am assuming a contextmenu or control that acts as a Copy/Paste for the target string (from Edit control or already stored in clipboard). Obtaining text from Edit control is easy, and you can also "watch" events such as focus and update (this is where you can count string length to perform checks, copy string or simply read string from Edit control among other actions).

This is how I pulled off a responsive Edit control (like typing into Facebook search, same idea - visually). And these events are required for this in my journey:

WM_LBUTTONDOWN
EN_SETFOCUS
EN_KILLFOCUS
EN_CHANGE


eg.
Code: [Select]
case WM_COMMAND:
     case MY_TEXT_CTRL: {
          switch (GET_WM_COMMAND_CMD(wParam, lParam)) {
               case EN_CHANGE: { ... break; }
               // Add more cases
               default:
                    break;
          }
     }
     break;

Just stuff to help. Any string copied into the clipboard is replaced with a new one effectively replacing the last string stored. This applies to OS in general, and all data types it supports for clipboard. Windows also watches and sanitizes copied objects and other data to ensure integrity and security. So it knows when a image is copied from the desktop (BLOB data likely) which allows to insert the image data into accepting applications (like Irfanview), etc.

Strings should be the easiest to work with.

Offline DonnyDave

  • Member
  • *
  • Posts: 9
Re: Select text for clipboard
« Reply #6 on: March 09, 2024, 11:49:14 AM »
This is roughly what I'm trying to do:-

struct                               //  This structure holds every line to be displayed.
  {
  char Contents[MAX_TEXT];
  } DisplayBuffStruct[RTVNUMLINES];

// ------------------------------------------------

    case WM_PAINT :
        hdc = BeginPaint (hwnd, &ps);        // Prepare the window for painting.
// ****************************** Find painting limits ******************************.
          for (n = FirstLine; n <= LastLine; n++)
           {
            TextOut(hdc, 10, y), DisplayBuffStruct[n].Contents, StrLength);    //  Write a line of text from DisplayBuffStruct[].Contents to the client area.
           }
        EndPaint (hwnd, &ps);        // Indicate that painting is finished.
    return 0;


// ------------------------------------------------

void WatchStr(char *TheString, char *TheText)  //  This counts as a declaration of WatchStr()
  {
    if(strlen(TheString) > MAX_TEXT-1)
      {
      MessageBox(NULL, TEXT("Too Big !"), TEXT("WatchStr"), MB_OK);
      exit(0);
      }

    sprintf(DisplayBuffStruct[DispLine++].Contents, "%s = %s", TheText, TheString);


  InvalidateRect(hwnd, NULL, TRUE);
  }
// ------------------------------------------------


I want to copy a selected portion of the text from the screen to the clipboard.

Offline John Z

  • Member
  • *
  • Posts: 860
Re: Select text for clipboard
« Reply #7 on: March 10, 2024, 04:25:41 PM »
Hi DonnyDave,

I think we keep circling the issue.  AFAIK using TextOut to the HDC draws the text in pixels on the DC using the current Font and colors.  The result is a picture of the text, the underlying characters used to draw the picture in terms of ASCII or Unicode character values are not stored anywhere to be retrieved with mouse highlighting and Ctrl+C.

To do that you would need to use a control like an edit box, or RichEdit control.  Using these controls the underlying text is preserved (stored),  The Cursor position can be set within the text display and text can be selected programmatically, Ctrl+C will then work to copy the selected text.

I could be wrong but doing a screen capture and then OCR is the only way I know of for retrieving text written using TextOut directly onto a DC.....If I am I'm sure we will here about it shortly  ;)  ;D

John Z

Offline Ushavilash

  • Member
  • *
  • Posts: 5
Re: Select text for clipboard
« Reply #8 on: April 01, 2024, 08:41:46 AM »
Hey hi, you need to implement text selection functionality within your application. This involves handling mouse events to determine the start and end points of the selection, updating the selection UI accordingly and some more information you can get https://learn.microsoft.com/en-us/windows/win32/api/.

Offline John Z

  • Member
  • *
  • Posts: 860
Re: Select text for clipboard
« Reply #9 on: April 01, 2024, 12:17:02 PM »
Hi Ushavilash,

Welcome to the forum.  Always nice to see new contributors.

I've attached a skeleton program for PellesC that outputs three TextOut lines. See attached image.
If you can add the needed code to grab the text and send to the clipboard that would
be a great help to DonnyDave. (and me too) 

John Z

Offline John Z

  • Member
  • *
  • Posts: 860
Re: Select text for clipboard
« Reply #10 on: April 03, 2024, 03:57:12 PM »
This is roughly what I'm trying to do:- . . . .

What you will see is that programs that use TextOut to write text to the screen also store the text, ASCII or UNICODE characters, in a buffer internal to the program to enable being able highlighting and edit the on screen text if editing is a feature.

When another program is trying to copy 'text' from a program that used TextOut it does not have access to that internal buffer.

Attached is some sample code from Win32 Programmer's Reference WIN32.chm which shows the fundamentals of using TextOut and being able to highlight text once written to the screen using TextOut.  Basically knowing the character starting point, character widths and heights and number of characters per logical line,  one can figure out where in the buffer the characters are from the mouse pointer start point and the mouse pointer end point, the characters can be redrawn highlighted (with TextOut), and if CRTL+C is used then the actual characters are retrieved from the internal character buffer - not directly from the screen.

Hope this helps . . .

John Z

Offline Ushavilash

  • Member
  • *
  • Posts: 5
Re: Select text for clipboard
« Reply #11 on: April 04, 2024, 12:47:59 PM »
Hi Ushavilash,

Welcome to the forum.  Always nice to see new contributors.

I've attached a skeleton program for PellesC that outputs three TextOut lines. See attached image.
If you can add the needed code to grab the text and send to the clipboard that would
be a great help to DonnyDave. (and me too) 

John Z

Ohh, thanks for posting with attachment sure I'll try. If this happens then I'll reach you.

Offline DonnyDave

  • Member
  • *
  • Posts: 9
Re: Select text for clipboard
« Reply #12 on: August 06, 2024, 05:38:02 PM »
I didn't specify the problem correctly !
I'm OK with adding a text buffer to the clipboard and pasting it to another app,
I can't workout how to select some part of the text from the (screen) buffer using the mouse.
« Last Edit: August 07, 2024, 03:15:36 PM by DonnyDave »

Offline John Z

  • Member
  • *
  • Posts: 860
Re: Select text for clipboard
« Reply #13 on: August 07, 2024, 10:20:42 PM »
Hi DonnyDave,

Have you looked at the posting above on April 03, 2024, 03:57:12 PM?  It has most of the information you need in the example code pdf.  The only addition would be to add the character position in the line rather than the entire line.  To do that you still get the mouse coordinates, starting and ending, and use them to calculate the buffer start and stop positions by knowing the approximate character width(s).  Line number is by height and character position within a line is by knowing character width.  Of course you need access to the buffer holding the original text to access once you know where in the buffer to grab.

Suggest you get the select by line working first then add in the select from character to character.

John Z