Jump to content

Issues with _keysend via user32.dll


dubi
 Share

Recommended Posts

Hi

I am trying to send a double digit number to a control with the function enclosed. The issue is that as long as I send single digit numbers (ie 1 to 9) it works ok. But I encounter several issues when running the code below:

  1.  Winspector reports an error (WM_KEYUP Virtual Key: Unknown key(49) after processing command                
        DllCall("user32.dll", "int", "PostMessage", _      
                            "hwnd", $hWnd, _                        
                            "int", 0x101, _                            
                            "int", Asc(StringMid($keys, $i, 1)), _
                            "long", _MakeLong(1, $ret[0]) + 0xC0000000)
  2. When I try to send a multi digit number (e.g. 13) then the control takes over 1 first and then 1 is then overridden by the 3. So the control then shows only "3" when finished. But I need to have "13" in the control when done.
  3. When I hand over severl numbers (ie not multi digit numbers) to the control, the last number will only be written into the field but it will not be "entered" so the control takes over the value.

The control I am trying to automate is called "XTPReport" if this is of help. And I am using the approach here as I need to manipulate the control while the main window is minimized.

 

Any help is highly appreciated :)

Thank you

-dubi

Func _SendKeys1($hWnd, $keys, $x, $Y)
    Local $MK_LBUTTON = 0x0001
    Local $WM_LBUTTONDOWN = 0x0201
    Local $WM_LBUTTONUP = 0x0202

    Local $MK_RBUTTON = 0x0002
    Local $WM_RBUTTONDOWN = 0x0204
    Local $WM_RBUTTONUP = 0x0205
    Local $WM_MOUSEMOVE = 0x0200
    Local $WM_MOUSEACTIVATE = 0x0021
    Local $i = 0
    Local $i, $ret
    Local $shiftdown = False
    $Button = $MK_LBUTTON
    $ButtonDown = $WM_LBUTTONDOWN
    $ButtonUp = $WM_LBUTTONUP

    If $hWnd <= 0 Or StringLen($keys) = 0 Then
        SetError(-1)
        Return False
    EndIf
    $keys = StringUpper($keys)
    $keys = StringReplace($keys, "`", Chr($VK_OEM_3))
    $keys = StringReplace($keys, "~", Chr($VK_OEM_3))
    $keys = StringReplace($keys, "-", Chr($VK_OEM_MINUS))
    $keys = StringReplace($keys, "=", Chr($VK_OEM_PLUS))
    $keys = StringReplace($keys, "{ENTER}", Chr(0xD))
    $keys = StringReplace($keys, "{TAB}", Chr(0x9))
    $keys = StringReplace($keys, "{ESC}", Chr($VK_ESC))
    $keys = StringReplace($keys, "{F5}", Chr($VK_F5))
    $keys = StringReplace($keys, "{F12}", Chr($VK_F12))
    $keys = StringReplace($keys, "{SHIFT}", "+")
    ; select the first row in the control (control consists of several rows)
    DllCall("user32.dll", "int", "SendMessage", _
            "hwnd", $hWnd, _
            "int", $WM_MOUSEMOVE, _
            "int", 0, _
            "long", _MakeLong($x, $Y))
    Sleep(100)

    DllCall("user32.dll", "int", "SendMessage", _
            "hwnd", $hWnd, _
            "int", $ButtonDown, _
            "int", $Button, _
            "long", _MakeLong($x, $Y))
    Sleep(100)

    DllCall("user32.dll", "int", "SendMessage", _
            "hwnd", $hWnd, _
            "int", $ButtonUp, _
            "int", $Button, _
            "long", _MakeLong($x, $Y))
    Sleep(100)

    For $i = 1 To StringLen($keys)
        If StringMid($keys, $i, 1) = "+" Then ; Shift?
            DllCall("user32.dll", "int", "PostMessage", _
                    "hwnd", $hWnd, _
                    "int", 0x100, _
                    "int", 0x10, _
                    "long", 0x002A0001)

            DllCall("user32.dll", "int", "PostMessage", _
                    "hwnd", $hWnd, _
                    "int", 0x100, _
                    "int", 0x10, _
                    "long", 0x402A0001)
            $shiftdown = True
            Sleep(100)
            ContinueLoop
        Else
            $ret = DllCall("user32.dll", "int", "MapVirtualKey", _
                    "int", Asc(StringMid($keys, $i, 1)), _
                    "int", 0)
            If IsArray($ret) Then
                DllCall("user32.dll", "int", "PostMessage", _
                        "hwnd", $hWnd, _
                        "int", 0x100, _
                        "int", Asc(StringMid($keys, $i, 1)), _
                        "long", _MakeLong(1, $ret[0]))
                Sleep(100)

                DllCall("user32.dll", "int", "PostMessage", _    
                        "hwnd", $hWnd, _                         
                        "int", 0x101, _                          
                        "int", Asc(StringMid($keys, $i, 1)), _ 
                        "long", _MakeLong(1, $ret[0]) + 0xC0000000) 
            EndIf
        EndIf
        If $shiftdown Then
            Sleep(1)
            DllCall("user32.dll", "int", "PostMessage", _
                    "hwnd", $hWnd, _
                    "int", 0x101, _
                    "int", 0x10, _
                    "long", 0xC02A0001)
            $shiftdown = False
        EndIf
    Next
    Return True
