-1

I've already realized application that can getting selected text by emulating ctr+c keypress.

So, now I have 3 working methods:

    // Using InputSimulator library
    private static void CtrlC_inputSimulator()
    {
        var hWnd = GetWindowUnderCursor();
        SetActiveWindow(hWnd);

        InputSimulator i = new InputSimulator();
        i.Keyboard.ModifiedKeyStroke(VirtualKeyCode.CONTROL, VirtualKeyCode.VK_C);
    }

    // Using SendKey
    private static void CtrlC_SendKey()
    {
        try
        {
            SendKeys.Send("^(c)");
        }
        catch(Exception ex) { }
    }

    // Using native user32 keybd_event directly
    private void CtrlC_KeybdEvent_User32()
    {
        uint KEYBD_EVENT_KEYUP = 2;

        var hWnd = GetWindowUnderCursor();
        SetForegroundWindow(hWnd);

        // Ctrl-C Down
        keybd_event(KEY_CONTROL, 0, 0, 0);
        keybd_event(KEY_C, 0, 0, 0);
        // Ctrl-C Up
        keybd_event(KEY_C, 0, KEYBD_EVENT_KEYUP, 0);
        keybd_event(KEY_CONTROL, 0, KEYBD_EVENT_KEYUP, 0);
    }

But in practice it's not stable way to use keypress simulation.

And I thought about how to get the selected text using system messages such as WM_GETTEXT, but as far as I know, most of these things are only working with rich text box, and will not work in programs such as Chrome or AcrobatReader.

Tell me please, is there a function or some librery than can do it?

Letfar
  • 3,253
  • 6
  • 25
  • 35
  • It will work even with selection in browser? – Letfar Oct 13 '15 at 09:42
  • In addition to this being unreliable, you're also clobbering the clipboard. What goes into the clipboard ought to be under the *users* control, not your application. – Damien_The_Unbeliever Oct 13 '15 at 09:43
  • Why did you reject automation in the first place, and decide to implement the gross hack that can be found in the question? – David Heffernan Oct 13 '15 at 09:45
  • use SendMessage(HWND,WM_COPY,0,0); hwnd can be GetFocus() for example – milevyo Oct 13 '15 at 12:31
  • WM_COPY works with text fields only, or I'm wrong? – Letfar Oct 13 '15 at 12:33
  • 1
    @milevyo: `WM_COPY` is only applicable, if the particular control is hosted in a native window. This is in general not the case, for any browser. Even if it were, the clipboard belongs to the user, not your application. Don't thrash it. – IInspectable Oct 13 '15 at 15:48
  • the only mistake i did (maybe) is using GetFocus instead of GetForegroundWindow(). any one can implement WM_COPY. well @ IInspectable you didn't say hi :) – milevyo Oct 13 '15 at 18:04
  • 1
    @Letfar, the documentation of microsoft says how edit control (including richedit) and comboboxs react to this message, and how to send this message to them (parameters). but it's up to any one to implement this in his application. try it ... (and it will works) – milevyo Oct 13 '15 at 18:08
  • @milevyo: `GetForegroundWindow` returns a **top-level** window. Keyboard focus, however, is usually on a **child** window. If you need to find the focus window of the foreground thread, call [GetGUIThreadInfo](https://msdn.microsoft.com/en-us/library/windows/desktop/ms633506.aspx). Of course, none of this will yield the desired result when used with an application, that uses window-less controls (like all mainstream browsers do). There's no need to try, since it cannot work. You'll have to use another approach, like [UI Automation](https://msdn.microsoft.com/en-us/library/ms747327.aspx). – IInspectable Oct 14 '15 at 11:58
  • @ IInspectable, exactly, since those mainstream browsers are (have) window-less controls, they are responsible to deal with WM_COPY. that why i used GetForegroundWindow , i don't have to deal with controls. – milevyo Oct 14 '15 at 12:48
  • if you want i can paste here a working code (vb6) to demonstrate that – milevyo Oct 14 '15 at 12:49
  • @milevyo: Where did you find documentation, that mandates a window-less control's host window to respond to `WM_COPY` messages? You are making up rules, that do not exist. The standard interface for automation and introspection is [UI Automation](https://msdn.microsoft.com/en-us/library/ms747327.aspx). Going that route has a number of advantages: Failed operations are observable, and it won't thrash the user's clipboard, for example. – IInspectable Oct 14 '15 at 13:40
  • do you need documentation or whatever to implement WM_COPY in your app?. if you can not find documentation for some thing, there is what is called reverse engineering. and reverse engineering start by guessing following some logic and doing tests. in my case i guessed, tested and it worked. do you tell me now that my results are false because there is no documentation that prove that. I know, implementing these technics in a productive software is not clever. but to resolve a problem and ease my life, is as clever as it sounds. – milevyo Oct 14 '15 at 13:50

1 Answers1

-1
// Using native user32 Copy Message
private void User32_Copy()
{
    uint WM_COPY = 0x0301;

    var hWnd = GetWindowUnderCursor();
    // SetForegroundWindow(hWnd);

    SendMessage(hWnd,WM_COPY,0,0);
}
milevyo
  • 2,165
  • 1
  • 13
  • 18
  • Calling `SendMessage` with a window handle that is outside your control is a bug. Always use [SendMessageTimeout](https://msdn.microsoft.com/en-us/library/windows/desktop/ms644952.aspx) in a scenario like that. I don't understand the commented out line with a call to `SetForegroundWindow`. What's the rationale for that? – IInspectable Oct 15 '15 at 13:08
  • @IInspectable, yes indeed, SendMessage will send and wait for a response, its friend PostMessage is Send 'n Forget. these functions are the most common and easy to use. SendMessageTimeout less common and is a solution when SendMessage risk to bloc waiting for a message that take a long time to respond. but SendMessage has never been considered as a bug. if you think so please post us a link from Microsoft that says that. – milevyo Oct 15 '15 at 16:30