Alan Sloan said:
I have a vb.net app in which I have setup a "hotkey" where when the user
types that key combo, something is supposed to happen. The hotkey part is
working and fires perfectly. What this is supposed to do, is copy whatever
text is selected, no matter where the user is in the system, either my app,
notepad, whatever, and copy that text to the clipboard.
I have tried SendMessage API, VB's SendKeys, and It only seems to work
sometimes. I would prefer to use SendMessage with a WM_COPY but can't get
it to work at all, so I've been using SendKeys, sending "^c" with sporatic
results.
Below is code to get the window with the focus, and copies the selection to
the clipboard. GetForegroundWindow() gets the main window handle, like
Notepad's main window, not the text box control within it. There is another
function that would get the text box handle, GetFocus(), but it require more
works to make it work with other processes. The code below uses
GetGUIThreadInfo(), then gets the text box handle using hwndFocus member.
To try the sample, add a Timer, and a TextBox to Form1. Set the TextBox's
Mutliline property to True, and set the Timer interval to 5000. Run the
project, then start Notepad, type some text then select it.
Option Explicit On
Public Class Form1
Private Declare Function GetForegroundWindow Lib "user32" () As Integer
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal
hWnd As Integer, ByRef lpdwProcessId As Integer) As Integer
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA"
(ByVal hWnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer,
ByVal lParam As Integer) As Integer
Private Declare Function GetGUIThreadInfo Lib "user32.dll" (ByVal
idThread As Integer, ByRef pgui As GUITHREADINFO) As Integer
Private Const WM_COPY As Integer = &H301
Private Structure RECT
Dim Left_Renamed As Integer
Dim Top As Integer
Dim Right_Renamed As Integer
Dim Bottom As Integer
End Structure
Private Structure GUITHREADINFO
Dim cbSize As Integer
Dim flags As Integer
Dim hwndActive As Integer
Dim hwndFocus As Integer
Dim hwndCapture As Integer
Dim hwndMenuOwner As Integer
Dim hwndMoveSize As Integer
Dim hwndCaret As Integer
Dim rcCaret As RECT
End Structure
Private Function GetFocusWindow() As Integer
Dim h As Integer
Dim ThreadID As Integer
Dim gui As GUITHREADINFO
Dim ret As Integer
h = GetForegroundWindow()
Console.WriteLine("GetFocusWindow: ForegroundWindow = " & Hex(h))
ThreadID = GetWindowThreadProcessId(h, 0)
gui.cbSize = Len(gui)
ret = GetGUIThreadInfo(ThreadID, gui)
If ret = 0 Then
Console.WriteLine("GetFocusWindow: GetGUIThreadInfo failed.
LastDllError = " & Err.LastDllError)
Exit Function
End If
Console.WriteLine("GetFocusWindow: hwndFocus = " &
Hex(gui.hwndFocus))
GetFocusWindow = gui.hwndFocus
End Function
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Timer1.Tick
Me.Text = Hex(GetFocusWindow())
SendCopyToWindow(GetFocusWindow())
TextBox1.Text = Clipboard.GetText
End Sub
Private Sub SendCopyToWindow(ByVal hWnd As Integer)
SendMessage(hWnd, WM_COPY, 0, 0)
End Sub
End Class