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. 【Git】Git如何合并某一次commit的内容到指定分支

    一.我是在什么场景下会用到该Git操作 当某同事,将开发分支dev2合并到开发分支dev1时(两个不同的功能,不能合并),其他同事不知情的情况下,继续在dev1上开发并提交了代码. 后面发现了该合并, ...

  2. linux设备驱动程序--bus

    linux 中bus驱动解析 总线(bus)是linux发展过程中抽象出来的一种设备模型,为了统一管理所有的设备,内核中每个设备都会被挂载在总线上,这个bus可以是对应硬件的bus(i2c bus.s ...

  3. 《团队名称》第八次团队作业:Alpha冲刺day4

    项目 内容 这个作业属于哪个课程 2016计算机科学与工程学院软件工程(西北师范大学) 这个作业的要求在哪里 实验十二 团队作业8-软件测试与ALPHA冲刺 团队名称 快活帮 作业学习目标 (1)掌握 ...

  4. SHOI2017 分手是祝愿

    分手是祝愿 有

  5. Convert PadLeft Bit Operate

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Cons ...

  6. vscode代码折叠方法

    最近换用了vscode代码编辑器,在查看c源码的时候想折叠所有区域的代码,不知道快捷键是哪一个?查看了使用说明,快捷键如下: 1. 折叠所有区域代码的快捷: ctrl + k      ctrl + ...

  7. excel双击下拉制作(以及双击下拉字符超限处理)

    最近,在项目的开发过程中,遇到了一个问题,自己要修改代码中的excel模板,有些列要处理成双击下拉的形式. excel制作双击下拉: 当然,我想,这对于大家来说是不难的,好实现,但是,我在制作的过程中 ...

  8. gettid和pthread_self区别

    http://blog.csdn.net/rsyp2008/article/details/45150621 1 线程ID获取方法 Linux下获取线程有两种方法: 1)gettid或者类似getti ...

  9. linux查看反汇编

    生成反汇编文件 gcc xxx.c -g -o a.out objdump a.out -dSsx > file 调试的时候查看反汇编: gdb a.out ...layout asm 参考博文 ...

  10. 前端零基础入门:页面结构层HTML

    HTML页面结构层HTML 分以下方面学习: HTML基础, HTML表格, HTML表单, 搭建网页结构 html基础 学习前端的第一门课程,为HTML基础,HTML标记语言,它是网页制作的第一步. ...