在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的界面包含进来的.

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

 

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

 

本文源代码

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

 

转载于:https://www.cnblogs.com/hackpig/p/5783604.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/403260.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SPI总线时序

SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,正是出于这种简单易用的特性,现在越来…

js计算浮点数出现小数;解决js计算小数问题;js数组相加出现小数;

原博1 原博2 方案1和方案2都是有效的 注意参数一定要是数字 而不能是字符串 否则会计算错误 情景: 在计算浮点数时候,出现多余小数。 例如: 1.11 1 2.1100000000000003 为什么计算小数会出现误差? 浮点数值的最高进度是17位…

Shell脚本中获取本机ip地址的3个方法

From: http://www.jb51.net/article/56585.htm 这篇文章主要介绍了Shell脚本中获取本机ip地址的3个方法,本文直接给出实现代码,需要的朋友可以参考下方法一: 复制代码 代码如下:/sbin/ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6|awk {print $2}|tr -d…

VMware安装系统时没有弹出分区设置

在安装虚拟机系统的时候,有时候会遇到在安装一些镜像时没有弹出分区设置的画面,比如,我在使用 VMware 安装 CentOS 的时候,在选择完镜像,设置好启动安装的时候系统自动为我划分了 3 个分区:/boot、/、swap分…

如何在postgresql中模拟oracle的dual表,来测试数据库最基本的连接功能?

还好,网上弄到的,,没有dual的数据库,可以试图用select函数不带from数据表的方式来实现返回值。 一段测试代码: try:conn psycopg2.connect(databasedb.service_name, userdb.username, passwordpassword, hostdb.ip, …

Linux 系统如何查看硬盘UUID与修改

一、查看 1. sudo blkid 2. ls -l /dev/disk/by-uuid 3. tune2fs -l /dev/sdb 二、修改与恢复 uuidgen 会返回一个合法的 uuid,结合 tune2fs 可以新生成一个 uuid 并写入 ext2,3,4 分区中: 比如新建或改变 sda5 的 uuid (需要 root 权限…

vue+element实现树状表格的增删改查;使用el-table树形数据与懒加载实现树状表格增删改查

以下代码可以直接复制使用 一、情景: 列表是一个树状表格,可以无限添加下级,以及对列表的某一行进行增删改查(目前查没有写)。 原博链接 二、本篇是在原博主的代码基础上添加了部分功能。 功能1: 给树状表格…

定时任务 Crontab命令 详解

From: http://www.centoscn.com/CentOS/help/2014/1030/4025.html 前言 crontab是Unix和Linux用于设置周期性被执行的指令,是互联网很常用的技术,很多任务都会设置在crontab循环执行,如果不使用crontab,那么任务就是常驻程序&…

Web Js 按键事件……Enter提交事件 Enter Js事件

$(document).ready(function(){document.onkeydown function (event){ if (event.keyCode13) //回车键的键值为13 submit();}; });$(document).ready(funtion) 可以简写为 ↓ $(function(){});转载于:https://www.cnblogs.com/blogs2014/p/5789256.html

ISCSI 1-由零开始

iSCSI的概念 iSCSI,即Internet SCSI,是IETF制订的一项标准,用于将SCSI数据块映射为以太网数据包。从根本上说,它是一种基于IP Storage理论的新型存储技术,该技术将存储行业广泛应用的SCSI接口技术与IP网络技术相结合&a…

js获取当前日期并格式化(多种格式)

获取当前日期的格式:2022-01-07 或者 2022/01/07 或者 2022-01-07 12:00:00 或者 2022/01/07 12:00:00 原博链接 方法1: // 对Date的扩展,将 Date 转化为指定格式的String // 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个…

为什么移动硬盘的实际容量比标注容量小

很多网友都反映,自己的移动硬盘实际容量并没有厂商标注的容量大,都怀疑自己是不是被坑了,其实不是的,小编现在为你解密为何硬盘实际容量小于标注容量的问题。对于此种情况,有多方面原因导致1.对于存储容量的计算&#…

bash: mail: command not found的解决方法

From: http://hxl2009.blog.51cto.com/779549/884569 近日,安装了一个最小化的centos 6.2 64bit,系统中显示有root用户的mail,想用mail命令查看相关信件, 但发现一个问题: -bash: mail: command not found 呵呵&#…

Who is the best at Dataset X?

推荐一个关于分类、目标检测、姿态估计的数据集收藏的网页。 Did you ever want to quickly learn?which paper provides the best results on standard dataset X ?Wait no more, just click below and discover the current state of the art. URL:ht…

存储技术与iSCSI

本章主要介绍基于IP SAN的网络存储iSCSI。iSCSI技术以其低廉的构建成本和优秀的存储性能,博得了很多CIO和存储管理员的喜爱,目前陆续进入企业应用领域,推动了企业的存储环境向集中式转变。虽然,目前对于iSCSI应该在什么样的环境中…

js判断字符串包含英文;js判断字符串包含汉字;

let str 123qwer汉字if (/.*[\u4e00-\u9fa5].*$/.test(str)) {this.alert(包含汉字)}if (/[a-zA-Z]/.test(str)) {this.alert(包含英文字母)}

lvs和HA的高可用性

Heartbeat实现Lvs高可用和HA高可用效果图如下1、heartbeat的介绍Heartbeat 项目是 Linux-HA 工程的一个组成部分,它实现了一个高可用集群系统。心跳服务和集群通信是高可用集群的两个关键组件,在 Heartbeat 项目里,由 heartbeat 模块实现了这…

postfix报错postfix: fatal: parameter inet_interfaces: no local interface found for ::1

From: http://blog.csdn.net/xiangshanqishi/article/details/23439397 启动postfix出错,查看centos中的postfix日志 more /var/log/maillog postfix: fatal: parameter inet_interfaces: no local interface found for ::1 vi /etc/postfix/main.cf 发现配…

Linux LVM-删除卷组逻辑卷物理卷

查看卷组相关信息 [rootlocalhost /]# vgscanReading all physical volumes. This may take a while...Found volume group "VolGroup00" using metadata type lvm2 查看卷组VolGroup00包含的PV、LV信息。 [rootlocalhost /]# vgdisplay -v VolGroup00Using volume …

输入框限制只能输入数字,正数、负数、0,最多两位小数;数字输入框可以输入负数,并最多保留两位小数;el-number-input去掉四舍五入和自动补齐小数;

场景: –要求1:输入框只能输入数字,可以使正数、负数、0,小数点最多保留两位。 –要求2:不需要自动补齐小数点,也不需要自动四舍五入。 element-ui的数字输入框el-input-number只能满足要求1,所…