将外部应用程序嵌入WinForm中
2010-05-26 10:37
393 查看
如何用C# WinFrom程序将其他程序激活并让其他程序作为他的子窗体。比如他开个主窗体可以把QQ,游戏什么的作为他的子窗体显示出来?这个问题我在网上看到很多人都提过。但真正解决问题的很难找到。后来终于在网上找到了一个相关方面的知识。我早把这个资源上传到我的下载文件中去了。但是我感觉这样的话,别人搜索到的机率还是很小。所以我现在再不厌其烦的,把代码再贴出来吧,方便大家共同学习。
需要Process.Start()启动外部应用。
还要FindWindow,SetParent等几个API。
C#调用请看
http://www.pinvoke.net/search.aspx?search=FindWindow&namespace=[All]
这个控件封装好了。
调用方法 (其实就是把上面生成的控件直接拖放到窗体,改一下路径等相关属性就可以了。)
特别申明:本文纯属个人在网上搜索所得。感谢原文网址(http://www.chenjiliang.com/Article/View.aspx?ArticleID=2103)
运行效果见图片
需要Process.Start()启动外部应用。
还要FindWindow,SetParent等几个API。
C#调用请看
http://www.pinvoke.net/search.aspx?search=FindWindow&namespace=[All]
这个控件封装好了。
using System; using System.Collections; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Data; using System.Windows.Forms; using System.Runtime.InteropServices; namespace AppControl { /// <summary> /// Application Display Control /// </summary> [ ToolboxBitmap(typeof(ApplicationControl), "AppControl.bmp"), ] public class ApplicationControl : System.Windows.Forms.Panel { /// <summary> /// Track if the application has been created /// </summary> bool created = false; /// <summary> /// Handle to the application Window /// </summary> IntPtr appWin; /// <summary> /// The name of the exe to launch /// </summary> private string exeName = ""; /// <summary> /// Get/Set if we draw the tick marks /// </summary> [ Category("Data"), Description("Name of the executable to launch"), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible) ] public string ExeName { get { return exeName; } set { exeName = value; } } /// <summary> /// Constructor /// </summary> public ApplicationControl() { } [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); [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); 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; /// <summary> /// Force redraw of control when size changes /// </summary> /// <param name="e">Not used</param> protected override void OnSizeChanged(EventArgs e) { this.Invalidate(); base.OnSizeChanged(e); } /// <summary> /// Creeate control when visibility changes /// </summary> /// <param name="e">Not used</param> protected override void OnVisibleChanged(EventArgs e) { // If control needs to be initialized/created if (created == false) { // Mark that control is created created = true; // Initialize handle value to invalid appWin = IntPtr.Zero; // Start the remote application Process p = null; try { // Start the process p = System.Diagnostics.Process.Start(this.exeName); // Wait for process to be created and enter idle condition p.WaitForInputIdle(); // Get the main handle appWin = p.MainWindowHandle; } catch (Exception ex) { MessageBox.Show(this, ex.Message, "Error"); } // Put it into this form SetParent(appWin, this.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); } base.OnVisibleChanged(e); } /// <summary> /// /// </summary> /// <param name="e"></param> protected override void OnHandleDestroyed(EventArgs e) { // Stop the application if (appWin != IntPtr.Zero) { // Post a colse message PostMessage(appWin, WM_CLOSE, 0, 0); // Delay for it to get the message System.Threading.Thread.Sleep(1000); // Clear internal handle appWin = IntPtr.Zero; } base.OnHandleDestroyed(e); } /// <summary> /// Update display of the executable /// </summary> /// <param name="e">Not used</param> protected override void OnResize(EventArgs e) { if (this.appWin != IntPtr.Zero) { MoveWindow(appWin, 0, 0, this.Width, this.Height, true); } base.OnResize(e); } } }
调用方法 (其实就是把上面生成的控件直接拖放到窗体,改一下路径等相关属性就可以了。)
this.applicationControl1 = new AppControl.ApplicationControl(); this.SuspendLayout(); // // applicationControl1 // this.applicationControl1.Anchor = ((System.Windows.Forms.AnchorStyles) ((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.applicationControl1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; // 在这里设置要嵌入的程序路径,我试验了灵格斯翻译专家成功,QQ没试,据说不成功,我不清楚呵呵。) this.applicationControl1.ExeName = @"f:/EditPlus/EDITPLUS.EXE"; //this.applicationControl1.ExeName = @"f:/Tencent/QQ/QQ.exe";//QQ的没成功 this.applicationControl1.Location = new System.Drawing.Point(29, 26); this.applicationControl1.Name = "applicationControl1"; this.applicationControl1.Size = new System.Drawing.Size(230, 195); this.applicationControl1.TabIndex = 0;
特别申明:本文纯属个人在网上搜索所得。感谢原文网址(http://www.chenjiliang.com/Article/View.aspx?ArticleID=2103)
运行效果见图片
相关文章推荐
- 在winform嵌入外部应用程序
- 将外部应用程序嵌入WinForm中
- 在WinForm应用程序中嵌入WPF控件(转)
- WinForm将其它应用程序窗体嵌入自己内部
- C#自定义控件:WinForm将其它应用程序窗体嵌入自己内部
- 【转】C#自定义控件:WinForm将其它应用程序窗体嵌入自己内部
- C#自定义控件:WinForm将其它应用程序窗体嵌入自己内部
- 在WinForm应用程序中嵌入WPF控件
- C#自定义控件:WinForm将其它应用程序窗体嵌入自己内部【转载】
- C#自定义控件:WinForm将其它应用程序窗体嵌入自己内部
- 在WinForm应用程序中嵌入WPF控件
- winform 嵌入 外部 exe窗体
- 在WinForm应用程序中嵌入WPF控件
- winform窗体中嵌入网页(DHTML代码和winfrom应用程序交互)
- 【转】C#自定义控件:WinForm将其它应用程序窗体嵌入自己内部
- C#自定义控件:WinForm将其它应用程序窗体嵌入自己内部
- [分享]外部exe窗体嵌入winform 分类: .NET 2015-03-12 11:26 68人阅读 评论(0) 收藏
- 外部exe窗体嵌入winform
- C#自定义控件:WinForm将其它应用程序窗体嵌入自己内部
- winform窗体中嵌入网页(DHTML代码和winfrom应用程序交互)