通过 WIN32 API 实现嵌入程序窗体
写了一个不使用 COM, 而是通过 WIN32 API 实现的示例, 它把写字板程序嵌在了自己的一个面板中.
这么做可能没有实际意义, 因为两个程序之前没有进行有价值的交互, 这里仅仅是为了演示这么做到, 以下是详细注释过的主要源代码.
我把它封装到一个类中:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Diagnostics;
- using System.Runtime.InteropServices;
- using System.Windows.Forms;
- namespace System.Windows.Forms
- {
- class InsertWindow
- {
- /// <summary>
- /// 将程序嵌入窗体
- /// </summary>
- /// <param name="pW">容器</param>
- /// <param name="appname">程序名</param>
- public InsertWindow(Panel pW,string appname)
- {
- this.pan = pW;
- this.LoadEvent(appname);
- pane();
- }
- ~InsertWindow()
- {
- if (m_innerProcess!=null)
- {
- m_innerProcess.Dispose();
- }
- }
- #region 函数和变量声明
- /*
- * 声明 Win32 API
- */
- [DllImport("user32.dll")]
- static extern IntPtr SetParent(IntPtr hWndChild,
- IntPtr hWndNewParent
- );
- [DllImport("user32.dll")]
- static extern Int32 GetWindowLong(IntPtr hWnd,
- Int32 nIndex
- );
- [DllImport("user32.dll")]
- static extern Int32 SetWindowLong(IntPtr hWnd,
- Int32 nIndex,
- Int32 dwNewLong
- );
- [DllImport("user32.dll")]
- static extern Int32 SetWindowPos(IntPtr hWnd,
- IntPtr hWndInsertAfter,
- Int32 X,
- Int32 Y,
- Int32 cx,
- Int32 cy,
- UInt32 uFlags
- );
- /*
- * 定义 Win32 常数
- */
- const Int32 GWL_STYLE = -16;
- const Int32 WS_BORDER = (Int32)0x00800000L;
- const Int32 WS_THICKFRAME = (Int32)0x00040000L;
- const Int32 SWP_NOMOVE = 0x0002;
- const Int32 SWP_NOSIZE = 0x0001;
- const Int32 SWP_NOZORDER = 0x0004;
- const Int32 SWP_FRAMECHANGED = 0x0020;
- const Int32 SW_MAXIMIZE = 3;
- IntPtr HWND_NOTOPMOST = new IntPtr(-2);
- // 目标应用程序的进程.
- Process m_innerProcess = null;
- #endregion
- #region 容器
- private Panel pan = null;
- public Panel panel1
- {
- set { pan = value; }
- get { return pan; }
- }
- private void pane()
- {
- panel1.Anchor = AnchorStyles.Left | AnchorStyles.Top |
- AnchorStyles.Right | AnchorStyles.Bottom;
- panel1.Resize += new EventHandler(panel1_Resize);
- }
- private void panel1_Resize(object sender, EventArgs e)
- {
- // 设置目标应用程序的窗体样式.
- IntPtr innerWnd = m_innerProcess.MainWindowHandle;
- SetWindowPos(innerWnd, IntPtr.Zero, 0, 0,
- panel1.ClientSize.Width, panel1.ClientSize.Height,
- SWP_NOZORDER);
- }
- #endregion
- #region 相应事件
- private void LoadEvent(string appFile)
- {
- // 启动目标应用程序.
- m_innerProcess = Process.Start(appFile);
- m_innerProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; //隐藏
- // 等待, 直到那个程序已经完全启动.
- m_innerProcess.WaitForInputIdle();
- // 目标应用程序的主窗体.
- IntPtr innerWnd = m_innerProcess.MainWindowHandle;
- // 设置目标应用程序的主窗体的父亲(为我们的窗体).
- SetParent(innerWnd, panel1.Handle);
- // 除去窗体边框.
- Int32 wndStyle = GetWindowLong(innerWnd, GWL_STYLE);
- wndStyle &= ~WS_BORDER;
- wndStyle &= ~WS_THICKFRAME;
- SetWindowLong(innerWnd, GWL_STYLE, wndStyle);
- SetWindowPos(innerWnd, IntPtr.Zero, 0, 0, 0, 0,
- SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
- // 在Resize事件中更新目标应用程序的窗体尺寸.
- panel1_Resize(panel1, null);
- }
- #endregion
- }
- }
然后在 窗口的 load事件中 加入
详细代码 如下:
- 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.Runtime;
- using System.Runtime.InteropServices;
- using System.Diagnostics;
- namespace 将程序窗口嵌入到任务栏中
- {
- public partial class Form1 : Form
- {
- private System.Windows.Forms.Panel panel1;
- public Form1()
- {
- InitializeComponent();
- this.panel1 = new System.Windows.Forms.Panel();
- this.SuspendLayout();
- //
- // panel1
- //
- this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
- this.panel1.Location = new System.Drawing.Point(0, 0);
- this.panel1.Name = "panel1";
- this.panel1.Size = new System.Drawing.Size(292, 273);
- this.panel1.TabIndex = 0;
- this.Controls.Add(this.panel1);
- Load += new EventHandler(Form1_Load);
- }
- private void Form1_Load(object sender, EventArgs e)
- {
- //string sPath = Environment.GetEnvironmentVariable("windir");//获取系统变量 windir(windows)
- const string appFile =
- "C:\\Program Files\\Windows NT\\Accessories\\wordpad.exe";
- InsertWindow insertwin = new InsertWindow(panel1, appFile);
- }
- }
- }
通过 WIN32 API 实现嵌入程序窗体的更多相关文章
- C#通过WIN32 API实现嵌入程序窗体
本文实例讲述了C#通过WIN32 API实现嵌入程序窗体的方法,分享给大家供大家参考.具体如下: 这是一个不使用COM,而是通过WIN32 API实现的示例, 它把写字板程序嵌在了自己的一个面板中. ...
- 重温 Win32 API ----- 截屏指定窗体并打印
朋友说在一个VC++6.0开发的项目中要增加打印窗体的功能,让帮忙写个代码供其调用. 这么老的IDE当然不想碰了,并且也不喜欢MFC笨拙不清晰的封装.所以决定採用纯Win32 API,然后用C++类简 ...
- C# 窗体常用API函数 应用程序窗体查找
常用的处理窗体的API函数如下(注意:API函数必须放在窗体中...): 使用C#语言,要引用DllImport,必须要添加using System.Runtime.InteropServices命名 ...
- MSIL 教程(二):数组、分支、循环、使用不安全代码和如何调用Win32 API(转)
转自:http://www.cnblogs.com/Yahong111/archive/2007/08/16/857574.html 续上文[翻译]MSIL 教程(一) ,本文继续讲解数组.分支.循环 ...
- VS中空项目、win32项目、控制台程序的区别(转)
空项目,大多数想单纯创建c++工程的新同学,打开vs后很可能不知道选择创建什么工程,这时候请相信我,空项目是你最好的选择.因为空工程不包含任何的源代码文件,接下来你只需要在相应的源代码文件夹和头文件文 ...
- C# 使用Win32 API将1个EXE程序嵌入另1个程序中
已经干到天快亮了,就不废话直接贴点儿代码吧 ; ; /// <summary> /// 查找窗口 ///第一个参数是窗口的标题,第二个参数可直接用 null ///通过窗口的标题查找对应的 ...
- WPF Win32 API 嵌入Form 窗体
WIn32 API: public class Win32Native { [DllImport("user32.dll", SetLastError = true, CharSe ...
- exe程序嵌入Winform窗体
1.新建winform程序,添加一个Panel控件和一个button控件,winform窗体命名为:Mainform: 2.新建一个类文件,方便引用,命名为:exetowinform: 3.Mainf ...
- C#自定义控件:WinForm将其它应用程序窗体嵌入自己内部【转载】
这是最近在做的一个项目中提到的需求,把一个现有的窗体应用程序界面嵌入到自己开发的窗体中来,看起来就像自己开发的一样(实际上……跟自己开发的还是有一点点区别的,就是内嵌程序和宿主程序的窗口激活状态问题) ...
随机推荐
- STORM 免费且开源的WebSerivce测试工具
一.名称 STORM 是一款免费且开源的WebSerivce测试工具 二.使用方式 1.发布自己的webservice服务 例如:http://www.webxml.com.cn/WebService ...
- Ext.Net学习笔记08:Ext.Net中使用数据
之前的七篇文章都是介绍Ext.Net较为基础的东西,今天的这一篇将介绍数据的一些用法,包括XTemplate绑定数据.Store(Modal.Proxy).ComboBox的用法等. XTemplat ...
- [python]魔术方法
一.初始化: 1.__new__方法,初始化过程中第一个用到的方法(用处不大). 2.之后,__init__方法,构造方法. 3.最后,在对象回收时,调用__del__方法.如果解释器退出时,对象还存 ...
- 巧谈 GCD
转载自:http://www.jianshu.com/p/665261814e24 谈到iOS多线程,一般都会谈到四种方式:pthread.NSThread.GCD和NSOperation.其中,苹果 ...
- js 实现图片旋转角度
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 迭代map方法
Map<String, String> map=new HashMap<String,String>();map.put("1", "one&qu ...
- php随机生成福彩双色球号码
发布:thebaby 来源:net [大 中 小] 不瞒您说,俺也是个双色球爱好者,经常买,但迟迟没有中过一等奖,哈哈.这里为大家介绍用php随机生成福彩双色球号码的二种方法,供朋友们学习 ...
- 直接通过curl方式取得数据、模拟登陆、POST数据
博客园的Markdown编辑器太坑爹了@!!! 算了.不用格式了!!! /********************** curl 系列 ***********************/ //直接通过c ...
- workerman安装
1.workerman安装 workerman是php的一个socket框架,简化了socket编程,已经为很多企业所用,今天在centos的ngix+php下安装了workerman,过程记录如下. ...
- web系列教程之php 与mysql 动态网站 。检索 与更新。
接着上次WEb 系列开发之php 与mysql动态网站入门. 个人觉得,学习技术就像一棵大树,主干很重要,枝叶其次.对于学习技术,我们应该分清主次关系.怎么学?为什么要学?有一个较好的分寸. 有时候觉 ...