EndFunc   ;==>_SendKeys1

 

Link to comment
Share on other sites

yes, I did. When I change the code as follows I am getting the (mostly) same result as with the dll-calls: When I try to enter "13" I can see 1 which will be overridden by a 3 afterwards.  I have tried both versions of controlsend (flag 0 and flag 1). I thought to stay with the dll calls as I was hoping to have more control this way....

When I enter numbers manually (with keyboard) I can enter multi digit numbers :'(

The adjusted code with controlsend is here for info (I am still using the first dll calls to select the first row in the control as the control is sort of a table...

Func _SendKeys1($hWnd, $keys, $x, $Y)
    Local $MK_LBUTTON = 0x0001
    Local $WM_LBUTTONDOWN = 0x0201
    Local $WM_LBUTTONUP = 0x0202

    Local $MK_RBUTTON = 0x0002
    Local $WM_RBUTTONDOWN = 0x0204
    Local $WM_RBUTTONUP = 0x0205
    Local $WM_MOUSEMOVE = 0x0200
    Local $WM_MOUSEACTIVATE = 0x0021
    Local $i = 0
    Local $i, $ret
    Local $shiftdown = False
    $Button = $MK_LBUTTON
    $ButtonDown = $WM_LBUTTONDOWN
    $ButtonUp = $WM_LBUTTONUP

    If $hWnd <= 0 Or StringLen($keys) = 0 Then
        SetError(-1)
        Return False
    EndIf
    $keys = StringUpper($keys)
    $keys = StringReplace($keys, "`", Chr($VK_OEM_3))
    $keys = StringReplace($keys, "~", Chr($VK_OEM_3))
    $keys = StringReplace($keys, "-", Chr($VK_OEM_MINUS))
    $keys = StringReplace($keys, "=", Chr($VK_OEM_PLUS))
    $keys = StringReplace($keys, "{ENTER}", Chr(0xD))
    $keys = StringReplace($keys, "{TAB}", Chr(0x9))
    $keys = StringReplace($keys, "{ESC}", Chr($VK_ESC))
    $keys = StringReplace($keys, "{F5}", Chr($VK_F5))
    $keys = StringReplace($keys, "{F12}", Chr($VK_F12))
    $keys = StringReplace($keys, "{SHIFT}", "+")

    DllCall("user32.dll", "int", "SendMessage", _
            "hwnd", $hWnd, _
            "int", $WM_MOUSEMOVE, _
            "int", 0, _
            "long", _MakeLong($x, $Y))
    Sleep(100)

    DllCall("user32.dll", "int", "SendMessage", _
            "hwnd", $hWnd, _
            "int", $ButtonDown, _
            "int", $Button, _
            "long", _MakeLong($x, $Y))
    Sleep(100)

    DllCall("user32.dll", "int", "SendMessage", _
            "hwnd", $hWnd, _
            "int", $ButtonUp, _
            "int", $Button, _
            "long", _MakeLong($x, $Y))
    Sleep(100)
    ControlSend($avChildren[$erg][0], "", "[CLASS:XTPReport; INSTANCE:1]", $keys,1)
    Exit
    ...

 

Link to comment
Share on other sites

The solution is....

After some more investigation with "Window Detective" I have seen that the XTPReport control creates another control of the class "Edit" after the respective row in the XTPReport control has been clicked on. I am now able to set the text of the Edit control and done :-) ... and yes - this all works with controlSetText, Controlclick. So it was really easy once I have detected the Edit-control!

So I am all set now :-)

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...