在C# WinForm中集成并自定义Putty窗口

在C# WinForm中集成并自定义Putty窗口

在这个教程中,我们将展示如何在C# WinForm应用程序中嵌入Putty终端窗口,并移除其标题栏、最大化按钮和最小化按钮等UI元素。这将使Putty窗口看起来像是应用程序的一部分,而不是一个独立的应用程序窗口。

前提条件

  • 安装了Visual Studio。
  • 安装了Putty(确保putty.exe在系统路径中或指定完整路径)。

步骤

1. 创建一个新的WinForms项目

首先,在Visual Studio中创建一个新的WinForms项目。

2. 添加Panel控件

在窗体上添加一个Panel控件,用于承载Putty窗口。

3. 编写代码

在你的主窗体类中编写以下代码:

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace PuttyInWinForms
{
    public partial class MainForm : Form
    {
        [DllImport("user32.dll")]
        private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

        [DllImport("user32.dll", SetLastError = true)]
        private static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);

        [DllImport("user32.dll", SetLastError = true)]
        private static extern int GetWindowLong(IntPtr hWnd, int nIndex);

        [DllImport("user32.dll")]
        private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

        [DllImport("user32.dll")]
        private static extern bool SetForegroundWindow(IntPtr hWnd);

        // 窗口样式常量
        private const int GWL_STYLE = -16;
        private const int GWL_EXSTYLE = -20;
        private const int WS_CAPTION = 0xC00000;      // 标题栏
        private const int WS_THICKFRAME = 0x00040000; // 可调整大小边框
        private const int WS_MINIMIZEBOX = 0x20000;   // 最小化按钮
        private const int WS_MAXIMIZEBOX = 0x10000;   // 最大化按钮
        private const int WS_SYSMENU = 0x80000;       // 系统菜单
        private const int WS_EX_DLGMODALFRAME = 0x0001; // 对话框模态框架
        private const int WS_EX_CLIENTEDGE = 0x00020000; // 客户区边缘
        private const int WS_EX_WINDOWEDGE = 0x00000100; // 窗口边缘

        private Process puttyProcess;

        public MainForm()
        {
            InitializeComponent();
            this.panel1.Resize += new EventHandler(Panel1_Resize);
            this.Activated += new EventHandler(MainForm_Activated);
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            StartAndEmbedPutty();
        }

        private void StartAndEmbedPutty()
        {
            puttyProcess = new Process();
            puttyProcess.StartInfo.FileName = "putty.exe";  // 确保路径正确或putty.exe位于系统路径中
            puttyProcess.StartInfo.UseShellExecute = false; // 必须设置为false才能获取hWnd
            puttyProcess.Start();

            while (puttyProcess.MainWindowHandle == IntPtr.Zero)
            {
                Application.DoEvents();
            }

            SetParent(puttyProcess.MainWindowHandle, panel1.Handle);
            AdjustPuttyWindowSize();
            HidePuttyTitleBar(puttyProcess.MainWindowHandle);
        }

        private void Panel1_Resize(object sender, EventArgs e)
        {
            if (puttyProcess != null && !puttyProcess.HasExited)
            {
                AdjustPuttyWindowSize();
            }
        }

        private void AdjustPuttyWindowSize()
        {
            if (puttyProcess != null && !puttyProcess.HasExited)
            {
                MoveWindow(puttyProcess.MainWindowHandle, 0, 0, panel1.ClientSize.Width, panel1.ClientSize.Height, true);
            }
        }

        private void MainForm_Activated(object sender, EventArgs e)
        {
            if (puttyProcess != null && !puttyProcess.HasExited)
            {
                SetForegroundWindow(puttyProcess.MainWindowHandle);
            }
        }

        private void HidePuttyTitleBar(IntPtr hWnd)
        {
            // 修改标准窗口样式
            int style = GetWindowLong(hWnd, GWL_STYLE);
            style &= ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU);
            SetWindowLong(hWnd, GWL_STYLE, style);

            // 修改扩展窗口样式
            int exStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
            exStyle &= ~(WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE | WS_EX_WINDOWEDGE);
            SetWindowLong(hWnd, GWL_EXSTYLE, exStyle);
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (puttyProcess != null && !puttyProcess.HasExited)
            {
                puttyProcess.Kill();
            }
        }
    }
}

4. 运行项目

编译并运行你的项目。你应该会看到一个没有标题栏、最大化按钮和最小化按钮的Putty窗口,它被嵌入到了你的WinForm应用程序中的Panel控件内。


在C# WinForm中集成并自定义Putty窗口
https://www.dearcloud.cn/2024/11/28/20241128-putty-winform/在CSharpWinForm中集成并自定义Putty窗口/
作者
宋兴柱
发布于
2024年11月28日
许可协议