Send Keystroke to Another App WITHOUT Focus

Ken Krugh 116 Reputation points
2021-07-30T14:51:58.95+00:00

I need to send up and down arrow keys to another app with VB. Activating that app, using SendKeys, the REactivating my app is working, but it's not all that reliable.

I've gotten both SendMessage and PostMessage to work but as with SendKeys the receiving app has to be active. The activating is what I'm thinking might be the problem. I saw mention of a SendString and SendInput APIs but it seems they both need to have the receiving app have the focus as well, which kind of makes sense.

Is there another method that might simulate an arrow key without the receiving app having the focus? And/or does anyone know if using SendMessage might be more reliable than SendKeys?

Thanks!
Ken

Developer technologies | Visual Basic for Applications
0 comments No comments
{count} votes

5 answers

Sort by: Most helpful
  1. Sam of Simple Samples 5,546 Reputation points
    2021-07-30T17:33:52.347+00:00

    See my Clicking a Button in Another Application. The general idea is that it sends a button clicked message to the window that contains the button; in other words, instead of sending a mouse click or a keyboard Enter key it sends the message that such action would result in. The concepts in that article can help you; you can use Spy++ to determine what messages (message id and dialog id as relevant) are the result of up and down arrow keys. If you can determine that then using SendMessage can be very reliable.

    With hWnd being set to the edit control in a Notepad instance the following moves the cursor down a line in it. Notepad is not the active window because I execute the following from VS without activating the Notepad instance. It works even if Notepad is minimized.

    uint lParam = (0x00000001 | (MapVirtualKey(0x30, 0) << 16));
    SendMessage(hWnd, WM_KEYDOWN, (IntPtr)VK_DOWN, (IntPtr)lParam);
    
    1 person found this answer helpful.
    0 comments No comments

  2. Tom van Stiphout 1,861 Reputation points MVP Volunteer Moderator
    2021-07-30T14:55:15.453+00:00

    I've gotten both SendMessage and PostMessage to work but as with SendKeys the receiving app has to be active

    That may be true for YOUR app, but it is not generally true. You can SendMessage or PostMessage to any hWnd.


  3. Ken Krugh 116 Reputation points
    2021-07-30T15:20:51.57+00:00

    So you're saying either of those APIs should work without the receiving app having the focus?

    By "YOUR" app are you referring to the sending or the receiving app?

    I'm sending the arrow keys to an Acrobat window. As I say, that works when it has the focus. What's interesting is that using the same method trying to send the down arrow to Word or Notepad DOESN'T work.

    So maybe all of this is a matter of how the receiving app takes the input?


  4. Ken Krugh 116 Reputation points
    2021-08-01T17:47:54.22+00:00

    Thanks so much guys! I at least initially started down the right path.

    Given what what Castorix31 says worked, I'm missing something with FindWindowEx and Acrobat. It's the comments panel I ultimately need but for testing I've been working with the main Window for which Castorix31 indicates AVPageView which I also saw in Spy++, but I keep getting zero back from FindWindowEx.

    I've got Acrobat XI and Acrobat DC available and both show the same thing in Spy++:
    119637-capture.jpg

    I'm 99% sure the window handle I'm passing to FindWindowEx (the main window in WinHWnd&) is correct, according to Spy++ but I'm always getting back zero.

    My call looks like this:

    PgHWnd& = FindWindowEx(WinHWnd&, 0, "AVL_AVView", "AVPageView")  
    

    And I've tried every combo I can think of parameters I can think of including vbNull instead of the zero and vbNullString for one of the lpstrings.

    What the @#$%^! am I missing?!

    Thanks again

    0 comments No comments

  5. Castorix31 90,681 Reputation points
    2021-08-01T19:43:44.877+00:00

    You must check the hierarchy of Windows to find the "AVPageView" class
    For Acrobat, it is complex on my version :

    119682-acrobat-hierarchy.jpg

    So this works for me, in VB.NET (you will have to adapt it for VBA) :

                Dim hWndAcrobat As IntPtr = FindWindow("AcrobatSDIWindow", Nothing)  
                Dim hWndFlipContainerView As IntPtr = FindWindowEx(hWndAcrobat, 0, Nothing, "AVFlipContainerView")  
                Dim hWndDocumentMainView As IntPtr = FindWindowEx(hWndFlipContainerView, 0, Nothing, "AVDocumentMainView")  
                Dim hWndFlipContainerView2 As IntPtr = FindWindowEx(hWndDocumentMainView, 0, Nothing, "AVFlipContainerView")  
                Dim hWndSplitterView As IntPtr = FindWindowEx(hWndFlipContainerView2, 0, Nothing, "AVSplitterView")  
                Dim hWndSplitationPageView As IntPtr = FindWindowEx(hWndSplitterView, 0, Nothing, "AVSplitationPageView")  
                Dim hWndSplitterView2 As IntPtr = FindWindowEx(hWndSplitationPageView, 0, Nothing, "AVSplitterView")  
                Dim hWndScrolledPageView As IntPtr = FindWindowEx(hWndSplitterView2, 0, Nothing, "AVScrolledPageView")  
                Dim hWndScrollView As IntPtr = FindWindowEx(hWndScrolledPageView, 0, Nothing, "AVScrollView")  
                Dim hWndPageView As IntPtr = FindWindowEx(hWndScrollView, 0, Nothing, "AVPageView")  
                PostMessage(hWndPageView, WM_KEYDOWN, VK_DOWN, 0)  
                'PostMessage(hWndPageView, WM_KEYDOWN, VK_NEXT, 0)  
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.