簡體   English   中英

當MainWindowHandle為0時將窗口置於前台

[英]Bring Window To Foreground When MainWindowHandle Is 0

如果MainWindowHandle不為0,則以下代碼將窗口置於前台。

如何將具有MainWindowHandle = 0的窗口置於最前面?

這用於Microsoft Excel-兼容性檢查器窗口,該窗口顯示GUI,但任務欄中沒有圖標,並且MainWindowHandle = 0。

我沒有其他正在運行的Excel實例。

Add-Type @"
  using System;
  using System.Runtime.InteropServices;
  public class Tricks {
     [DllImport("user32.dll")]
     [return: MarshalAs(UnmanagedType.Bool)]
     public static extern bool SetForegroundWindow(IntPtr hWnd);
  }
"@

$excel = (Get-Process | Where-Object { $_.ProcessName -eq 'EXCEL' }).MainWindowHandle
[void] [Tricks]::SetForegroundWindow($excel)

在Windows Task Manager中,我可以右鍵單擊“ Microsoft Excel-Compatibility Checker”,然后單擊“ Bring To Front”,它可以正常工作。 如何在Powershell中模仿此功能?

感謝IInspectable為我指出正確的方向。

此代碼獲取真實的MainWindowHandle值:

$TypeDef2 = @"

using System;
using System.Text;
using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace Api
{

public class WinStruct
{
   public string WinTitle {get; set; }
   public int MainWindowHandle { get; set; }
}

public class ApiDef
{
   private delegate bool CallBackPtr(int hwnd, int lParam);
   private static CallBackPtr callBackPtr = Callback;
   private static List<WinStruct> _WinStructList = new List<WinStruct>();

   [DllImport("User32.dll")]
   [return: MarshalAs(UnmanagedType.Bool)]
   private static extern bool EnumWindows(CallBackPtr lpEnumFunc, IntPtr lParam);

   [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
   static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

   private static bool Callback(int hWnd, int lparam)
   {
       StringBuilder sb = new StringBuilder(256);
       int res = GetWindowText((IntPtr)hWnd, sb, 256);
      _WinStructList.Add(new WinStruct { MainWindowHandle = hWnd, WinTitle = sb.ToString() });
       return true;
   }  

   public static List<WinStruct> GetWindows()
   {
      _WinStructList = new List<WinStruct>();
      EnumWindows(callBackPtr, IntPtr.Zero);
      return _WinStructList;
   }

}
}
"@

Add-Type -TypeDefinition $TypeDef2 -Language CSharpVersion3

$excelInstance = [Api.Apidef]::GetWindows() | Where-Object { $_.WinTitle.ToUpper() -eq "Microsoft Excel - Compatibility Checker".ToUpper() }

因此,現在使用此正確值,我可以調用SetForegroundWindow()函數:

Add-Type @"
  using System;
  using System.Runtime.InteropServices;
  public class Tricks {
     [DllImport("user32.dll")]
     [return: MarshalAs(UnmanagedType.Bool)]
     public static extern bool SetForegroundWindow(IntPtr hWnd);
  }
"@
[void] [Tricks]::SetForegroundWindow($excelInstance.MainWindowHandle)

我在我的網站上寫了一個詳細的博客。

我已經在GitHub上舉了一個完整的示例,說明如何創建Excel文件,對其進行編輯並在不同的線程中運行上述代碼,因為Excel彈出窗口會阻止主線程。

暫無
暫無

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

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