Luk*_*ane 101
使用win32 API可以"吃掉"另一个应用程序.基本上,您可以获得该应用程序的顶部窗口,并将其父级设置为要放置的面板的句柄.如果您不想要MDI样式效果,则还必须调整窗口样式以使其最大化并且删除标题栏.
这是一些简单的示例代码,其中我有一个带有按钮和面板的表单:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            Process p = Process.Start("notepad.exe");
            Thread.Sleep(500); // Allow the process to open it's window
            SetParent(p.MainWindowHandle, panel1.Handle);
        }
        [DllImport("user32.dll")]
        static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
    }
}
我刚看到另一个例子,他们调用WaitForInputIdle而不是sleep.所以代码是这样的:
Process p = Process.Start("notepad.exe");
p.WaitForInputIdle();
SetParent(p.MainWindowHandle, panel1.Handle);
代码项目在整个过程中有一篇很好的文章:在WinForm项目中托管EXE应用程序
And*_*ite 15
我不知道这是否仍然是推荐使用的东西,但"对象链接和嵌入"框架允许您将某些对象/控件直接嵌入到您的应用程序中.这可能只适用于某些应用程序,我不确定Notepad是否是其中之一.对于像记事本这样非常简单的事情,你可能会更容易使用你正在使用的任何媒体提供的文本框控件(例如WinForms).
这是一个启动OLE信息的链接:
http://en.wikipedia.org/wiki/Object_Linking_and_Embedding
这段代码帮助我以 Windows 形式停靠了一些可执行文件。像记事本、Excel、word、Acrobat 阅读器等等……
但它不适用于某些应用程序。有时当您启动某个应用程序的进程时....等待空闲时间...并尝试获取其 mainWindowHandle.... 直到主窗口句柄变为空.....
所以我做了一个技巧来解决这个问题
如果您将主窗口句柄设为空...然后在系统上搜索所有正在运行的进程并找到您的进程...然后获取进程的主窗口并将设置面板作为其父进程。
        ProcessStartInfo info = new ProcessStartInfo();
        info.FileName = "xxxxxxxxxxxx.exe";
        info.Arguments = "yyyyyyyyyy";
        info.UseShellExecute = true;
        info.CreateNoWindow = true;
        info.WindowStyle = ProcessWindowStyle.Maximized;
        info.RedirectStandardInput = false;
        info.RedirectStandardOutput = false;
        info.RedirectStandardError = false;
        System.Diagnostics.Process p = System.Diagnostics.Process.Start(info); 
        p.WaitForInputIdle();
        Thread.Sleep(3000);
        Process[] p1 ;
    if(p.MainWindowHandle == null)
    {
        List<String> arrString = new List<String>();
        foreach (Process p1 in Process.GetProcesses())
        {
            // Console.WriteLine(p1.MainWindowHandle);
            arrString.Add(Convert.ToString(p1.ProcessName));
        }
        p1 = Process.GetProcessesByName("xxxxxxxxxxxx");
        //p.WaitForInputIdle();
        Thread.Sleep(5000);
      SetParent(p1[0].MainWindowHandle, this.panel2.Handle);
    }
    else
    {
     SetParent(p.MainWindowHandle, this.panel2.Handle);
     }
以下是另一个使用WinForm容器吸引外部应用程序的有趣解决方案:
[DllImport("user32.dll")]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
private void Form1_Load(object sender, EventArgs e)
{
    ProcessStartInfo psi = new ProcessStartInfo("notepad.exe");
    psi.WindowStyle = ProcessWindowStyle.Minimized;
    Process p = Process.Start(psi);
    Thread.Sleep(500);
    SetParent(p.MainWindowHandle, panel1.Handle);
    CenterToScreen();
    psi.WindowStyle = ProcessWindowStyle.Normal;
}
ProcessWindowStyle.Minimized从ProcessWindowStyle.Normal 到的步骤   消除了烦人的延迟。