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

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

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

源代码如下:

 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.InteropServices;
using System.Diagnostics;
using System.Threading; namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
Process p; public Form1()
{
InitializeComponent();
} #region API
[DllImport("user32.dll")]
private static extern int SetParent(IntPtr hWndChild, IntPtr hWndParent); [DllImport("user32.dll")]
private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow); [DllImport("user32.dll", SetLastError = true)]
private static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam); [DllImport("user32.dll", EntryPoint = "SetWindowPos")]
private static extern bool SetWindowPos(IntPtr hWnd, int hWndInsertAfter,
int X, int Y, int cx, int cy, uint uFlags); [DllImport("user32.dll")]
private static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam); [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern uint SetWindowLong(IntPtr hwnd, int nIndex, uint newLong); [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern uint GetWindowLong(IntPtr hwnd, int nIndex); [DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern bool ShowWindow(IntPtr hWnd, short State); private const int HWND_TOP = 0x0;
private const int WM_COMMAND = 0x0112;
private const int WM_QT_PAINT = 0xC2DC;
private const int WM_PAINT = 0x000F;
private const int WM_SIZE = 0x0005;
private const int SWP_FRAMECHANGED = 0x0020;
public enum ShowWindowStyles : short
{
SW_HIDE = ,
SW_SHOWNORMAL = ,
SW_NORMAL = ,
SW_SHOWMINIMIZED = ,
SW_SHOWMAXIMIZED = ,
SW_MAXIMIZE = ,
SW_SHOWNOACTIVATE = ,
SW_SHOW = ,
SW_MINIMIZE = ,
SW_SHOWMINNOACTIVE = ,
SW_SHOWNA = ,
SW_RESTORE = ,
SW_SHOWDEFAULT = ,
SW_FORCEMINIMIZE = ,
SW_MAX =
}
#endregion private void Form1_Load(object sender, EventArgs e)
{
p = new Process();
//需要启动的程序
p.StartInfo.FileName = @"calc.exe";
//为了美观,启动的时候最小化程序
p.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
//启动
p.Start(); //这里必须等待,否则启动程序的句柄还没有创建,不能控制程序
Thread.Sleep();
//最大化启动的程序
ShowWindow(p.MainWindowHandle, (short)ShowWindowStyles.SW_MAXIMIZE);
//设置被绑架程序的父窗口
SetParent(p.MainWindowHandle, this.Handle);
//改变尺寸
ResizeControl();
} //控制嵌入程序的位置和尺寸
private void ResizeControl()
{
SendMessage(p.MainWindowHandle, WM_COMMAND, WM_PAINT, );
PostMessage(p.MainWindowHandle, WM_QT_PAINT, , ); SetWindowPos(
p.MainWindowHandle,
HWND_TOP,
- ,//设置偏移量,把原来窗口的菜单遮住
- ,
(int)this.Width + ,
(int)this.Height + ,
SWP_FRAMECHANGED); SendMessage(p.MainWindowHandle, WM_COMMAND, WM_SIZE, );
} private void Form1_SizeChanged(object sender, EventArgs e)
{
ResizeControl();
} private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
p.Kill();
p.Dispose();
}
}
}

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

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

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

效果如上图所示. 但是你的程序在退出前,要自己"杀掉"计算器的进程, 否则你的程序退出它还在.

本文源代码

