簡體   English   中英

隱藏Windows表單后無法將其顯示回來

[英]After hiding the windows form not able to show it back

下面是我的代碼。 在這里您可以看到我使用常量來隱藏/顯示窗口。 從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函數的答案-但似乎很復雜: 通過進程名稱取消隱藏進程?

使用WPF應用程序進行的快速測試顯示,使用鏈接的解決方案中的代碼可以找到多個Window句柄-答案是刪除對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作為Window句柄的類型-這是首選使用的類型,它是MainWindowHandle的實際類型。 在您的hide方法中,只需將代碼更改為

IntPtr hWnd = pr.MainWindowHandle;

或整個循環

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

這就是Process.GetProcess()工作方式。

隱藏進程的主窗口后,其MainWindowHandle用於進程的下一次迭代)將變為IntPtr.Zero 我猜這與MainWindowHandle的獲取方式有關。

解決方案:

  1. 一次枚舉進程
  2. 存儲hWnd (例如,在Dictionary<string, int> )並調用ShowWindow()而無需再次檢索進程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM