将外部应用程序嵌入WinForm中

转自:http://blog.csdn.net/llddyy123wq/article/details/5624625

如何用C# WinFrom程序将其他程序激活并让其他程序作为他的子窗体。比如他开个主窗体可以把QQ,游戏什么的作为他的子窗体显示出来?这个问题我在网上看到很多人都提过。但真正解决问题的很难找到。后来终于在网上找到了一个相关方面的知识。我早把这个资源上传到我的下载文件中去了。但是我感觉这样的话,别人搜索到的机率还是很小。所以我现在再不厌其烦的,把代码再贴出来吧,方便大家共同学习。

需要Process.Start()启动外部应用。  
还要FindWindow,SetParent等几个API。  
C#调用请看  
http://www.pinvoke.net/search.aspx?search=FindWindow&namespace=[All] 

这个控件封装好了。 

[c-sharp]  view plain copy
  1. using System;  
  2. using System.Collections;  
  3. using System.ComponentModel;  
  4. using System.Diagnostics;  
  5. using System.Drawing;  
  6. using System.Data;  
  7. using System.Windows.Forms;  
  8. using System.Runtime.InteropServices;  
  9.   
  10. namespace AppControl  
  11. {  
  12.   
  13.     /// <summary>  
  14.     /// Application Display Control  
  15.     /// </summary>  
  16.     [  
  17.     ToolboxBitmap(typeof(ApplicationControl), "AppControl.bmp"),  
  18.     ]  
  19.     public class ApplicationControl : System.Windows.Forms.Panel  
  20.     {  
  21.   
  22.         /// <summary>  
  23.         /// Track if the application has been created  
  24.         /// </summary>  
  25.         bool created = false;  
  26.   
  27.         /// <summary>  
  28.         /// Handle to the application Window  
  29.         /// </summary>  
  30.         IntPtr appWin;  
  31.   
  32.         /// <summary>  
  33.         /// The name of the exe to launch  
  34.         /// </summary>  
  35.         private string exeName = "";  
  36.   
  37.         /// <summary>  
  38.         /// Get/Set if we draw the tick marks  
  39.         /// </summary>  
  40.         [  
  41.         Category("Data"),  
  42.         Description("Name of the executable to launch"),  
  43.         DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)  
  44.         ]  
  45.         public string ExeName  
  46.         {  
  47.             get  
  48.             {  
  49.                 return exeName;  
  50.             }  
  51.             set  
  52.             {  
  53.                 exeName = value;  
  54.             }  
  55.         }  
  56.   
  57.   
  58.         /// <summary>  
  59.         /// Constructor  
  60.         /// </summary>  
  61.         public ApplicationControl()  
  62.         {  
  63.         }  
  64.   
  65.   
  66.         [DllImport("user32.dll", EntryPoint = "GetWindowThreadProcessId", SetLastError = true,  
  67.              CharSet = CharSet.Unicode, ExactSpelling = true,  
  68.              CallingConvention = CallingConvention.StdCall)]  
  69.         private static extern long GetWindowThreadProcessId(long hWnd, long lpdwProcessId);  
  70.   
  71.         [DllImport("user32.dll", SetLastError = true)]  
  72.         private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);  
  73.   
  74.         [DllImport("user32.dll", SetLastError = true)]  
  75.         private static extern long SetParent(IntPtr hWndChild, IntPtr hWndNewParent);  
  76.   
  77.         [DllImport("user32.dll", EntryPoint = "GetWindowLongA", SetLastError = true)]  
  78.         private static extern long GetWindowLong(IntPtr hwnd, int nIndex);  
  79.   
  80.         [DllImport("user32.dll", EntryPoint = "SetWindowLongA", SetLastError = true)]  
  81.         private static extern long SetWindowLong(IntPtr hwnd, int nIndex, long dwNewLong);  
  82.   
  83.         [DllImport("user32.dll", SetLastError = true)]  
  84.         private static extern long SetWindowPos(IntPtr hwnd, long hWndInsertAfter, long x, long y, long cx, long cy, long wFlags);  
  85.   
  86.         [DllImport("user32.dll", SetLastError = true)]  
  87.         private static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint);  
  88.   
  89.         [DllImport("user32.dll", EntryPoint = "PostMessageA", SetLastError = true)]  
  90.         private static extern bool PostMessage(IntPtr hwnd, uint Msg, long wParam, long lParam);  
  91.   
  92.         private const int SWP_NOOWNERZORDER = 0x200;  
  93.         private const int SWP_NOREDRAW = 0x8;  
  94.         private const int SWP_NOZORDER = 0x4;  
  95.         private const int SWP_SHOWWINDOW = 0x0040;  
  96.         private const int WS_EX_MDICHILD = 0x40;  
  97.         private const int SWP_FRAMECHANGED = 0x20;  
  98.         private const int SWP_NOACTIVATE = 0x10;  
  99.         private const int SWP_ASYNCWINDOWPOS = 0x4000;  
  100.         private const int SWP_NOMOVE = 0x2;  
  101.         private const int SWP_NOSIZE = 0x1;  
  102.         private const int GWL_STYLE = (-16);  
  103.         private const int WS_VISIBLE = 0x10000000;  
  104.         private const int WM_CLOSE = 0x10;  
  105.         private const int WS_CHILD = 0x40000000;  
  106.   
  107.         /// <summary>  
  108.         /// Force redraw of control when size changes  
  109.         /// </summary>  
  110.         /// <param name="e">Not used</param>  
  111.         protected override void OnSizeChanged(EventArgs e)  
  112.         {  
  113.             this.Invalidate();  
  114.             base.OnSizeChanged(e);  
  115.         }  
  116.   
  117.   
  118.         /// <summary>  
  119.         /// Creeate control when visibility changes  
  120.         /// </summary>  
  121.         /// <param name="e">Not used</param>  
  122.         protected override void OnVisibleChanged(EventArgs e)  
  123.         {  
  124.   
  125.             // If control needs to be initialized/created  
  126.             if (created == false)  
  127.             {  
  128.   
  129.                 // Mark that control is created  
  130.                 created = true;  
  131.   
  132.                 // Initialize handle value to invalid  
  133.                 appWin = IntPtr.Zero;  
  134.   
  135.                 // Start the remote application  
  136.                 Process p = null;  
  137.                 try  
  138.                 {  
  139.   
  140.                     // Start the process  
  141.                     p = System.Diagnostics.Process.Start(this.exeName);  
  142.   
  143.                     // Wait for process to be created and enter idle condition  
  144.                     p.WaitForInputIdle();  
  145.   
  146.                     // Get the main handle  
  147.                     appWin = p.MainWindowHandle;  
  148.                 }  
  149.                 catch (Exception ex)  
  150.                 {  
  151.                     MessageBox.Show(this, ex.Message, "Error");  
  152.                 }  
  153.   
  154.                 // Put it into this form  
  155.                 SetParent(appWin, this.Handle);  
  156.   
  157.                 // Remove border and whatnot  
  158.                 SetWindowLong(appWin, GWL_STYLE, WS_VISIBLE);  
  159.   
  160.                 // Move the window to overlay it on this window  
  161.                 MoveWindow(appWin, 0, 0, this.Width, this.Height, true);  
  162.   
  163.             }  
  164.   
  165.             base.OnVisibleChanged(e);  
  166.         }  
  167.   
  168.   
  169.         /// <summary>  
  170.         ///   
  171.         /// </summary>  
  172.         /// <param name="e"></param>  
  173.         protected override void OnHandleDestroyed(EventArgs e)  
  174.         {  
  175.             // Stop the application  
  176.             if (appWin != IntPtr.Zero)  
  177.             {  
  178.   
  179.                 // Post a colse message  
  180.                 PostMessage(appWin, WM_CLOSE, 0, 0);  
  181.   
  182.                 // Delay for it to get the message  
  183.                 System.Threading.Thread.Sleep(1000);  
  184.   
  185.                 // Clear internal handle  
  186.                 appWin = IntPtr.Zero;  
  187.   
  188.             }  
  189.   
  190.             base.OnHandleDestroyed(e);  
  191.         }  
  192.   
  193.   
  194.         /// <summary>  
  195.         /// Update display of the executable  
  196.         /// </summary>  
  197.         /// <param name="e">Not used</param>  
  198.         protected override void OnResize(EventArgs e)  
  199.         {  
  200.             if (this.appWin != IntPtr.Zero)  
  201.             {  
  202.                 MoveWindow(appWin, 0, 0, this.Width, this.Height, true);  
  203.             }  
  204.             base.OnResize(e);  
  205.         }  
  206.   
  207.   
  208.     }  
  209.   
  210.   
  211. }  