原创文章,出处 : http://www.cnblogs.com/hackpig/

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

  1. 在winform嵌入外部应用程序

    应朋友要求,需要将一个第三方应用程序嵌入到本程序WinForm窗口,以前在VB6时代做过类似的功能,其原理就是利用Windows API中FindWindow函数找到第三方应用程序句柄,再利用SetP ...

  2. 把演讲人的桌面、头像、声音合成后推送到 指定的直播流平台上; 录制电脑桌面、摄像头头像、声音保存为本地视频; 适用于讲课老师、医生等演讲内容保存为视频; 提供PPT嵌入Winform/WPF解决方案,Winform/WPF 中嵌入 office ppt 解决方案

    提供PPT嵌入Winform/WPF解决方案,Winform/WPF 中嵌入 office ppt 解决方案 Winform/WPF 中嵌入 office ppt(powerpoint)解决方案示: ...

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

    实现原理是启动一个应用程序,通过ProcessID得到窗体句柄,然后对其设定父窗体句柄为本程序某控件句柄(本例是窗体内一个Panel的句柄),这样就达成了内嵌的效果. 本文实现的是内嵌一个记事本程序, ...

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

    WinForm容器内控件批量效验是否允许为空?设置是否只读?设置是否可用等方法分享 在WinForm程序中,我们有时需要对某容器内的所有控件做批量操作.如批量判断是否允许为空?批量设置为只读.批量设置 ...

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

    公司现在在研发基于.Net中WPF技术的产品,由于要兼容旧有产品,比如一些旧有的Win32程序.第三方的Win32程序等等,还要实现自动登录这些外部Win32程序,因此必须能够将这些程序整合到我们的系 ...

  6. Delphi SetParent 嵌入其他应用程序

    [代码]Delphi实现窗体内嵌其他应用程序窗体 实现原理是启动一个应用程序,通过ProcessID得到窗体句柄,然后对其设定父窗体句柄为本程序某控件句柄(本例是窗体内一个Panel的句柄),这样就达 ...

  7. 在 Windows Azure 上设计多租户应用程序

    作者:Suren Machiraju 和 Ralph Squillace 审校:Christian Martinez.James Podgorski.Valery Mizonov 和 Michael ...

  8. WinForm容器内控件批量效验是否同意为空?设置是否仅仅读?设置是否可用等方法分享

    WinForm容器内控件批量效验是否同意为空?设置是否仅仅读?设置是否可用等方法分享 在WinForm程序中,我们有时须要对某容器内的全部控件做批量操作.如批量推断是否同意为空?批量设置为仅仅读.批量 ...

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

    把任意的EXE嵌入到自己程序中 taoyuan19822008-08-24上传   Delphi把任意的EXE嵌入到自己程序中的程序 资源积分:0分 下载次数:327 资源类型:其他 资源大小:175 ...

随机推荐

  1. js 报错检查顺序

    如上图所示错误列表: 处理步骤:检查顺序应从最后到前,并且先检查当面页面引用的文件(公共引用文件一般不会出错的) 如:at.nt.query方法检查错误开始 倒推

  2. c# mvc 获取 HtmlHelper 表达式值和时间格式化 去边框

    /// <summary> /// 返回没有边框的只读的TextBox标签 /// </summary> /// <typeparam name="TModel ...

  3. k8s sidecar, Ambassador, Adapter containers

    When you start thinking in terms of Pods, there are naturally some general patterns of modular appli ...

  4. laravel-第一課安裝

    本地安装laravel,php环境要配置好,推荐xmapp一键搭建. 1.程序包直接从官方下载,官方开源地址:https://github.com/laravel/laravel(当然也可从此网站:h ...

  5. 前端Table数据导出Excel使用HSSFWorkbook(Java)

    一.实现原理: 1. 前端查询列表数据并渲染至table(<table>...</table>)表格 2. 表格html代码传输至后台 3. 后台把html转成Excel输出流 ...

  6. js(数组篇02)

    原文:http://www.cnblogs.com/zaking/p/8686676.html 上一篇文章简单的介绍了一下js的类型,以及数组的增删方法.这一篇文章,我们一起来看看数组还有哪些用法,以 ...

  7. 非抢占式RCU中关于grace period的处理(限于方法)

    参考自:http://blog.csdn.net/junguo/article/details/8244530             Documentation/RCU/* TREE_RCU将所有的 ...

  8. jquery方法.serializeArray()获取name和value并转为json数组

    jquery的.serializeArray()方法可以获取形如以下 [ {name: 'firstname', value: 'Hello'}, {name: 'lastname', value: ...

  9. saltstack系列1之salt-api配置与使用

    salt-api salt-api是我们通过restful-api调用salt-master的接口,且调用的时候必须通过认证才能调用,认证的用户为系统用户,下面就说说如何配置salt-api. 不带S ...

  10. 【转】ZooKeeper详细介绍和使用第一节

    一.分布式协调技术 在给大家介绍ZooKeeper之前先来给大家介绍一种技术——分布式协调技术.那么什么是分布式协调技术?那么我来告诉大家,其实分布式协调技术 主要用来解决分布式环境当中多个进程之间的 ...