WinAPI cannot send text to RGUI

Asked 2 years ago, Updated 2 years ago, 93 views

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

vb.net winapi

2022-09-30 16:34

1 Answers

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.


2022-09-30 16:34

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.