You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)

效果表现为窗体仅部分显示或被控制台文本区域遮挡。

解决方案

问题根源

  1. 直接将控制台主窗口作为父窗体,而控制台内部存在一个负责绘制文本的ConsoleWindowClass子控件,窗体被该控件遮挡。
  2. 未适配控制台的客户区尺寸,窗体位置和大小不合理导致显示不全。

修正后的完整代码

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 17:15:10