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 ...
随机推荐
- 【解决】挂载NFS服务时,不同共享客户端间的数据不同步
问题现象 当您用台 ECS 挂载同一个 NFS 文件系统,在 ECS-A 上 append 写文件,在 ECS-B 用 tail -f 观察文件内容的变化.在 ECS-A 写完之后,在 ECS-B 看 ...
- Xshell 配置密钥
- Discuz! 3.3全站帖子自动添加图片alt标签
网站想要更好的适应搜索引擎的话,就要把最基础的一些小优化标签做好, 虽然说现在搜索都很厉害能够识别图片,但是除非的你的图片每一张都是周杰伦.范冰冰等知名图片... 不然你还是要给你自己的图添加alt标 ...
- VisualVM的插件中心已经迁移至GitHub
VisualVM是一款免费的集成了多个JDK命令行工具的可视化性能分析工具,而且目前已经被JDK包含了,取名为:jvisualvm .如果你是一名Javaer,强烈建议你能够使用它,因为它不仅能生成和 ...
- 安装GO
1.中文社区 下载地址 https://studygolang.com/dl 选择自己操作系统版本 2.找到适合你系统的版本下载,本人下载的是windows版本.也可以下载Source自己更 ...
- 接口调试工具Postman之自动同步Chrome cookies,实现自动登陆验证
前言 在前后端分离开发时,做为后端开发人员,要求独立开发完成某个接口后,开发人员自己需要先测试通过后再提交给测试人员进行测试,否则会出现到测试人员哪里业务流程根本就走不通,或者BUG会过多的情况等. ...
- 关于System.TypeInitializationException异常
什么是System.TypeInitializationException 作为类初始值设定项引发的异常的包装器而引发的异常. 继承 Object Exception SystemException ...
- JS对象创建模式
JS的对象创建模式 1.Object构造函数模式 var person = new Object(); person.name = 'name'; person.age = 43; console.l ...
- BZOJ 4816[SDOI2017]数字表格(莫比乌斯反演)
题目链接 \(Description\) 用\(f_i\)表示\(fibonacci\)数列第\(i\)项,求\(\prod_{i=1}^{n}\prod_{j=1}^{m}f[gcd(i,j)]\) ...
- FDQuery Out of memory
4万行记录 FDQuery查询 Out of memory sql server 可以查询成功 First chance exception at $7505D722. Exception class ...