C#将外部窗口嵌入到WPF控件当中
来源:互联网 发布:淘宝保证金别骗怎么办 编辑:程序博客网 时间:2024/05/16 19:49
C#讲外部窗口嵌入到WPF控件当中
本Markdown编辑器使用[StackEdit][6]修改而来,用它写博客,将会带来全新的体验哦:
- 可能会用到的API函数
public class Win32API { #region Win32 API [DllImport("user32.dll", EntryPoint = "GetWindowThreadProcessId", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern long GetWindowThreadProcessId(long hWnd, long lpdwProcessId); [DllImport("user32.dll", SetLastError = true)] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll", SetLastError = true)] public static extern int SetParent(IntPtr hWndChild, IntPtr hWndNewParent); [DllImport("user32.dll", EntryPoint = "GetWindowLongA", SetLastError = true)] public static extern long GetWindowLong(IntPtr hwnd, int nIndex); public static IntPtr SetWindowLong(HandleRef hWnd, int nIndex, int dwNewLong) { if (IntPtr.Size == 4) { return SetWindowLongPtr32(hWnd, nIndex, dwNewLong); } return SetWindowLongPtr64(hWnd, nIndex, dwNewLong); } [DllImport("user32.dll", EntryPoint = "SetWindowLong", CharSet = CharSet.Auto)] public static extern IntPtr SetWindowLongPtr32(HandleRef hWnd, int nIndex, int dwNewLong); [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr", CharSet = CharSet.Auto)] public static extern IntPtr SetWindowLongPtr64(HandleRef hWnd, int nIndex, int dwNewLong); [DllImport("user32.dll", SetLastError = true)] public static extern long SetWindowPos(IntPtr hwnd, long hWndInsertAfter, long x, long y, long cx, long cy, long wFlags); [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", EntryPoint = "PostMessageA", SetLastError = true)] public static extern bool PostMessage(IntPtr hwnd, uint Msg, uint wParam, uint lParam); /// <summary> /// 获取系统错误信息描述 /// </summary> /// <param name="errCode">系统错误码</param> /// <returns></returns> public static string GetLastError() { var errCode = Marshal.GetLastWin32Error(); IntPtr tempptr = IntPtr.Zero; string msg = null; FormatMessage(0x1300, ref tempptr, errCode, 0, ref msg, 255, ref tempptr); return msg; } /// <summary> /// 获取系统错误信息描述 /// </summary> /// <param name="errCode">系统错误码</param> /// <returns></returns> public static string GetLastErrorString(int errCode) { IntPtr tempptr = IntPtr.Zero; string msg = null; FormatMessage(0x1300, ref tempptr, errCode, 0, ref msg, 255, ref tempptr); return msg; } [System.Runtime.InteropServices.DllImport("Kernel32.dll")] public extern static int FormatMessage(int flag, ref IntPtr source, int msgid, int langid, ref string buf, int size, ref IntPtr args); [DllImport("user32.dll", SetLastError = true)] public static extern IntPtr GetParent(IntPtr hwnd); [DllImport("user32.dll", EntryPoint = "ShowWindow", SetLastError = true)] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); public const int SWP_NOOWNERZORDER = 0x200; public const int SWP_NOREDRAW = 0x8; public const int SWP_NOZORDER = 0x4; public const int SWP_SHOWWINDOW = 0x0040; public const int WS_EX_MDICHILD = 0x40; public const int SWP_NOACTIVATE = 0x10; public const int SWP_ASYNCWINDOWPOS = 0x4000; public const int SWP_NOMOVE = 0x2; public const int SWP_NOSIZE = 0x1; public const int WM_CLOSE = 0x10; public const int SW_HIDE = 0; //{隐藏, 并且任务栏也没有最小化图标} public const int SW_SHOWNORMAL = 1; //{用最近的大小和位置显示, 激活} public const int SW_NORMAL = 1; //{同 SW_SHOWNORMAL} public const int SW_SHOWMINIMIZED = 2; //{最小化, 激活} public const int SW_SHOWMAXIMIZED = 3; //{最大化, 激活} public const int SW_MAXIMIZE = 3; //{同 SW_SHOWMAXIMIZED} public const int SW_SHOWNOACTIVATE = 4; //{用最近的大小和位置显示, 不激活} public const int SW_SHOW = 5; //{同 SW_SHOWNORMAL} public const int SW_MINIMIZE = 6; //{最小化, 不激活} public const int SW_SHOWMINNOACTIVE = 7; //{同 SW_MINIMIZE} public const int SW_SHOWNA = 8; //{同 SW_SHOWNOACTIVATE} public const int SW_RESTORE = 9; //{同 SW_SHOWNORMAL} public const int SW_SHOWDEFAULT = 10; //{同 SW_SHOWNORMAL} public const int SW_MAX = 10; //{同 SW_SHOWNORMAL} //const int PROCESS_ALL_ACCESS = 0x1F0FFF; //const int PROCESS_VM_READ = 0x0010; //const int PROCESS_VM_WRITE = 0x0020; internal const int GWL_WNDPROC = (-4), GWL_HINSTANCE = (-6), GWL_HWNDPARENT = (-8), GWL_STYLE = (-16), GWL_EXSTYLE = (-20), GWL_USERDATA = (-21), GWL_ID = (-12); internal const int WS_CHILD = 0x40000000, WS_VISIBLE = 0x10000000, LBS_NOTIFY = 0x00000001, HOST_ID = 0x00000002, LISTBOX_ID = 0x00000001, WS_VSCROLL = 0x00200000, WS_BORDER = 0x00800000; private const int HWND_TOP = 0x0; private const int WM_COMMAND = 0x0112; private const int WM_QT_PAINT = 0xC2DC; private const int WM_PAINT = 0x000F; private const int WM_SIZE = 0x0005; private const int SWP_FRAMECHANGED = 0x0020; #endregion Win32 API }
- 给该窗口添加一个容器
public partial class PluginContainer : ContentControl { public PluginContainer(string appFileName,IntPtr hostHandle) { InitializeComponent(); _appFilename = appFileName; _hostWinHandle = hostHandle; } private void OpenExternProcess(int width,int height) { try{ ProcessStartInfo info = new ProcessStartInfo(_appFilename) ; info.UseShellExecute = true; //info.WindowStyle = ProcessWindowStyle.Minimized; info.WindowStyle = ProcessWindowStyle.Hidden; AppProcess = System.Diagnostics.Process.Start(info); // Wait for process to be created and enter idle condition AppProcess.WaitForInputIdle(); while (AppProcess.MainWindowHandle == IntPtr.Zero){ Thread.Sleep(5); } } catch (Exception ex){ throw ex; } } public bool EmbedProcess(int width, int height) { OpenExternProcess(width, height); try { var pluginWinHandle = AppProcess.MainWindowHandle;//Get the handle of main window. embedResult = Win32API.SetParent(pluginWinHandle, _hostWinHandle);//set parent window Win32API.SetWindowLong(new HandleRef(this, pluginWinHandle), Win32API.GWL_STYLE, Win32API.WS_VISIBLE);//Set window style to "None". var moveResult = Win32API.MoveWindow(pluginWinHandle, 0, 0, width, height, true);//Move window to fixed position(up-left is (0,0), and low-right is (width, height)). //embed failed, and tries again if (!moveResult || embedResult==0){ AppProcess.Kill(); if (MAXCOUNT-->0){ EmbedProcess(width, height); } } else{ Win32API.ShowWindow(pluginWinHandle, (short)Win32API.SW_MAXIMIZE); } } catch (Exception ex) { var errorString = Win32API.GetLastError(); MessageBox.Show(errorString+ex.Message); } return (embedResult != 0); } #region public int embedResult = 0; public Process AppProcess { get; set; } private IntPtr _hostWinHandle { get; set; } private string _appFilename = ""; private int MAXCOUNT=10; #endregion }
- 正式使用
//把句柄传进去,这个mainBorder是在MainWindow中一个Border控件的名字,下面这个获取句柄这个只能在MainWindow.xaml.cs文件中才能获取,我也不知道为什么。在其他的某个xaml.cs中却获取不到这个句柄,这个窗口句柄被当做外部窗口的父窗口了(API中的 SetParent函数来实现的)var hostWinHandle = ((HwndSource)PresentationSource.FromVisual(mainBorder)).Handle;var plugin = new PluginContainer(fileName, hostWinHandle);mainBorder.Content = plugin;plugin.EmbedProcess((int)mainBorder.Width,(int)mainBorder.Height);``
- *此外
获取窗口句柄还可以用API函数FindWindow来实现
IntPtr handle = FindWindow(null,"Window_Name");
0 0
- C#将外部窗口嵌入到WPF控件当中
- c# wpf启动外部exe并嵌入到启动主窗口中运行
- 【已解决】C#将DLL嵌入到exe当中
- C# 将MDI窗口嵌入普通窗口
- 将外部进程嵌入到Qt中
- 将win32窗口嵌入到pyqt5中
- WPF嵌入MFC窗口
- 将MFC dll中的窗口嵌入到工程窗口中
- C#将子窗体嵌入到tabControl控件的tabpage中
- 将.net winform 通过wpf嵌入到浏览器中
- 将外部程序嵌入到Qt界面中
- WPF 将控件绑定到变量
- 将窗口嵌入桌面
- 将窗口嵌入桌面
- C#中 将DataTable内容显示到ListView当中
- HOW TO:将程序窗口嵌入到任务栏中
- 将QT窗口嵌入到MFC中的方案
- 将Flash 嵌入WPF 程序
- 安卓APP之加固技术
- CentOS7 安装 Mysql rpm
- 数字图像处理--掩膜重建
- 解决服务化架构中数据一致性的6种方案
- 找出数组中两个只出现一次的数字
- C#将外部窗口嵌入到WPF控件当中
- 一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。 找出这两个数字,编程实现。
- 菜鸡的从零开始的web笔记---表单
- 思科单臂路由实验个人的理解
- 【C的结构体与C++的不同】 以及 【C++ 的类的和结构体区别】
- 使用ItemDecoration打造列表顶部悬浮效果
- [HDU3949]XOR(高斯消元求线性基)
- 《iOS移动开发从入门到精通》图书连载15:数组
- poj1753