PowerShell窗体嵌入控制台后隐藏或部分可见的问题求助
PowerShell窗体嵌入控制台显示异常的解决方法
问题
我尝试将PowerShell窗体嵌入PowerShell控制台中,但窗体要么被隐藏,要么仅部分可见。使用的代码如下:
Add-Type @" using System; using System.Runtime.InteropServices; public class Win32 { [DllImport("user32.dll")] public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent); } "@ # 获取控制台窗口句柄 $consoleHandle = [System.Diagnostics.Process]::GetCurrentProcess().MainWindowHandle # 将窗体父窗口设置为控制台窗口 [Win32]::SetParent($form.Handle, $consoleHandle) | Out-Null # 非模态显示窗体 $form.Show() # 维持窗体运行 [System.Windows.Forms.Application]::Run($form)
效果表现为窗体仅部分显示或被控制台文本区域遮挡。
解决方案
问题根源
- 直接将控制台主窗口作为父窗体,而控制台内部存在一个负责绘制文本的
ConsoleWindowClass子控件,窗体被该控件遮挡。 - 未适配控制台的客户区尺寸,窗体位置和大小不合理导致显示不全。
修正后的完整代码
Add-Type @" using System; using System.Runtime.InteropServices; using System.Windows.Forms; public class Win32 { [DllImport("user32.dll")] public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent); [DllImport("user32.dll")] public static extern IntPtr FindWindowEx(IntPtr hWndParent, IntPtr hWndChildAfter, string lpszClass, string lpszWindow); [DllImport("user32.dll")] public static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect); [StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left; public int Top; public int Bottom; public int Right; } } "@ # 加载Windows Forms程序集 Add-Type -AssemblyName System.Windows.Forms # 创建示例窗体 $form = New-Object System.Windows.Forms.Form $form.Text = "嵌入控制台的窗体" $form.BackColor = [System.Drawing.Color]::LightBlue # 获取控制台内部的文本显示控件句柄 $consoleHandle = [System.Diagnostics.Process]::GetCurrentProcess().MainWindowHandle $consoleEditHandle = [Win32]::FindWindowEx($consoleHandle, [IntPtr]::Zero, "ConsoleWindowClass", $null) # 将窗体父窗口设置为控制台文本控件 [Win32]::SetParent($form.Handle, $consoleEditHandle) | Out-Null # 获取控制台客户区大小,调整窗体位置和尺寸 $rect = New-Object Win32+RECT [Win32]::GetClientRect($consoleEditHandle, [ref]$rect) $form.Location = New-Object System.Drawing.Point(10, 10) $form.Size = New-Object System.Drawing.Size($rect.Right - 20, $rect.Bottom - 20) # 监听控制台大小变化,同步调整窗体 $form.Add_Resize({ $rect = New-Object Win32+RECT [Win32]::GetClientRect($consoleEditHandle, [ref]$rect) $this.Size = New-Object System.Drawing.Size($rect.Right - 20, $rect.Bottom - 20) }) # 非模态显示窗体并启动消息循环 $form.Show() [System.Windows.Forms.Application]::Run($form)
关键调整说明
- 替换父窗口:使用控制台内部的
ConsoleWindowClass控件作为父窗口,避免被文本区域遮挡。 - 适配尺寸:获取控制台客户区的实际大小,设置窗体的位置和尺寸,确保在控制台内完整显示。
- 同步窗口变化:添加Resize事件监听,当控制台窗口调整大小时,自动调整窗体尺寸保持适配。
内容的提问来源于stack exchange,提问作者Pravin
相关产品推荐
相关产品推荐

