ShowWindowAsync()不显示隐藏窗口(SW_SHOW)

时间:2011-05-01 08:58:53

标签: windows vb.net

您好 我正在使用Visual Basic 2008

这是我的代码的一部分:

    Private Const SW_HIDE As Integer = 0
    Private Const SW_SHOW As Integer = 5

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

button1代码:

            Try
               Dim p() As Process = Process.GetProcessesByName("notepad")
               Dim mwh = p(0).MainWindowHandle
               ShowWindowAsync(mwh, SW_HIDE)
            Catch ex As Exception
               MsgBox("error")
            End Try      

button2代码:

            Try         
               Dim p() As Process = Process.GetProcessesByName("notepad")
               Dim mwh = p(0).MainWindowHandle
               ShowWindowAsync(mwh, SW_SHOW)
            Catch ex As Exception
               MsgBox("error")
            End Try  

当我点击button 1(隐藏窗口)时效果很好,但是当我想要显示窗口时(通过点击button 2),该函数返回FALSE,谁可以告诉我为什么?以及如何让它工作,隐藏窗口然后再显示它?

4 个答案:

答案 0 :(得分:2)

因为ShowWindowAsync() returns zero when the window was previously hidden according to the MSDN documentation,零被解释为FALSE。返回值不表示函数是否成功。

因此,当您第一次在可见窗口上调用ShowWindowAsync(mwh, SW_HIDE)时,函数返回TRUE,因为ShowWindowAsync()返回一个非零值,表示窗口(现在/将被隐藏)曾经是可见的。

然后隐藏窗口上的第二个调用ShowWindowAsync(mwh, SW_SHOW)返回FALSE,因为ShowWindowAsync()返回一个零值,表示用于隐藏的窗口(现在/将是可见的)。 / p>

换句话说,这是设计的,函数应该按预期工作(除非mwh窗口没有响应消息或无效)。

但真正的问题是,一旦你隐藏了一个窗口,Process::MainWindowHandle property doesn't have the handle anymore

  

进程有一个主窗口关联   只有当过程有一个   图形界面。如果相关联   进程没有主窗口,   MainWindowHandle值为零。   进程的值也为零   被隐藏的,也就是说,   在...中看不到的进程   任务栏。这可能就是这种情况   在...中显示为图标的进程   通知区域,位于最右侧   任务栏。

您应该做的是通过p(0).MainWindowHandle获取窗口句柄一次并将返回的句柄保存在某处,以便您可以显示/隐藏窗口。当然,当窗口被目标进程销毁时,您应确保将保存的句柄清零。在记事本的情况下,您可以使用Process::Exited event

答案 1 :(得分:1)

听起来像“按设计”。不要将“false”的返回值视为错误。

根据MSDN:

If the window was previously visible, the return value is nonzero.

If the window was previously hidden, the return value is zero. 

http://msdn.microsoft.com/en-us/library/ms633549%28VS.85%29.aspx

您可以通过将函数的互操作导入声明为32位整数类型而不是布尔值来阻止异常发生。

Private Shared Function ShowWindowAsync(ByVal hwnd As IntPtr, ByVal nCmdShow As Integer) As Integer

答案 2 :(得分:1)

隐藏时我做了:

WindowHandle = Proc(0).MainWindowHandle
ShowWindowAsync(Proc(0).MainWindowHandle, ShowWindowConstants.SW_HIDE)

然后在显示时我使用了WindowHandle变量:

ShowWindowAsync(WindowHandle, ShowWindowConstants.SW_SHOW)

答案 3 :(得分:1)

要最大化另一个进程的隐藏窗口,您必须执行以下3个步骤(非常简单):

1-获取MainWindowHandle 因为应用程序是隐藏的,MainWindowHandle是0(false)。要解决此问题,您可以使用FindWindow

//Get the MainWindowHandle
IntPtr hwnd = FindWindow(null, <WINDOW TITLE>);

2-使用ShowWindowAsync()

bool result = ShowWindowAsync(hwnd, 3); //3= Maximize application

3-实现以下应用程序事件之一:“GotFocus”,“Activated”或“IsVisibleChanged”   (我只测试了“激活”事件)

private void WindowApplication_Activated(object sender, EventArgs e)
{
    Application.Current.MainWindow.Show();
}

您可以在此网址上找到更多相关信息: http://isolvable.blogspot.pt/2009/09/restoring-wpf-window-of-another-process.html

希望这些信息可以帮助别人!