简体   繁体   English

VB:ShowWindow焦点问题

[英]VB: ShowWindow focus issue

I'm attempting to send automated keystrokes to an application that does not support copy+paste via a small VB form. 我试图通过一个小的VB表单将自动击键发送到不支持复制+粘贴的应用程序。 The form loads data from a text file and uses SendKeys to fire it over once I click a button. 表单从文本文件加载数据,并在单击按钮后使用SendKeys将其触发。

Everything appears to work except for the ShowWindow portion. 除了ShowWindow部分,其他所有内容似乎都可以正常工作。 I'm currently testing using Notepad and, with one exception, I can't seem to get ShowWindow to kick focus to Notepad. 我目前正在使用记事本进行测试,除了一个例外,我似乎无法让ShowWindow将重点放在记事本上。 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. 使记事本处于活动状态的唯一ShowWindow参数是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. SW_SHOW和SW_SHOWNORMAL似乎没有执行任何操作,而SW_RESTORE如果将其最小化,它将恢复记事本,但我的VB表单仍处于活动窗口。

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. 我不是程序员,但我犯了一个错误,就是告诉我的老板,我在高中(十多年前)涉足Pascal Turbo,所以我就是一个试图完成这项工作的人。 My current code cobbled together from SO and other sources: 我当前的代码从SO和其他来源整理而来:

(I'm running Windows 7 and using MVSE2013) (我正在运行Windows 7并使用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. 我尝试了另一种类似SetForegroundWindow的技术,但我读到它在Windows 7中不能很好地工作。

Found what I hope will be a passable workaround from PInvoke. 找到了我希望可以通过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. 我意识到两者之间在功能上有所不同,但是更改在我的特定实例中有效,因此我很高兴。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM