If WM_COPY fails, there are a few avenues you could try...
To fake a keypress you can send WM_KEYDOWN and WM_KEYUP messages.
However, what do you send in the message? If you send a "c", then there is no way in these messages for you to inform the application that ctrl was also held down.
You may be able to send a character 0x03 (which is the character code that ctrl+c actually generates), but there is no guarantee that the receiving application will interpret this as a "ctrl+c" action.
Why might it not work? The receiving application might...
- ignore WM_KEYDOWN and WM_KEYUP and use other means to read the keyboard (e.g. GetAsyncKeyState to see if a key is down)
- handle WM_KEYDOWN and/or WM_KEYUP messages, but look for "c" and then use GetAsyncKeyState() or similar to detect if ctrl is down when the message is processed.
- It might still ignore the messages if it doesn't have input focus, or worse, action those messages as though they were received through the input focus window.
So - give it a try, but it may not work.
Alternatively, if SendInput works, then you could just force the input focus to the correct control, SendInput, and then restore the input focus to its previous location.
Another approach (possibly the best one) is if it is a dialog known to you and it contains a static text field, you may just be able to find that child control and GetText on it (send WM_GETTEXT message), and avoid using the clipboard at all. (Or if you need the text on the clipboard, get it like this and then place it on the clipboard yourself). This would avoid tricking the application into providing the text, and fall back to standard Windows behaviour.