c# - 隐藏 Windows 窗体后无法将其显示回来

标签 c# .net

下面是我的代码。在这里您可以看到我使用常量来隐藏/显示窗口。在 C#.net 中隐藏另一个应用程序。

    private const int SW_HIDE = 0;
    private const int SW_SHOW = 5;

    [DllImport("User32")]
    private static extern int ShowWindow(int hwnd, int nCmdShow);

    private void btnHide_Click(object sender, EventArgs e){

        Process[] processRunning = Process.GetProcesses();
        foreach (Process pr in processRunning){

            if (pr.ProcessName == FileName){
                hWnd = pr.MainWindowHandle.ToInt32();
                ShowWindow(hWnd, SW_HIDE);
            }
        }
    }

    private void btnShow_Click(object sender, EventArgs e){

        Process[] processRunning = Process.GetProcesses();

        foreach (Process pr in processRunning){
            if (pr.ProcessName == FileName){

                hWnd = pr.MainWindowHandle.ToInt32();
                ShowWindow(hWnd, SW_SHOW);
            }
        }
    }

最佳答案

当可见时,MainWindowHandle 不为零,在窗口隐藏后,句柄设置为 0。我还没有找到一种方法来获取所需的句柄 - 也许解决方法是维护一个列表您隐藏的窗口。

List<int> HiddenWindows = new List<int>();

private void btnHide_Click(object sender, RoutedEventArgs e)
{
  Process[] processRunning = Process.GetProcessesByName(FileName);
  foreach (Process pr in processRunning)
  {
    int hWnd = pr.MainWindowHandle.ToInt32();
    if (hWnd == 0)
      continue;
    ShowWindow(hWnd, SW_HIDE);
    HiddenWindows.Add(hWnd);
  }
}

private void btnShow_Click(object sender, RoutedEventArgs e)
{
  foreach (int hWnd in HiddenWindows)
  {
    ShowWindow(hWnd, SW_SHOW);
  }
  HiddenWindows.Clear();
}

注意 - 您可以使用 GetProcessesByName 来获取您感兴趣的进程,而不是迭代 GetProcesses 返回的所有进程。

这里有一个基于其他 User32 函数的答案 - 但看起来相当复杂:Unhide process by its process name?

对 WPF 应用程序的快速测试显示,使用链接解决方案中的代码找到了多个窗口句柄 - 答案是在调用 ShowWindow 后删除返回。我在下面添加了一个修改版本,以便在需要时重新打开多个应用程序实例。

private const int SW_SHOW = 5;
private String FileName = "notepad";

[DllImport("User32")]
private static extern int ShowWindow(IntPtr hwnd, int nCmdShow);
[DllImport("User32.dll")]
private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string strClassName, string strWindowName);

[DllImport("user32.dll")]
private static extern int GetWindowThreadProcessId(IntPtr hWnd, out int ProcessId);

private void btnShow2_Click(object sender, RoutedEventArgs e)
{
  //an array of all processes with name "processName"
  Process[] localAll = Process.GetProcessesByName(FileName);

  foreach (var pr in localAll)
  {
    IntPtr hWnd = IntPtr.Zero;
    int prcsId = 0;

    //check all open windows (not only the process we are looking) begining from the
    //child of the desktop, handle = IntPtr.Zero initialy.
    do
    {
      //get child handle of window who's handle is "handle".
      hWnd = FindWindowEx(IntPtr.Zero, hWnd, null, null);
      GetWindowThreadProcessId(hWnd, out prcsId); //get ProcessId from "handle"

      //if it matches what we are looking
      //Note there maybe multiple Windows found - so try all of them
      if (prcsId == pr.Id)
        ShowWindow(hWnd, SW_SHOW); //Show Window
    } while (hWnd != IntPtr.Zero);
  }
}

请注意,我已修改 ShowWindow 定义以使用 IntPtr 作为窗口句柄的类型 - 这是首选使用的类型,并且它是 MainWindowHandle 的实际类型。在您的隐藏方法中,只需将代码更改为 是

IntPtr hWnd = pr.MainWindowHandle;

或整个循环

foreach (Process pr in processRunning)
{
  ShowWindow(pr.MainWindowHandle, SW_HIDE);
}

关于c# - 隐藏 Windows 窗体后无法将其显示回来,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55004021/

相关文章:

c# - 我可以在 DbContext 的 ViewModel 中使用依赖注入(inject)吗?核心2.0

c# - 防止更新面板内的按钮更新更新面板

.net - Windows Service workers 可以使用 Tasks 吗

c# - 如何找到所有包含匹配模式的类型/成员的程序集?

.net - WebResource.axd 在哪里

c# - 查询结果超过1000条时Dapper抛出System.Data.SqlClient.SqlException

c# - 如何删除.net core 2.0中的x-powered-by header

.net - .NET 库可以处理哪些声音格式?

.net - 我可以提高 Thread.Sleep 的分辨率吗?

c# - Informix 和 .NET 的时间和日期时间格式