在winform上内嵌入其它的程序

这段代码很有意义,用于把一个程序的界面嵌入到我们自己程序的某个指定窗体上.

比如在某个项目里,我需要把基恩士的激光扫描轮廓显示给客户看,但是激光的DLL中并没有这种功能提供. 于是我想先启动激光的官方程序用以显示轮廓, 然后再把这种显示界面嵌入到我自己程序的界面上指定的位置上.

在笔者构想的PLC仿真器由梯形图编辑器, 3D仿真组态环境两部分组成, 这两部分就可以考虑开发成独立的软件,然后嵌入到我需要的另外的一款PLC仿真教学软件中去.

源代码如下:

  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.InteropServices;
 10 using System.Diagnostics;
 11 using System.Threading;
 12
 13 namespace WindowsFormsApplication1
 14 {
 15     public partial class Form1 : Form
 16     {
 17         Process p;
 18
 19         public Form1()
 20         {
 21             InitializeComponent();
 22         }
 23
 24         #region API
 25         [DllImport("user32.dll")]
 26         private static extern int SetParent(IntPtr hWndChild, IntPtr hWndParent);
 27
 28         [DllImport("user32.dll")]
 29         private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
 30
 31         [DllImport("user32.dll", SetLastError = true)]
 32         private static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
 33
 34         [DllImport("user32.dll", EntryPoint = "SetWindowPos")]
 35         private static extern bool SetWindowPos(IntPtr hWnd, int hWndInsertAfter,
 36                     int X, int Y, int cx, int cy, uint uFlags);
 37
 38         [DllImport("user32.dll")]
 39         private static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
 40
 41         [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
 42         private static extern uint SetWindowLong(IntPtr hwnd, int nIndex, uint newLong);
 43
 44         [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
 45         private static extern uint GetWindowLong(IntPtr hwnd, int nIndex);
 46
 47         [DllImport("user32.dll", CharSet = CharSet.Auto)]
 48         private static extern bool ShowWindow(IntPtr hWnd, short State);
 49
 50         private const int HWND_TOP = 0x0;
 51         private const int WM_COMMAND = 0x0112;
 52         private const int WM_QT_PAINT = 0xC2DC;
 53         private const int WM_PAINT = 0x000F;
 54         private const int WM_SIZE = 0x0005;
 55         private const int SWP_FRAMECHANGED = 0x0020;
 56         public enum ShowWindowStyles : short
 57         {
 58             SW_HIDE = 0,
 59             SW_SHOWNORMAL = 1,
 60             SW_NORMAL = 1,
 61             SW_SHOWMINIMIZED = 2,
 62             SW_SHOWMAXIMIZED = 3,
 63             SW_MAXIMIZE = 3,
 64             SW_SHOWNOACTIVATE = 4,
 65             SW_SHOW = 5,
 66             SW_MINIMIZE = 6,
 67             SW_SHOWMINNOACTIVE = 7,
 68             SW_SHOWNA = 8,
 69             SW_RESTORE = 9,
 70             SW_SHOWDEFAULT = 10,
 71             SW_FORCEMINIMIZE = 11,
 72             SW_MAX = 11
 73         }
 74         #endregion
 75
 76         private void Form1_Load(object sender, EventArgs e)
 77         {
 78             p = new Process();
 79             //需要启动的程序
 80             p.StartInfo.FileName = @"calc.exe";
 81             //为了美观,启动的时候最小化程序
 82             p.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
 83             //启动
 84             p.Start();
 85
 86             //这里必须等待,否则启动程序的句柄还没有创建,不能控制程序
 87             Thread.Sleep(10000);
 88             //最大化启动的程序
 89             ShowWindow(p.MainWindowHandle, (short)ShowWindowStyles.SW_MAXIMIZE);
 90             //设置被绑架程序的父窗口
 91             SetParent(p.MainWindowHandle, this.Handle);
 92             //改变尺寸
 93             ResizeControl();
 94         }
 95
 96         //控制嵌入程序的位置和尺寸
 97         private void ResizeControl()
 98         {
 99             SendMessage(p.MainWindowHandle, WM_COMMAND, WM_PAINT, 0);
100             PostMessage(p.MainWindowHandle, WM_QT_PAINT, 0, 0);
101
102             SetWindowPos(
103             p.MainWindowHandle,
104               HWND_TOP,
105               0 - 10,//设置偏移量,把原来窗口的菜单遮住
106                0 - 32,
107               (int)this.Width + 32,
108               (int)this.Height + 32,
109               SWP_FRAMECHANGED);
110
111             SendMessage(p.MainWindowHandle, WM_COMMAND, WM_SIZE, 0);
112         }
113
114         private void Form1_SizeChanged(object sender, EventArgs e)
115         {
116             ResizeControl();
117         }
118
119         private void Form1_FormClosing(object sender, FormClosingEventArgs e)
120         {
121             p.Kill();
122             p.Dispose();
123         }
124     }
125 }

核心功能利用了windows API中的SetParent()

程序运行后, 先启动calc.exe(windows计算器), 然后等待10秒后再显示本程序自己的窗体, 这时你会发现这个窗体已经把calc.exe的界面包含进来的.

这样你就可以清楚的看到嵌入的效果是怎么样的.

本文源代码

时间: 2024-11-07 15:36:56

在winform上内嵌入其它的程序的相关文章

[转]嵌入字体到程序 Winform C#

http://www.cnblogs.com/top5/archive/2011/06/20/2084942.html 程序安装字体或直接调用非注册字体[c#] 1.安装字体 //程序直接将字体文件安装的系统中. 函数声明: [DllImport("kernel32.dll", SetLastError = true)] static extern int WriteProfileString(string lpszSection, string lpszKeyName, string

在winform嵌入外部应用程序

应朋友要求,需要将一个第三方应用程序嵌入到本程序WinForm窗口,以前在VB6时代做过类似的功能,其原理就是利用Windows API中FindWindow函数找到第三方应用程序句柄,再利用SetParent函数,将该句柄设置为本窗口的子窗口. 网上搜索大部分都是利用System.Diagnostics.Process获取外部应用程序的MainWindowHandle,貌似以前的COM应用程序可以,在Win10下调用Process.MainWindowHandle会提示“应用程序已退出”,也就

WPF中嵌入普通Win32程序的方法

公司现在在研发基于.Net中WPF技术的产品,由于要兼容旧有产品,比如一些旧有的Win32程序.第三方的Win32程序等等,还要实现自动登录这些外部Win32程序,因此必须能够将这些程序整合到我们的系统中来,让使用者看起来它们好像是一个程序. 在MSDN中有专门的章节提到了在WPF中嵌入Win32控件的办法,那就是使用 HwndHost ,只要把 Win32控件的句柄传递给 HwndHost 就可以了.MSDN中的例子演示的都是在同一个进程内创建的 Win32控件,我一开始认为只要通过FindW

把任意的EXE嵌入到自己程序中

把任意的EXE嵌入到自己程序中 taoyuan19822008-08-24上传 Delphi把任意的EXE嵌入到自己程序中的程序 资源积分:0分 下载次数:327 资源类型:其他 资源大小:175KB 资源得分: (42位用户参与评分) 把任意的EXE嵌入到自己程序中 进入下载页 收藏(1) 评论(14) 举报 VIP下载  免积分60元/年(1200次) 相关推荐 把任意的EXE嵌入到自己程序中 把任意的EXE嵌入到自己程序中 您可能还需要 Web程序设计 ...简单的C#宿...matlab

WinForm容器内控件批量效验是否允许为空?设置是否只读?设置是否可用等方法分享

WinForm容器内控件批量效验是否允许为空?设置是否只读?设置是否可用等方法分享 在WinForm程序中,我们有时需要对某容器内的所有控件做批量操作.如批量判断是否允许为空?批量设置为只读.批量设置为可用或不可用等常用操作,本文分享这几种方法,起抛砖引玉的作用,欢迎讨论! 1.  清除容器控件内里面指定控件的值的方法 /// <summary> /// 清除容器里面指定控件的值(通过控件的AccessibleName属性设置为"EmptyValue") /// </

Delphi实现窗体内嵌其他应用程序窗体

实现原理是启动一个应用程序,通过ProcessID得到窗体句柄,然后对其设定父窗体句柄为本程序某控件句柄(本例是窗体内一个Panel的句柄),这样就达成了内嵌的效果. 本文实现的是内嵌一个记事本程序,如下图: 在实现细节上需要注意几点: 为了美化程序的嵌入效果,需要隐藏其标题栏 在外部窗体大小变化时,需要内嵌的窗体也随之变化大小 外部程序退出时,内嵌的程序也要退出 下面是例子程序.新建窗体,上面放置一个Panel控件,名为pnlApp,然后按下面代码编写: ? unit frmTestEmbed

[WinForm] VS2010发布、打包安装程序(超全超详细)

1. 在vs2010 选择"新建项目"→" 其他项目类型"→" Visual Studio Installer→"安装项目": 命名为:Setup1 . 这是在VS2010中将有三个文件夹, 1."应用程序文件夹"表示要安装的应用程序需要添加的文件: 2."用户的'程序'菜单"表示:应用程序安装完,用户的"开始菜单"中的显示的内容,一般在这个文件夹中,需要再创建一个文件用来存放

嵌入资源第三讲:多格式文件内嵌入WPF资源文件

作为一个扩展,你需要了解DotNetZip用法,请参见:C# .NET 使用第三方类库DotNetZip解压/压缩Zip文件 你也需要了解单文件内嵌入资源文件基本方法,参见:WPF调用嵌入的非.net的EXE资源文件 作者:一剑 如果你有一大堆文件或者想通过打包的方式嵌入任意格式的文件到资源文件中,那么你可以打包成一个ZIP文件,再嵌入到资源文件中是一个不错的选择: using System.Reflection;//++ using System.IO; using Ionic.Zip; na

跟上脚步(微信小程序)

微信应用号(小程序,「应用号」的新称呼)终于来了! 目前还处于内测阶段,微信只邀请了部分企业参与封测.想必大家都关心应用号的最终形态到底是什么样子?怎样将一个「服务号」改造成为「小程序」? 我们暂时以一款简单的第三方工具的实例,来演示一下开发过程吧—— 序言 开始开发应用号之前,先看看官方公布的「小程序」教程吧!(以下内容来自微信官方公布的「小程序」开发指南) 本文档将带你一步步创建完成一个微信小程序,并可以在手机上体验该小程序的实际效果.这个小程序的首页将会显示欢迎语以及当前用户的微信头像,点