Thank you for your help.
We are creating an app that sends command text to the GUI version of the statistics and analysis environment "R" in Windows 7.
I succeeded in obtaining RGUI's parent window handle, MDI's window handle, and RConsole's own handle using FindWindowEx function.
*Check the handle with WinSpector
I'm going to skip the string with the SendMessage function to the handle I got, but they don't enter any characters.
I think there is no problem because I have obtained the window handle itself, but is there anything missing?
I would appreciate it if you could suggest it.
Thank you for your cooperation.
Option Strict Off
Option Explicit On
Friend Class Form 1
Inherits System.Windows.Forms.Form
'Class name, get child window handle from caption
Private Declare Function FindWindowEx Lib "user32.dll "Alias "FindWindowExA" (ByVal hwndParent As Integer, ByVal hwndChildAfter As Integer, ByVal lpClassName As String, ByVallpWindowName As String) As Integer
Private Declare Function SendMessage Lib "user32.dll "Alias "SendMessageA" (ByVal hWnd As Integer, ByVal Msg As Integer, ByValwParam As Integer, ByVallParam As String) As Integer
Private Const WM_IME_CHARAs Short=&H286S' Character Code Sent
Private Const WM_SETTEXT As Short=&HCS' string transmission
Private SubCommand1_Click(ByVal eventSenderAsSystem.Object,_
ByVal eventArgs As System.EventArgs) Handles Command 1.Click
DimlnghWnd As Integer 'Top Level (parent) window handle
DimnghWndMDIAs Integer
DimlnghWndTarget As Integer' target (child) window handle
DimngRc As Integer' API Return Values
lngRc=Shell("C:\Program Files\R\R\3.3.1\bin\x64\Rgui.exe", AppWinStyle.NormalFocus)
System.Threading.Thread.Sleep (3000)
'
'-------------------------------------
' Obtain the handle of the target window
'-------------------------------------
lnghWnd=FindWindowEx(0,0, "Rgui Workspace", "Rgui(64-bit)")
lnghWndMDI=FindWindowEx(lnghWnd, 0, "MDIClient", "")
lnghWndTarget=FindWindowEx(lnghWndMDI, 0, "Rgui Document", "R Console")
'-------------------------------------
' sending
'-------------------------------------
DimstrDt As String
'-------------------------------------
' 50mm (0.05) second interval sent one character at a time
'-------------------------------------
DimngDt As Integer
Dimi As Integer
Fori=1 To Len(Text1.Text) 'Repeat for a few minutes
strDt=Mid(Text1.Text,i,1)'1 character
lngDt = convert to Asc(strDt)'ASCII code
lngRc = SendMessage(lnghWndTarget, WM_IME_CHAR, lngDt, 0) 'One character transmission
System.Threading.Thread.Sleep(50) 'Wait specified milliseconds
Next i
End Sub
Private SubForm1_Load(ByVal eventSenderAsSystem.Object,_
ByVal eventArgs As System.EventArgs) Handles MyBase.Load
Text1.Text="q()" & vbCrLf
End Sub
Private SubForm1_FormClosing(ByVal eventSenderAsSystem.Object,_
ByVal eventArgs As System.Windows.Forms.FormClosingEventArgs)Handles Me.FormClosing
Dim Cancel As Boolean= eventArgs.Cancel
Dim UnloadMode As System.Windows.Forms.CloseReason=eventArgs.CloseReason
End
eventArgs.Cancel=Cancel
End Sub
End Class
Key entry is not as simple as completing a single Window Message.Not only key down/key up, but also key state management such as Shift/Ctrl/Alt.For native code, use SendInput
, but for .NET, use SendKeys.SendWait
.See the SendKeys class description for information on handling special keys, such as {ENTER}
for Enter keys.
Then, since keystrokes are not tied to an application and are made for an active window, you must configure them in the SetActiveWindow
before they can be activated, and you must put them must be front-facing in the SetForegroundWindow
SetForegroundWindow(lnghWndTarget)
SetActiveWindow(lnghWndTarget)
SendKeys.SendWait("q{(}{)}{ENTER}")
Apart from that, I use 32-bit Integer
for HWND
, but it looks like a 64-bit environment, so it should be IntPtr
.
© 2024 OneMinuteCode. All rights reserved.