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中的更多相关文章

  1. WPF应用程序嵌入第三方exe

    把其它应用嵌入到C#窗口 源代码-CSDN下载 https://download.csdn.net/download/aiqinghee/10652732 WPF应用程序嵌入第三方exe - gao2 ...

  2. C# 把引用的dll嵌入到exe文件中

    当发布的程序有引用其它dll, 又只想发布一个exe时就需要把dll打包到exe 当然有多种方法可以打包, 比如微软的ILMerge,混淆器附带的打包... 用代码打包的实现方式也有很好,本文只是其中 ...

  3. Qt界面中嵌入其他exe程序的界面,使用Qt5

    下面用一个小例子来演示如何在Qt的界面中嵌入其他exe程序的界面,最终效果如下图所示.本文参考了 http://blog.csdn.net/jiaoyaziyang/article/details/4 ...

  4. C#将exe运行程序嵌入到自己的winform窗体中

    以下例子是将Word打开,然后将它嵌入到winform窗体中,效果如下图:C将exe运行程序嵌入到自己的winform窗体中 - kingmax_res - iSport注意:该方法只适用于com的e ...

  5. WPF:将Office文档、任意类型文件嵌入到EXE可执行文件中

    原文:WPF:将Office文档.任意类型文件嵌入到EXE可执行文件中 版权声明:本文为博主原创文章,未经博主允许可以随意转载 https://blog.csdn.net/songqingwei198 ...

  6. WPF程序将DLL嵌入到EXE的两种方法

    WPF程序将DLL嵌入到EXE的两种方法 这一篇可以看作是<Visual Studio 版本转换工具WPF版开源了>的续,关于<Visual Studio 版本转换工具WPF版开源了 ...

  7. WPF编程,获取句柄将外部程序嵌入到WPF界面。

    原文:WPF编程,获取句柄将外部程序嵌入到WPF界面. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/article/details ...

  8. 如何在Exe和BPL插件中实现公共变量共享及窗口溶入技术Demo源码

    如何在Exe和BPL插件中实现公共变量共享及窗口溶入技术Demo源码 1.Delphi编译方式介绍: 当我们在开发一个常规应用程序时,Delphi可以让我们用两种方式使用VCL,一种是把VCL中的申明 ...

  9. Xamarin.Android 嵌入web端界面

    在程序中嵌入Web端界面. 首先在前台界面上创建一个webview <android.webkit.WebView android:layout_width="match_parent ...

随机推荐

  1. Copy Files from Windows 10 to wsl

    Method 1 reboot( close wsl window and reopen ) Method 2 – Windows System Drive as a Mount point Wind ...

  2. React源码 ReactContext

    我们知道在react当中,组件与组件的沟通是通过props,父组件通过props给子组件传递一些属性,父组件可以传递一些回调函数给子组件,让子组件在某些特定的时候,可以调用父组件的一些特性. 但是我们 ...

  3. jmeter从表格批量读取数据(一)

    1.新建一个文本文档,重命名为2.csv 2.可以在文档中设置如下参数:casenum:用例编号:url:访问路径:para:访问的域名:function:请求方式:expectValue:响应值 3 ...

  4. 20180414模拟赛T2——拼图

    拼图 源程序名 puzzling.??? (PAS,BAS,C,CPP) 可执行文件名 puzzling.EXE 输入文件名 puzzling.IN 输出文件名 puzzling.OUT 时间限制 1 ...

  5. 利用反射与dom4j读取javabean生成对应XML

    项目中需要自定义生成一个xml,要把Javabean中的属性拼接一个xml,例如要生成以下xml <?xml version="1.0" encoding="gb2 ...

  6. wordpress站点更换域名了如何快速设置

    有时我们的wordpress站点因为各种原因需要更换域名了,如何快速设置让网站直接用新域名而不受影响呢?比如旧域名是a.com,新域名为b.com,下面这段sql代码很有用 UPDATE wp_opt ...

  7. Markdown插入图表

    链接:https://www.jianshu.com/p/3cf83d22dd3d Markdown图表语法 本文介绍如何用Markdown的mermaid等语法插入时序图.流程图.甘特图 如果是想学 ...

  8. NSData、数据结构与数据转换

    数据结构公式:Data_Structure=(D,R): 只要数据元素与数据(组织关系)能够保持:同一个数据(结构)可以在各种存贮形式间进行转换. 字节流或字符串是所有转化的中间节点(中转站).相当于 ...

  9. 最长公共上升子序列 O(n^2)

    #include <bits/stdc++.h> using namespace std; const int MAXN = 5005; int A[MAXN], B[MAXN], N, ...

  10. 10 Unit Testing and Automation Tools and Libraries Java Programmers Should Learn

    转自:https://javarevisited.blogspot.com/2018/01/10-unit-testing-and-integration-tools-for-java-program ...