1.新建winform程序,添加一个Panel控件和一个button控件,winform窗体命名为:Mainform;

exe程序嵌入Winform窗体(转载)_任务栏

2.新建一个类文件,方便引用,命名为:exetowinform;

exe程序嵌入Winform窗体(转载)_控件_02

3.Mainform中cs代码如下:


[csharp]​view plain​​​ ​​copy​​​ ​​print​​​​?​


  1. exetowinform fr = null;
  2. private void button1_Click(object sender, EventArgs e)
  3. {
  4. OpenFileDialog Oppf = new OpenFileDialog();
  5. Oppf.ShowDialog();
  6. if (Oppf.FileName != "")
  7. {
  8. panel1.Controls.Clear();
  9. fr = new exetowinform(panel1, "");
  10. fr.Start(Oppf.FileName);
  11. }
  12. }


4.exetowinform类文件代码如下:



[csharp]​view plain​​​ ​​copy​​​ ​​print​​​​?​


  1. public class exetowinform
  2. {
  3. EventHandler appIdleEvent = null;
  4. Control ParentCon = null;
  5. string strGUID = "";

  6. public exetowinform(Control C, string Titlestr)
  7. {
  8. appIdleEvent = new EventHandler(Application_Idle);
  9. ParentCon = C;
  10. strGUID = Titlestr;
  11. }

  12. /// <summary>
  13. /// 将属性<code>AppFilename</code>指向的应用程序打开并嵌入此容器
  14. /// </summary>
  15. public IntPtr Start(string FileNameStr)
  16. {
  17. if (m_AppProcess != null)
  18. {
  19. Stop();
  20. }
  21. try
  22. {
  23. ProcessStartInfo info = new ProcessStartInfo(FileNameStr);
  24. info.UseShellExecute = true;
  25. info.WindowStyle = ProcessWindowStyle.Minimized;
  26. m_AppProcess = System.Diagnostics.Process.Start(info);
  27. m_AppProcess.WaitForInputIdle();
  28. Application.Idle += appIdleEvent;
  29. }
  30. catch
  31. {
  32. if (m_AppProcess != null)
  33. {
  34. if (!m_AppProcess.HasExited)
  35. m_AppProcess.Kill();
  36. m_AppProcess = null;
  37. }
  38. }
  39. return m_AppProcess.Handle;
  40. }
  41. /// <summary>
  42. /// 确保应用程序嵌入此容器
  43. /// </summary>
  44. /// <param name="sender"></param>
  45. /// <param name="e"></param>
  46. void Application_Idle(object sender, EventArgs e)
  47. {
  48. if (this.m_AppProcess == null || this.m_AppProcess.HasExited)
  49. {
  50. this.m_AppProcess = null;
  51. Application.Idle -= appIdleEvent;
  52. return;
  53. }

  54. while (m_AppProcess.MainWindowHandle == IntPtr.Zero)
  55. {
  56. Thread.Sleep(100);
  57. m_AppProcess.Refresh();
  58. }
  59. Application.Idle -= appIdleEvent;
  60. EmbedProcess(m_AppProcess, ParentCon);
  61. }
  62. /// <summary>
  63. /// 应用程序结束运行时要清除这里的标识
  64. /// </summary>
  65. /// <param name="sender"></param>
  66. /// <param name="e"></param>
  67. void m_AppProcess_Exited(object sender, EventArgs e)
  68. {
  69. m_AppProcess = null;
  70. }
  71. /// <summary>
  72. /// 将属性<code>AppFilename</code>指向的应用程序关闭
  73. /// </summary>
  74. public void Stop()
  75. {
  76. if (m_AppProcess != null)// && m_AppProcess.MainWindowHandle != IntPtr.Zero)
  77. {
  78. try
  79. {
  80. if (!m_AppProcess.HasExited)
  81. m_AppProcess.Kill();
  82. }
  83. catch (Exception)
  84. {
  85. }
  86. m_AppProcess = null;
  87. }
  88. }


  89. #region 属性
  90. /// <summary>
  91. /// application process
  92. /// </summary>
  93. Process m_AppProcess = null;

  94. /// <summary>
  95. /// 标识内嵌程序是否已经启动
  96. /// </summary>
  97. public bool IsStarted { get { return (this.m_AppProcess != null); } }

  98. #endregion 属性

  99. #region Win32 API
  100. [DllImport("user32.dll", EntryPoint = "GetWindowThreadProcessId", SetLastError = true,
  101. CharSet = CharSet.Unicode, ExactSpelling = true,
  102. CallingConvention = CallingConvention.StdCall)]
  103. private static extern long GetWindowThreadProcessId(long hWnd, long lpdwProcessId);

  104. [DllImport("user32.dll", SetLastError = true)]
  105. private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

  106. [DllImport("user32.dll", SetLastError = true)]
  107. private static extern long SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

  108. [DllImport("user32.dll", EntryPoint = "GetWindowLongA", SetLastError = true)]
  109. private static extern long GetWindowLong(IntPtr hwnd, int nIndex);

  110. public static IntPtr SetWindowLong(HandleRef hWnd, int nIndex, int dwNewLong)
  111. {
  112. if (IntPtr.Size == 4)
  113. {
  114. return SetWindowLongPtr32(hWnd, nIndex, dwNewLong);
  115. }
  116. return SetWindowLongPtr64(hWnd, nIndex, dwNewLong);
  117. }
  118. [DllImport("user32.dll", EntryPoint = "SetWindowLong", CharSet = CharSet.Auto)]
  119. public static extern IntPtr SetWindowLongPtr32(HandleRef hWnd, int nIndex, int dwNewLong);
  120. [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr", CharSet = CharSet.Auto)]
  121. public static extern IntPtr SetWindowLongPtr64(HandleRef hWnd, int nIndex, int dwNewLong);

  122. [DllImport("user32.dll", SetLastError = true)]
  123. private static extern long SetWindowPos(IntPtr hwnd, long hWndInsertAfter, long x, long y, long cx, long cy, long wFlags);

  124. [DllImport("user32.dll", SetLastError = true)]
  125. private static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint);

  126. [DllImport("user32.dll", EntryPoint = "PostMessageA", SetLastError = true)]
  127. private static extern bool PostMessage(IntPtr hwnd, uint Msg, uint wParam, uint lParam);

  128. [DllImport("user32.dll", SetLastError = true)]
  129. private static extern IntPtr GetParent(IntPtr hwnd);

  130. [DllImport("user32.dll", EntryPoint = "ShowWindow", SetLastError = true)]
  131. static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

  132. private const int SWP_NOOWNERZORDER = 0x200;
  133. private const int SWP_NOREDRAW = 0x8;
  134. private const int SWP_NOZORDER = 0x4;
  135. private const int SWP_SHOWWINDOW = 0x0040;
  136. private const int WS_EX_MDICHILD = 0x40;
  137. private const int SWP_FRAMECHANGED = 0x20;
  138. private const int SWP_NOACTIVATE = 0x10;
  139. private const int SWP_ASYNCWINDOWPOS = 0x4000;
  140. private const int SWP_NOMOVE = 0x2;
  141. private const int SWP_NOSIZE = 0x1;
  142. private const int GWL_STYLE = (-16);
  143. private const int WS_VISIBLE = 0x10000000;
  144. private const int WM_CLOSE = 0x10;
  145. private const int WS_CHILD = 0x40000000;

  146. private const int SW_HIDE = 0; //{隐藏, 并且任务栏也没有最小化图标}
  147. private const int SW_SHOWNORMAL = 1; //{用最近的大小和位置显示, 激活}
  148. private const int SW_NORMAL = 1; //{同 SW_SHOWNORMAL}
  149. private const int SW_SHOWMINIMIZED = 2; //{最小化, 激活}
  150. private const int SW_SHOWMAXIMIZED = 3; //{最大化, 激活}
  151. private const int SW_MAXIMIZE = 3; //{同 SW_SHOWMAXIMIZED}
  152. private const int SW_SHOWNOACTIVATE = 4; //{用最近的大小和位置显示, 不激活}
  153. private const int SW_SHOW = 5; //{同 SW_SHOWNORMAL}
  154. private const int SW_MINIMIZE = 6; //{最小化, 不激活}
  155. private const int SW_SHOWMINNOACTIVE = 7; //{同 SW_MINIMIZE}
  156. private const int SW_SHOWNA = 8; //{同 SW_SHOWNOACTIVATE}
  157. private const int SW_RESTORE = 9; //{同 SW_SHOWNORMAL}
  158. private const int SW_SHOWDEFAULT = 10; //{同 SW_SHOWNORMAL}
  159. private const int SW_MAX = 10; //{同 SW_SHOWNORMAL}

  160. #endregion Win32 API

  161. /// <summary>
  162. /// 将指定的程序嵌入指定的控件
  163. /// </summary>
  164. private void EmbedProcess(Process app, Control control)
  165. {
  166. // Get the main handle
  167. if (app == null || app.MainWindowHandle == IntPtr.Zero || control == null) return;
  168. try
  169. {
  170. // Put it into this form
  171. SetParent(app.MainWindowHandle, control.Handle);
  172. }
  173. catch (Exception)
  174. { }
  175. try
  176. {
  177. // Remove border and whatnot
  178. SetWindowLong(new HandleRef(this, app.MainWindowHandle), GWL_STYLE, WS_VISIBLE);
  179. SendMessage(app.MainWindowHandle, WM_SETTEXT, IntPtr.Zero, strGUID);
  180. }
  181. catch (Exception)
  182. { }
  183. try
  184. {
  185. // Move the window to overlay it on this window
  186. MoveWindow(app.MainWindowHandle, 0, 0, control.Width, control.Height, true);
  187. }
  188. catch (Exception)
  189. { }
  190. }

  191. [DllImport("User32.dll", EntryPoint = "SendMessage")]
  192. private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);

  193. const int WM_SETTEXT = 0x000C;
  194. }


5.最后结果如图:


exe程序嵌入Winform窗体(转载)_应用程序_03