调用方法 (其实就是把上面生成的控件直接拖放到窗体,改一下路径等相关属性就可以了。)
[c-sharp]  view plain copy
  1. this.applicationControl1 = new AppControl.ApplicationControl();  
  2. this.SuspendLayout();  
  3. //   
  4. // applicationControl1  
  5. //   
  6. this.applicationControl1.Anchor = ((System.Windows.Forms.AnchorStyles) ((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)  
  7.             | System.Windows.Forms.AnchorStyles.Left)  
  8.             | System.Windows.Forms.AnchorStyles.Right)));  
  9. this.applicationControl1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;  
  10. // 在这里设置要嵌入的程序路径,我试验了灵格斯翻译专家成功,QQ没试,据说不成功,我不清楚呵呵。)  
  11. this.applicationControl1.ExeName = @"f:/EditPlus/EDITPLUS.EXE";  
  12. //this.applicationControl1.ExeName = @"f:/Tencent/QQ/QQ.exe";//QQ的没成功  
  13. this.applicationControl1.Location = new System.Drawing.Point(29, 26);  
  14. this.applicationControl1.Name = "applicationControl1";  
  15. this.applicationControl1.Size = new System.Drawing.Size(230, 195);  
  16. this.applicationControl1.TabIndex = 0;  

特别申明:本文纯属个人在网上搜索所得。感谢原文网址( http://www.chenjiliang.com/Article/View.aspx?ArticleID=2103)

运行效果见图片

将外部应用程序嵌入WinForm中_第1张图片


你可能感兴趣的:(将外部应用程序嵌入WinForm中)