2

I'm attempting to send automated keystrokes to an application that does not support copy+paste via a small VB form. The form loads data from a text file and uses SendKeys to fire it over once I click a button.

Everything appears to work except for the ShowWindow portion. I'm currently testing using Notepad and, with one exception, I can't seem to get ShowWindow to kick focus to Notepad. Obviously I'm worried it will do the same to the application I'll eventually be running this against (I don't currently have access to it). The only ShowWindow parameter that makes Notepad active is SW_SHOWMAXIMIZED. SW_SHOW and SW_SHOWNORMAL don't appear to do anything while SW_RESTORE will restore Notepad if minimized but my VB form remains the active window.

I'm not a programmer but I had made the mistake of telling my boss I dabbled in Pascal Turbo in high school (over a decade ago) so I'm the one stuck with trying to make this work. My current code cobbled together from S.O. and other sources:

(I'm running Windows 7 and using MVSE2013)

Imports System.Runtime.InteropServices
Public Class Form1
Private Declare Function FindWindow _
       Lib "user32" _
       Alias "FindWindowA" _
      (ByVal lpClassName As String, _
       ByVal lpWindowName As String) As IntPtr

<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function ShowWindow(ByVal hwnd As IntPtr, ByVal nCmdShow As ShowWindowCommands) As Boolean
End Function

Enum ShowWindowCommands As Integer
    SW_SHOWNORMAL = 1
    SW_SHOWMAXIMIZED = 3
    SW_RESTORE = 9
End Enum

Private Sub Form1_Load
    [form]
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click

    Dim lHwnd As IntPtr = FindWindow("Notepad", vbNullString)

    If lHwnd <> IntPtr.Zero Then
        ShowWindow(lHwnd, ShowWindowCommands.SW_SHOWNORMAL)
        SendKeys.Send(TextBox1.Text)
    Else
        [blah blah error handling]
    End If

End Sub

I'd try another technique like SetForegroundWindow but I read it doesn't play nice with Windows 7.

FrankWesterly
  • 88
  • 1
  • 8

1 Answers1

0

Found what I hope will be a passable workaround from PInvoke. I ended up swapping this block:

<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function ShowWindow(ByVal hwnd As IntPtr, ByVal nCmdShow _
As ShowWindowCommands) As Boolean
End Function

For this:

Public Declare Function BringWindowToTop Lib "user32" (ByVal hwnd As IntPtr) As Boolean

And then this line:

ShowWindow(lHwnd, ShowWindowCommands.SW_SHOWNORMAL)

For this:

BringWindowToTop(lHwnd)

I realize there are functional differences between the two but the change works in my specific instance so I'm happy.

FrankWesterly
  • 88
  • 1
  • 8