C# 嵌入第三方EXE界面到panel中
C#可以通过windows API,将第三方程序嵌入到panel中,并且可以隐藏程序边框。
问题:
焦点在内部程序时,主窗口失去焦点;
通讯解决方案
使用 User32.dll SendMessage 发送窗口级的 WM_COPYDATA 消息;使用 DefWndProc 处理消息;
来实现两个独立C#程序之间的通讯。
主程序代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Forms; namespace CallMain
{
public partial class Form1 : Form
{
#region 外部DLL定义 [DllImport("User32.dll", EntryPoint = "SetParent")]
public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent); [DllImport("user32.dll", EntryPoint = "ShowWindow")]
public static extern int ShowWindow(IntPtr hwnd, int nCmdShow); [DllImport("user32.dll", SetLastError = true)]
public static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint); [DllImport("user32.dll")]
public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); const int WS_THICKFRAME = ;
const int WS_BORDER = ;
const int GWL_STYLE = -; [DllImport("User32.dll")]
public static extern int SendMessage(IntPtr hwnd, int msg, IntPtr wParam, ref COPYDATASTRUCT IParam); public const int WM_COPYDATA = 0x004A; public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
[MarshalAs(UnmanagedType.LPStr)]
public string lpData;
} // 发送 windows 消息
public void SendMsg(IntPtr hwnd, string str)
{
byte[] arr = Encoding.Default.GetBytes(str);
int len = arr.Length;
COPYDATASTRUCT cdata;
cdata.dwData = (IntPtr);
cdata.lpData = str;
cdata.cbData = len + ;
SendMessage(hwnd, WM_COPYDATA, this.Handle, ref cdata);
} public delegate void EventMsg(object sender, IntPtr wnd, string str);
public event EventMsg OnMsg; // 进程间消息通讯
protected override void DefWndProc(ref Message m)
{
switch (m.Msg)
{
case WM_COPYDATA:
COPYDATASTRUCT cdata = new COPYDATASTRUCT();
Type mytype = cdata.GetType();
cdata = (COPYDATASTRUCT)m.GetLParam(mytype);
OnMsg(this, m.WParam, cdata.lpData);
break;
default:
base.DefWndProc(ref m);
break;
}
} #endregion public Form1()
{
InitializeComponent();
} private void Form1_Load(object sender, EventArgs e)
{
this.OnMsg += Form1_OnMsg; ;
} private void Form1_OnMsg(object sender, IntPtr wnd, string str)
{
// 接收消息处理
SendMsg(wnd, "收到了子窗口消息:" + str);
} private void button1_Click(object sender, EventArgs e)
{
Process proApp = new Process();
proApp.StartInfo.FileName = Application.StartupPath + "\\CallTest.exe";
proApp.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
proApp.Start();
proApp.WaitForInputIdle(); while (proApp.MainWindowHandle == IntPtr.Zero)
{
Thread.Sleep();
proApp.Refresh();
}
IntPtr wnd = proApp.MainWindowHandle; Int32 wndStyle = GetWindowLong(wnd, GWL_STYLE);
wndStyle &= ~WS_BORDER;
wndStyle &= ~WS_THICKFRAME;
SetWindowLong(wnd, GWL_STYLE, wndStyle); SetParent(wnd, panel1.Handle);
ShowWindow(wnd, (int)ProcessWindowStyle.Maximized); panel1.Tag = proApp; SendMsg(wnd, "hi");
} private void button2_Click(object sender, EventArgs e)
{
// 给子窗口发消息
Process proApp = (Process)panel1.Tag;
SendMsg(proApp.MainWindowHandle, "hello 子窗口");
}
}
}
子程序通讯代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms; namespace CallTest
{
public partial class Form1 : Form
{
#region 消息通讯 [DllImport("User32.dll")]
public static extern int SendMessage(IntPtr hwnd, int msg, IntPtr wParam, ref COPYDATASTRUCT IParam); const int WM_COPYDATA = 0x004A; public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
[MarshalAs(UnmanagedType.LPStr)]
public string lpData;
} private IntPtr MainWnd = IntPtr.Zero; public delegate void EventMsg(object sender, string str);
public event EventMsg OnMsg; //发送消息
private void SendMsg(string str)
{
if (MainWnd == IntPtr.Zero)
{
return;
} byte[] arr = Encoding.Default.GetBytes(str);
int len = arr.Length;
COPYDATASTRUCT cdata;
cdata.dwData = (IntPtr);
cdata.lpData = str;
cdata.cbData = len + ;
SendMessage(MainWnd, WM_COPYDATA, this.Handle, ref cdata);
} protected override void DefWndProc(ref Message m)
{
switch (m.Msg)
{
case WM_COPYDATA:
COPYDATASTRUCT cdata = new COPYDATASTRUCT();
Type mytype = cdata.GetType();
cdata = (COPYDATASTRUCT)m.GetLParam(mytype);
MainWnd = m.WParam; OnMsg(this, cdata.lpData);
break;
default:
base.DefWndProc(ref m);
break;
}
}
#endregion public Form1()
{
InitializeComponent();
} private int index = ;
private void button1_Click(object sender, EventArgs e)
{
// 发送消息
index++;
SendMsg("收到啦!" + index);
} private void Form1_Load(object sender, EventArgs e)
{
this.OnMsg += Form1_OnMsg;
} private void Form1_OnMsg(object sender, string str)
{
// 接收消息
if (str == "hi")
{
SendMsg("hi");
return;
} label1.Text = str;
label2.Text = MainWnd.ToString("x");
}
}
}
C# 嵌入第三方EXE界面到panel中的更多相关文章
- WPF应用程序嵌入第三方exe
把其它应用嵌入到C#窗口 源代码-CSDN下载 https://download.csdn.net/download/aiqinghee/10652732 WPF应用程序嵌入第三方exe - gao2 ...
- C# 把引用的dll嵌入到exe文件中
当发布的程序有引用其它dll, 又只想发布一个exe时就需要把dll打包到exe 当然有多种方法可以打包, 比如微软的ILMerge,混淆器附带的打包... 用代码打包的实现方式也有很好,本文只是其中 ...
- Qt界面中嵌入其他exe程序的界面,使用Qt5
下面用一个小例子来演示如何在Qt的界面中嵌入其他exe程序的界面,最终效果如下图所示.本文参考了 http://blog.csdn.net/jiaoyaziyang/article/details/4 ...
- C#将exe运行程序嵌入到自己的winform窗体中
以下例子是将Word打开,然后将它嵌入到winform窗体中,效果如下图:C将exe运行程序嵌入到自己的winform窗体中 - kingmax_res - iSport注意:该方法只适用于com的e ...
- WPF:将Office文档、任意类型文件嵌入到EXE可执行文件中
原文:WPF:将Office文档.任意类型文件嵌入到EXE可执行文件中 版权声明:本文为博主原创文章,未经博主允许可以随意转载 https://blog.csdn.net/songqingwei198 ...
- WPF程序将DLL嵌入到EXE的两种方法
WPF程序将DLL嵌入到EXE的两种方法 这一篇可以看作是<Visual Studio 版本转换工具WPF版开源了>的续,关于<Visual Studio 版本转换工具WPF版开源了 ...
- WPF编程,获取句柄将外部程序嵌入到WPF界面。
原文:WPF编程,获取句柄将外部程序嵌入到WPF界面. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/article/details ...
- 如何在Exe和BPL插件中实现公共变量共享及窗口溶入技术Demo源码
如何在Exe和BPL插件中实现公共变量共享及窗口溶入技术Demo源码 1.Delphi编译方式介绍: 当我们在开发一个常规应用程序时,Delphi可以让我们用两种方式使用VCL,一种是把VCL中的申明 ...
- Xamarin.Android 嵌入web端界面
在程序中嵌入Web端界面. 首先在前台界面上创建一个webview <android.webkit.WebView android:layout_width="match_parent ...
随机推荐
- Django 之瀑布流实现
需求分析 现在是 "图片为王"的时代,在浏览一些网站时,经常会看到类似于这种满屏都是图片.图片大小不一,却按空间排列,就这是瀑布流布局. 以瀑布流形式布局,从数据库中取出图片 每次 ...
- GeoGebra 代数输入的提示和技巧
GeoGebra是Mac平台上一款自由且跨平台的动态数学软件,提供各级教育使用,包含了几何.代数.表格.图形.统计和微积分,集中在一个容易使用的软件. 确认表达式 始终按 Enter 键确认您 ...
- web服务器-apache
一.apache详解 1. 概述 apache是世界上使用排名第一的web服务器软件.它可以运行在几乎所有广泛使用的计算机平台上,由于其跨平台和安全性被广泛使用,是最流行的web服务器端软件之一.它快 ...
- (05节)快速搭建SSM项目
1.1 快速搭建Web项目 注意点:name:archetypeCatalog,value:internal 原因:Intellij IDEA根据maven archetype的本质,执行mvn a ...
- 字符流,字节流,属性集(Properties)
字节输入流(InputStream) java.io.InputStream抽象类是表示字节输入流的所有类的超类.可以读取字节信息到内存中.它定义了字节输入流的基本共性功能方法. public voi ...
- Spring Boot 中集成 Redis 作为数据缓存
只添加注解:@Cacheable,不配置key时,redis 中默认存的 key 是:users::SimpleKey [](1.redis-cli 中,通过命令:keys * 查看:2.key:缓存 ...
- MySQL 8.x 函数和操作符,官方网址:https://dev.mysql.com/doc/refman/8.0/en/functions.html
MySql 8.x 函数和操作符,官方网址:https://dev.mysql.com/doc/refman/8.0/en/functions.html
- 数据分析 - Matplotlib
简介 Matplotlib是一个强大的Python绘图和数据可视化的工具包.数据可视化也是我们数据分析的最重要的工作之一,可以帮助我们完成很多操作,例如:找出异常值.必要的一些数据转换等.完成数据分析 ...
- gettid和pthread_self区别
http://blog.csdn.net/rsyp2008/article/details/45150621 1 线程ID获取方法 Linux下获取线程有两种方法: 1)gettid或者类似getti ...
- Struct Socket详细分析(转)
原文地址:http://anders0913.iteye.com/blog/411986 用户使用socket系统调用编写应用程序时,通过一个数字来表示一个socket,所有的操作都在该数字上进行,这 ...