可是我直接把这些代码打进去没效果啊。。怎么回事?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;namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } #region WIN API---引入系统API,用于把程序打开的窗口整合到SHOW页面中 #region 宏定义 private const int SWP_NOOWNERZORDER = 0x200; private const int SWP_NOREDRAW = 0x8; private const int SWP_NOZORDER = 0x4; private const int SWP_SHOWWINDOW = 0x0040; private const int WS_EX_MDICHILD = 0x40; private const int SWP_FRAMECHANGED = 0x20; private const int SWP_NOACTIVATE = 0x10; private const int SWP_ASYNCWINDOWPOS = 0x4000; private const int SWP_NOMOVE = 0x2; private const int SWP_NOSIZE = 0x1; private const int GWL_STYLE = (-16); private const int WS_VISIBLE = 0x10000000; private const int WM_CLOSE = 0x10; private const int WS_CHILD = 0x40000000; #endregion [DllImport("user32.dll", EntryPoint = "GetWindowThreadProcessId", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] private static extern long GetWindowThreadProcessId(long hWnd, long lpdwProcessId); [DllImport("user32.dll", SetLastError = true)] private static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll", SetLastError = true)] private static extern long SetParent(IntPtr hWndChild, IntPtr hWndNewParent); [DllImport("user32.dll", EntryPoint = "GetWindowLongA", SetLastError = true)] private static extern long GetWindowLong(IntPtr hwnd, int nIndex); [DllImport("user32.dll", EntryPoint = "SetWindowLongA", SetLastError = true)] private static extern long SetWindowLong(IntPtr hwnd, int nIndex, long dwNewLong); //private static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong); [DllImport("user32.dll", SetLastError = true)] private static extern long SetWindowPos(IntPtr hwnd, long hWndInsertAfter, long x, long y, long cx, long cy, long wFlags); [DllImport("user32.dll", SetLastError = true)] private static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint); [DllImport("user32.dll", EntryPoint = "PostMessageA", SetLastError = true)] private static extern bool PostMessage(IntPtr hwnd, uint Msg, long wParam, long lParam); #endregion Process process = null; IntPtr appWin; private string exeName = ""; private void splitContainer1_Panel2_Resize(object sender, EventArgs e) { if (this.appWin != IntPtr.Zero) { MoveWindow(appWin, 0, 0, this.splitContainer1.Panel2.Width, this.splitContainer1.Panel2.Height, true); } base.OnResize(e); } private void Form1_Load(object sender, EventArgs e) { exeName = "否定.exe"; try { // Start the process process = System.Diagnostics.Process.Start(this.exeName); // Wait for process to be created and enter idle condition process.WaitForInputIdle(); // Get the main handle appWin = process.MainWindowHandle; } catch (Exception ex) { MessageBox.Show(this, ex.Message, "Error"); } // Put it into this form SetParent(appWin, this.splitContainer1.Panel2.Handle); // Remove border and whatnot // SetWindowLong(appWin, GWL_STYLE, WS_VISIBLE); // Move the window to overlay it on this window MoveWindow(appWin, 0, 0, this.Width, this.Height, true); } private void Form1_FormClosed(object sender, FormClosedEventArgs e) { if (process != null && !process.HasExited) process.Kill(); } } }
这个代码基本可用,如果没效果,一个可能的原因是有些exe取不到MainWindowHandle,我的解决办法是先运行这个exe,然后用autoit这个工具,找到它的窗口的class,然后用appWin = FindWindow("className", null);来取得句柄。手头有个Alexsys Team 2 Pro的软件,用MainWindowHandle没效果,用class可行。
我试了你的方法,可是窗口还是在另一个窗口中打开了。。没有嵌入我的窗体。我对Win API不是很熟悉,请问这是为什么呢?private void Form1_Load(object sender, EventArgs e) { exeName = "否定.exe"; try { // Start the process process = System.Diagnostics.Process.Start(this.exeName); // Wait for process to be created and enter idle condition process.WaitForInputIdle(); // Get the main handle appWin = FindWindow("WindowsForms10.Window.8.app.0.2bf8098_r13_ad1", null); //appWin = process.MainWindowHandle; } catch (Exception ex) { MessageBox.Show(this, ex.Message, "Error"); } // Put it into this form SetParent(appWin, this.splitContainer1.Panel2.Handle); // Remove border and whatnot // SetWindowLong(appWin, GWL_STYLE, WS_VISIBLE); // Move the window to overlay it on this window MoveWindow(appWin, 0, 0, this.Width, this.Height, true); }
在你的示例 的代码中。我加了一个button button的点击事件。 private void button1_Click(object sender, EventArgs e) { OpenFileDialog dlg = new OpenFileDialog(); dlg.Filter = "*.exe|*.exe"; if (dlg.ShowDialog() == DialogResult.OK) { string filename = dlg.FileName; Process proc = Process.Start(filename); IntPtr inp = FindWindow(null, "Form1"); while (inp == IntPtr.Zero) { System.Threading.Thread.Sleep(100); Application.DoEvents(); } long i = SetParent(proc.MainWindowHandle, this.Handle); } } 测试过可以用。
这些都必须使用win api来做。这些个api 网上都有。
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;namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
#region WIN API---引入系统API,用于把程序打开的窗口整合到SHOW页面中
#region 宏定义
private const int SWP_NOOWNERZORDER = 0x200;
private const int SWP_NOREDRAW = 0x8;
private const int SWP_NOZORDER = 0x4;
private const int SWP_SHOWWINDOW = 0x0040;
private const int WS_EX_MDICHILD = 0x40;
private const int SWP_FRAMECHANGED = 0x20;
private const int SWP_NOACTIVATE = 0x10;
private const int SWP_ASYNCWINDOWPOS = 0x4000;
private const int SWP_NOMOVE = 0x2;
private const int SWP_NOSIZE = 0x1;
private const int GWL_STYLE = (-16);
private const int WS_VISIBLE = 0x10000000;
private const int WM_CLOSE = 0x10;
private const int WS_CHILD = 0x40000000;
#endregion
[DllImport("user32.dll", EntryPoint = "GetWindowThreadProcessId", SetLastError = true,
CharSet = CharSet.Unicode, ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
private static extern long GetWindowThreadProcessId(long hWnd, long lpdwProcessId); [DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll", SetLastError = true)]
private static extern long SetParent(IntPtr hWndChild, IntPtr hWndNewParent); [DllImport("user32.dll", EntryPoint = "GetWindowLongA", SetLastError = true)]
private static extern long GetWindowLong(IntPtr hwnd, int nIndex); [DllImport("user32.dll", EntryPoint = "SetWindowLongA", SetLastError = true)]
private static extern long SetWindowLong(IntPtr hwnd, int nIndex, long dwNewLong);
//private static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
[DllImport("user32.dll", SetLastError = true)]
private static extern long SetWindowPos(IntPtr hwnd, long hWndInsertAfter, long x, long y, long cx, long cy, long wFlags); [DllImport("user32.dll", SetLastError = true)]
private static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint); [DllImport("user32.dll", EntryPoint = "PostMessageA", SetLastError = true)]
private static extern bool PostMessage(IntPtr hwnd, uint Msg, long wParam, long lParam);
#endregion
Process process = null;
IntPtr appWin;
private string exeName = ""; private void splitContainer1_Panel2_Resize(object sender, EventArgs e)
{
if (this.appWin != IntPtr.Zero)
{
MoveWindow(appWin, 0, 0, this.splitContainer1.Panel2.Width, this.splitContainer1.Panel2.Height, true);
}
base.OnResize(e);
} private void Form1_Load(object sender, EventArgs e)
{
exeName = "否定.exe";
try
{
// Start the process
process = System.Diagnostics.Process.Start(this.exeName); // Wait for process to be created and enter idle condition
process.WaitForInputIdle(); // Get the main handle
appWin = process.MainWindowHandle;
}
catch (Exception ex)
{
MessageBox.Show(this, ex.Message, "Error");
} // Put it into this form
SetParent(appWin, this.splitContainer1.Panel2.Handle); // Remove border and whatnot
// SetWindowLong(appWin, GWL_STYLE, WS_VISIBLE);
// Move the window to overlay it on this window
MoveWindow(appWin, 0, 0, this.Width, this.Height, true);
} private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
if (process != null && !process.HasExited)
process.Kill();
}
}
}
{
exeName = "否定.exe";
try
{
// Start the process
process = System.Diagnostics.Process.Start(this.exeName); // Wait for process to be created and enter idle condition
process.WaitForInputIdle(); // Get the main handle
appWin = FindWindow("WindowsForms10.Window.8.app.0.2bf8098_r13_ad1", null);
//appWin = process.MainWindowHandle;
}
catch (Exception ex)
{
MessageBox.Show(this, ex.Message, "Error");
} // Put it into this form
SetParent(appWin, this.splitContainer1.Panel2.Handle); // Remove border and whatnot
// SetWindowLong(appWin, GWL_STYLE, WS_VISIBLE);
// Move the window to overlay it on this window
MoveWindow(appWin, 0, 0, this.Width, this.Height, true);
}
在你的示例 的代码中。我加了一个button
button的点击事件。
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog dlg = new OpenFileDialog();
dlg.Filter = "*.exe|*.exe";
if (dlg.ShowDialog() == DialogResult.OK)
{
string filename = dlg.FileName;
Process proc = Process.Start(filename);
IntPtr inp = FindWindow(null, "Form1");
while (inp == IntPtr.Zero)
{
System.Threading.Thread.Sleep(100);
Application.DoEvents();
}
long i = SetParent(proc.MainWindowHandle, this.Handle);
}
}
测试过可以用。
我的想法其实是嵌入我的一个控件内显示(例如在tabControl的一个子页面中)
替换为this.tabControl.Handle
{
OpenFileDialog dlg = new OpenFileDialog();
dlg.Filter = "*.exe|*.exe";
if (dlg.ShowDialog() == DialogResult.OK)
{
string filename = dlg.FileName;
Process proc = Process.Start(filename);
IntPtr inp = FindWindow(null,"否定");
while (inp == IntPtr.Zero)
{
System.Threading.Thread.Sleep(100);
Application.DoEvents();
}
long i = SetParent(proc.MainWindowHandle, this.tabPage1.Handle);
}
Process.Start之后先sleep