写了一个不使用 COM, 而是通过 WIN32 API 实现的示例, 它把写字板程序嵌在了自己的一个面板中.

这么做可能没有实际意义, 因为两个程序之前没有进行有价值的交互, 这里仅仅是为了演示这么做到, 以下是详细注释过的主要源代码.

我把它封装到一个类中:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Diagnostics;
  6. using System.Runtime.InteropServices;
  7. using System.Windows.Forms;
  8. namespace System.Windows.Forms
  9. {
  10. class InsertWindow
  11. {
  12. /// <summary>
  13. /// 将程序嵌入窗体
  14. /// </summary>
  15. /// <param name="pW">容器</param>
  16. /// <param name="appname">程序名</param>
  17. public InsertWindow(Panel pW,string appname)
  18. {
  19. this.pan = pW;
  20. this.LoadEvent(appname);
  21. pane();
  22. }
  23. ~InsertWindow()
  24. {
  25. if (m_innerProcess!=null)
  26. {
  27. m_innerProcess.Dispose();
  28. }
  29. }
  30. #region  函数和变量声明
  31. /*
  32. * 声明 Win32 API
  33. */
  34. [DllImport("user32.dll")]
  35. static extern IntPtr SetParent(IntPtr hWndChild,
  36. IntPtr hWndNewParent
  37. );
  38. [DllImport("user32.dll")]
  39. static extern Int32 GetWindowLong(IntPtr hWnd,
  40. Int32 nIndex
  41. );
  42. [DllImport("user32.dll")]
  43. static extern Int32 SetWindowLong(IntPtr hWnd,
  44. Int32 nIndex,
  45. Int32 dwNewLong
  46. );
  47. [DllImport("user32.dll")]
  48. static extern Int32 SetWindowPos(IntPtr hWnd,
  49. IntPtr hWndInsertAfter,
  50. Int32 X,
  51. Int32 Y,
  52. Int32 cx,
  53. Int32 cy,
  54. UInt32 uFlags
  55. );
  56. /*
  57. * 定义 Win32 常数
  58. */
  59. const Int32 GWL_STYLE = -16;
  60. const Int32 WS_BORDER = (Int32)0x00800000L;
  61. const Int32 WS_THICKFRAME = (Int32)0x00040000L;
  62. const Int32 SWP_NOMOVE = 0x0002;
  63. const Int32 SWP_NOSIZE = 0x0001;
  64. const Int32 SWP_NOZORDER = 0x0004;
  65. const Int32 SWP_FRAMECHANGED = 0x0020;
  66. const Int32 SW_MAXIMIZE = 3;
  67. IntPtr HWND_NOTOPMOST = new IntPtr(-2);
  68. // 目标应用程序的进程.
  69. Process m_innerProcess = null;
  70. #endregion
  71. #region  容器
  72. private Panel pan = null;
  73. public Panel panel1
  74. {
  75. set { pan = value; }
  76. get { return pan; }
  77. }
  78. private void pane()
  79. {
  80. panel1.Anchor = AnchorStyles.Left | AnchorStyles.Top |
  81. AnchorStyles.Right | AnchorStyles.Bottom;
  82. panel1.Resize += new EventHandler(panel1_Resize);
  83. }
  84. private void panel1_Resize(object sender, EventArgs e)
  85. {
  86. // 设置目标应用程序的窗体样式.
  87. IntPtr innerWnd = m_innerProcess.MainWindowHandle;
  88. SetWindowPos(innerWnd, IntPtr.Zero, 0, 0,
  89. panel1.ClientSize.Width, panel1.ClientSize.Height,
  90. SWP_NOZORDER);
  91. }
  92. #endregion
  93. #region  相应事件
  94. private void LoadEvent(string appFile)
  95. {
  96. // 启动目标应用程序.
  97. m_innerProcess = Process.Start(appFile);
  98. m_innerProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; //隐藏
  99. // 等待, 直到那个程序已经完全启动.
  100. m_innerProcess.WaitForInputIdle();
  101. // 目标应用程序的主窗体.
  102. IntPtr innerWnd = m_innerProcess.MainWindowHandle;
  103. // 设置目标应用程序的主窗体的父亲(为我们的窗体).
  104. SetParent(innerWnd, panel1.Handle);
  105. // 除去窗体边框.
  106. Int32 wndStyle = GetWindowLong(innerWnd, GWL_STYLE);
  107. wndStyle &= ~WS_BORDER;
  108. wndStyle &= ~WS_THICKFRAME;
  109. SetWindowLong(innerWnd, GWL_STYLE, wndStyle);
  110. SetWindowPos(innerWnd, IntPtr.Zero, 0, 0, 0, 0,
  111. SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
  112. // 在Resize事件中更新目标应用程序的窗体尺寸.
  113. panel1_Resize(panel1, null);
  114. }
  115. #endregion
  116. }
  117. }

然后在 窗口的 load事件中 加入

详细代码 如下:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Windows.Forms;
  9. using System.Runtime;
  10. using System.Runtime.InteropServices;
  11. using System.Diagnostics;
  12. namespace 将程序窗口嵌入到任务栏中
  13. {
  14. public partial class Form1 : Form
  15. {
  16. private System.Windows.Forms.Panel panel1;
  17. public Form1()
  18. {
  19. InitializeComponent();
  20. this.panel1 = new System.Windows.Forms.Panel();
  21. this.SuspendLayout();
  22. //
  23. // panel1
  24. //
  25. this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
  26. this.panel1.Location = new System.Drawing.Point(0, 0);
  27. this.panel1.Name = "panel1";
  28. this.panel1.Size = new System.Drawing.Size(292, 273);
  29. this.panel1.TabIndex = 0;
  30. this.Controls.Add(this.panel1);
  31. Load += new EventHandler(Form1_Load);
  32. }
  33. private void Form1_Load(object sender, EventArgs e)
  34. {
  35. //string sPath = Environment.GetEnvironmentVariable("windir");//获取系统变量 windir(windows)
  36. const string appFile =
  37. "C:\\Program Files\\Windows NT\\Accessories\\wordpad.exe";
  38. InsertWindow insertwin = new InsertWindow(panel1, appFile);
  39. }
  40. }
  41. }

通过 WIN32 API 实现嵌入程序窗体的更多相关文章

  1. C#通过WIN32 API实现嵌入程序窗体

    本文实例讲述了C#通过WIN32 API实现嵌入程序窗体的方法,分享给大家供大家参考.具体如下: 这是一个不使用COM,而是通过WIN32 API实现的示例, 它把写字板程序嵌在了自己的一个面板中. ...

  2. 重温 Win32 API ----- 截屏指定窗体并打印

    朋友说在一个VC++6.0开发的项目中要增加打印窗体的功能,让帮忙写个代码供其调用. 这么老的IDE当然不想碰了,并且也不喜欢MFC笨拙不清晰的封装.所以决定採用纯Win32 API,然后用C++类简 ...

  3. C# 窗体常用API函数 应用程序窗体查找

    常用的处理窗体的API函数如下(注意:API函数必须放在窗体中...): 使用C#语言,要引用DllImport,必须要添加using System.Runtime.InteropServices命名 ...

  4. MSIL 教程(二):数组、分支、循环、使用不安全代码和如何调用Win32 API(转)

    转自:http://www.cnblogs.com/Yahong111/archive/2007/08/16/857574.html 续上文[翻译]MSIL 教程(一) ,本文继续讲解数组.分支.循环 ...

  5. VS中空项目、win32项目、控制台程序的区别(转)

    空项目,大多数想单纯创建c++工程的新同学,打开vs后很可能不知道选择创建什么工程,这时候请相信我,空项目是你最好的选择.因为空工程不包含任何的源代码文件,接下来你只需要在相应的源代码文件夹和头文件文 ...

  6. C# 使用Win32 API将1个EXE程序嵌入另1个程序中

    已经干到天快亮了,就不废话直接贴点儿代码吧 ; ; /// <summary> /// 查找窗口 ///第一个参数是窗口的标题,第二个参数可直接用 null ///通过窗口的标题查找对应的 ...

  7. WPF Win32 API 嵌入Form 窗体

    WIn32 API: public class Win32Native { [DllImport("user32.dll", SetLastError = true, CharSe ...

  8. exe程序嵌入Winform窗体

    1.新建winform程序,添加一个Panel控件和一个button控件,winform窗体命名为:Mainform: 2.新建一个类文件,方便引用,命名为:exetowinform: 3.Mainf ...

  9. C#自定义控件:WinForm将其它应用程序窗体嵌入自己内部【转载】

    这是最近在做的一个项目中提到的需求,把一个现有的窗体应用程序界面嵌入到自己开发的窗体中来,看起来就像自己开发的一样(实际上……跟自己开发的还是有一点点区别的,就是内嵌程序和宿主程序的窗口激活状态问题) ...

随机推荐

  1. 【JAVA错误笔记】 - c3p0问题java.lang.NoClassDefFoundError:com.mchange.v2.ser.Indirector

    错误描述:java.lang.NoClassDefFoundError:com.mchange.v2.ser.Indirector 原因分析: 这是c3p0的一个错误信息,我们在下载 c3p0时候,z ...

  2. 学习笔记_过滤器应用_1(分ip统计网站的访问次数)

    分ip统计网站的访问次数 ip count 192.168.1.111 2 192.168.1.112 59 统计工作需要在所有资源之前都执行,那么就可以放到Filter中了. 我们这个过滤器不打算做 ...

  3. Java线程间通信-回调的实现方式

    Java线程间通信-回调的实现方式   Java线程间通信是非常复杂的问题的.线程间通信问题本质上是如何将与线程相关的变量或者对象传递给别的线程,从而实现交互.   比如举一个简单例子,有一个多线程的 ...

  4. Win7/Win8.1预订升级Win10失败临时解决方案

    很多Win7/Win8.1用户在今天凌晨通过微软官方推送的方式升级Win10,但这一过程中遇到了“安装失败”等问题,导致升级无法进行.鉴于这种情况,很多用户选择进入Windows10预下载安装文件夹打 ...

  5. SQL 查找存储过程及视图与自带函数

    查找所有所有存储过程的名称及信息select * from sysobjectswhere type='P' 查看存储过程定义语句sp_helptext [存储过程名] 查看所有视图及信息select ...

  6. html-----014---统一资源定位器

    HTML 统一资源定位器 URL 可以由单词组成,比如 “w3school.com.cn”,或者是因特网协议(IP)地址:192.168.1.253.大多数人在网上冲浪时,会键入网址的域名,因为名称比 ...

  7. 查看编译后的calss文件编译jdk版本

    使用UtralEdit或者sublime text打开编译后的.class文件, 其中cafe babe为magic number(魔数),标识这个文件是java的class文件. 0033转换成10 ...

  8. tomcat内存溢出问题

    内存泄露java.lang.OutOfMemoryError: PermGen space解决办法 今天访问web服务器,tomcat服务就瘫痪了,通过查看日志,发现java.lang.OutOfMe ...

  9. docker中搭建gitlab

    1, 下载镜像 docker pull sameersbn/gitlab:7.4.3 # 下载gitlab镜像 docker pull sameersbn/mysql:latest # 下载gitla ...

  10. linux相关解压命令

    ZIP 我们可以使用下列的命令压缩一个目录: # zip -r archive_name.zip directory_to_compress 下面是如果解压一个zip文档: # unzip archi ...