将 WPF 窗口附加到另一个进程的窗口

2024-04-02

我想编写一个 WPF 应用程序,该应用程序停靠到在另一个进程中运行的应用程序(这是我无法控制的第 3 方应用程序)。理想情况下,我希望能够定义应用程序是停靠在左侧还是右侧。

这是我想做的一个例子:

我尝试实现以下 2 个示例,但没有成功。

将窗口附加到另一个进程的窗口 https://stackoverflow.com/questions/10676649/attach-window-to-window-of-another-process- Button_Click 出现以下错误:

在 C# 中将窗体窗口附加到另一个窗口 https://stackoverflow.com/questions/10773003/attach-form-window-to-another-window-in-c-sharp- Button_Click_1 将其停靠在标题栏上,但我看不到整个应用程序:

以下是代码:

namespace WpfApplicationTest
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    [DllImport("user32.dll")]
    public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

    [DllImport("user32.dll")]
    public static extern int GetWindowLong(IntPtr hWnd, int nIndex);

    [DllImport("user32.dll", SetLastError = true)]
    private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

    public static int GWL_STYLE = -16;
    public static int WS_CHILD = 0x40000000;

    [DllImport("user32")]
    private static extern bool SetWindowPos(
        IntPtr hWnd,
        IntPtr hWndInsertAfter,
        int x,
        int y,
        int cx,
        int cy,
        uint uFlags);

    private IntPtr _handle;
    private void SetBounds(int left, int top, int width, int height)
    {
        if (_handle == IntPtr.Zero)
            _handle = new WindowInteropHelper(this).Handle;

        SetWindowPos(_handle, IntPtr.Zero, left, top, width, height, 0);
    }

    public MainWindow()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Process hostProcess = Process.GetProcessesByName("notepad").FirstOrDefault();
        IntPtr hostHandle = hostProcess.MainWindowHandle;

        //MyWindow window = new MyWindow();
        this.ShowActivated = true;

        HwndSourceParameters parameters = new HwndSourceParameters();

        parameters.WindowStyle = 0x10000000 | 0x40000000;
        parameters.SetPosition(0, 0);
        parameters.SetSize((int)this.Width, (int)this.Height);
        parameters.ParentWindow = hostHandle;
        parameters.UsesPerPixelOpacity = true;
        HwndSource src = new HwndSource(parameters);

        src.CompositionTarget.BackgroundColor = Colors.Transparent;
        src.RootVisual = (Visual)this.Content;
    }

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        Process hostProcess = Process.GetProcessesByName("notepad").FirstOrDefault();
        if (hostProcess != null)
        {
            Hide();

            //this.WindowStyle;

            //new WindowInteropHelper(this).SetBounds(0, 0, 0, 0, BoundsSpecified.Location);

            //SetWindowPos(new WindowInteropHelper(this).Handle, IntPtr.Zero, 0, 0, 0, 0, 0);
            SetBounds(0, 0, 0, 0);

            IntPtr hostHandle = hostProcess.MainWindowHandle;
            IntPtr guestHandle = new WindowInteropHelper(this).Handle;

            SetWindowLong(guestHandle, GWL_STYLE, GetWindowLong(guestHandle, GWL_STYLE) | WS_CHILD);
            SetParent(guestHandle, hostHandle);

            Show();
        }
    }
}

您的实现是完全错误的,您试图将窗口作为要捕捉的窗口的子窗口。

我编写了一个小帮助程序类,用于通过标题捕捉到另一个窗口,我希望这会有所帮助。

WindowSnapper.cs

public class WindowSnapper
{
    private struct Rect
    {
        public int Left { get; set; }
        public int Top { get; set; }
        public int Right { get; set; }
        public int Bottom { get; set; }

        public int Height
        {
            get { return Bottom - Top; }
        }

        public static bool operator !=(Rect r1, Rect r2)
        {
            return !(r1 == r2);
        }

        public static bool operator ==(Rect r1, Rect r2)
        {
            return r1.Left == r2.Left && r1.Right == r2.Right && r1.Top == r2.Top && r1.Bottom == r2.Bottom;
        }
    }

    [DllImport("user32.dll")]
    private static extern bool GetWindowRect(IntPtr hwnd, ref Rect rectangle);

    private DispatcherTimer _timer;
    private IntPtr _windowHandle;
    private Rect _lastBounds;
    private Window _window;
    private string _windowTitle;

    public WindowSnapper(Window window, String windowTitle)
    {
        _window = window;
        _window.Topmost = true;
        _windowTitle = windowTitle;

        _timer = new DispatcherTimer();
        _timer.Interval = TimeSpan.FromMilliseconds(10);
        _timer.Tick += (x, y) => SnapToWindow();
        _timer.IsEnabled = false;
    }

    public void Attach()
    {
        _windowHandle = GetWindowHandle(_windowTitle);
        _timer.Start();
    }

    public void Detach()
    {
        _timer.Stop();
    }

    private void SnapToWindow()
    {
        var bounds = GetWindowBounds(_windowHandle);

        if (bounds != _lastBounds)
        {
            _window.Top = bounds.Top;
            _window.Left = bounds.Left - _window.Width;
            _window.Height = bounds.Height;
            _lastBounds = bounds;
        }
    }

    private Rect GetWindowBounds(IntPtr handle)
    {
        Rect bounds = new Rect();
        GetWindowRect(handle, ref bounds);
        return bounds;
    }

    private IntPtr GetWindowHandle(string windowTitle)
    {
        foreach (Process pList in Process.GetProcesses())
        {
            if (pList.MainWindowTitle.Contains(windowTitle))
            {
                return pList.MainWindowHandle;
            }
        }

        return IntPtr.Zero;
    }
}

使用示例:

public partial class MainWindow : Window
{
    private WindowSnapper _snapper;

    public MainWindow()
    {
        InitializeComponent();

        _snapper = new WindowSnapper(this, "Notepad");
        _snapper.Attach();
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 WPF 窗口附加到另一个进程的窗口 的相关文章

  • 按成员序列化

    我已经实现了template
  • 在哪里可以找到列出 SSE 内在函数操作的官方参考资料?

    是否有官方参考列出了 GCC 的 SSE 内部函数的操作 即 头文件中的函数 除了 Intel 的 vol 2 PDF 手册外 还有一个在线内在指南 https www intel com content www us en docs in
  • ASP.NET MVC:这个业务逻辑应该放在哪里?

    我正在开发我的第一个真正的 MVC 应用程序 并尝试遵循一般的 OOP 最佳实践 我正在将控制器中的一些简单业务逻辑重构到我的域模型中 我最近一直在阅读一些内容 很明显我应该将逻辑放在域模型实体类中的某个位置 以避免出现 贫血域模型 反模式
  • 查找c中结构元素的偏移量

    struct a struct b int i float j x struct c int k float l y z 谁能解释一下如何找到偏移量int k这样我们就可以找到地址int i Use offsetof 找到从开始处的偏移量z
  • 嵌套接口:将 IDictionary> 转换为 IDictionary>?

    我认为投射一个相当简单IDictionary
  • 类模板参数推导 - clang 和 gcc 不同

    下面的代码使用 gcc 编译 但不使用 clang 编译 https godbolt org z ttqGuL template
  • 如何使用 ICU 解析汉字数字字符?

    我正在编写一个使用 ICU 来解析由汉字数字字符组成的 Unicode 字符串的函数 并希望返回该字符串的整数值 五 gt 5 三十一 gt 31 五千九百七十二 gt 5972 我将区域设置设置为 Locale getJapan 并使用
  • 如何从 appsettings.json 文件中的对象数组读取值

    我的 appsettings json 文件 StudentBirthdays Anne 01 11 2000 Peter 29 07 2001 Jane 15 10 2001 John Not Mentioned 我有一个单独的配置类 p
  • while 循环中的 scanf

    在这段代码中 scanf只工作一次 我究竟做错了什么 include
  • SolrNet连接说明

    为什么 SolrNet 连接的容器保持静态 这是一个非常大的错误 因为当我们在应用程序中向应用程序发送异步请求时 SolrNet 会表现异常 在 SolrNet 中如何避免这个问题 class P static void M string
  • 转发声明和包含

    在使用库时 无论是我自己的还是外部的 都有很多带有前向声明的类 根据情况 相同的类也包含在内 当我使用某个类时 我需要知道该类使用的某些对象是前向声明的还是 include d 原因是我想知道是否应该包含两个标题还是只包含一个标题 现在我知
  • 控件的命名约定[重复]

    这个问题在这里已经有答案了 Microsoft 在其网站上提供了命名指南 here http msdn microsoft com en us library xzf533w0 VS 71 aspx 我还有 框架设计指南 一书 我找不到有关
  • 如何序列化/反序列化自定义数据集

    我有一个 winforms 应用程序 它使用强类型的自定义数据集来保存数据进行处理 它由数据库中的数据填充 我有一个用户控件 它接受任何自定义数据集并在数据网格中显示内容 这用于测试和调试 为了使控件可重用 我将自定义数据集视为普通的 Sy
  • 如何使用 C# / .Net 将文件列表从 AWS S3 下载到我的设备?

    我希望下载存储在 S3 中的多个图像 但目前如果我只能下载一个就足够了 我有对象路径的信息 当我运行以下代码时 出现此错误 遇到错误 消息 读取对象时 访问被拒绝 我首先做一个亚马逊S3客户端基于我的密钥和访问配置的对象连接到服务器 然后创
  • 向现有 TCP 和 UDP 代码添加 SSL 支持?

    这是我的问题 现在我有一个 Linux 服务器应用程序 使用 C gcc 编写 它与 Windows C 客户端应用程序 Visual Studio 9 Qt 4 5 进行通信 是什么very在不完全破坏现有协议的情况下向双方添加 SSL
  • 将控制台重定向到 .NET 程序中的字符串

    如何重定向写入控制台的任何内容以写入字符串 对于您自己的流程 Console SetOut http msdn microsoft com en us library system console setout aspx并将其重定向到构建在
  • 混合 ExecutionContext.SuppressFlow 和任务时 AsyncLocal.Value 出现意外值

    在应用程序中 由于 AsyncLocal 的错误 意外值 我遇到了奇怪的行为 尽管我抑制了执行上下文的流程 但 AsyncLocal Value 属性有时不会在新生成的任务的执行范围内重置 下面我创建了一个最小的可重现示例来演示该问题 pr
  • 是否可以在 .NET Core 中将 gRPC 与 HTTP/1.1 结合使用?

    我有两个网络服务 gRPC 客户端和 gRPC 服务器 服务器是用 NET Core编写的 然而 客户端是托管在 IIS 8 5 上的 NET Framework 4 7 2 Web 应用程序 所以它只支持HTTP 1 1 https le
  • C# 模拟VolumeMute按下

    我得到以下代码来模拟音量静音按键 DllImport coredll dll SetLastError true static extern void keybd event byte bVk byte bScan int dwFlags
  • 如何将服务器服务连接到 Dynamics Online

    我正在修改内部管理应用程序以连接到我们的在线托管 Dynamics 2016 实例 根据一些在线教程 我一直在使用OrganizationServiceProxy out of Microsoft Xrm Sdk Client来自 SDK

随机推荐

  • xaml 中的 WPF ObservableCollection

    我在用户控件的代码后面创建了一个 ObservableCollection 它是在窗口加载时创建的 private void UserControl Loaded object sender RoutedEventArgs e Entiti
  • 找不到列“dbo”或用户定义函数或聚合“dbo.Splitfn”,或者名称不明确

    我使用了以下分割函数 CREATE FUNCTION dbo Splitfn String varchar 8000 Delimiter char 1 returns temptable TABLE items varchar 8000 a
  • 加密 web.config 失败错误

    我知道有人已经问过有关加密 web config 的问题 我还尝试加密我的测试配置文件 但我收到此错误 aspnet regiis pef connectionStrings C encryptedWeb config 正在加密配置部分 无
  • 从 Javascript 方法返回全局变量 [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我有一个方法 function ca
  • 在 PySpark 中读取 Lzo 文件

    我是 Spark 新手 我的文件夹中有一堆 LZO 索引文件 索引已完成 如上所示https github com twitter hadoop lzo https github com twitter hadoop lzo 文件如下 1
  • 如何检查所有列表项是否具有相同的值并返回它,或者如果没有则返回另一个值?

    如果列表中的所有项目都具有相同的值 那么我需要使用该值 否则我需要使用 otherValue 我想不出一个简单明了的方法来做到这一点 当列表为空时 它应该返回 其他 值 也可以看看编写对集合中的第一项具有特殊逻辑的循环的巧妙方法 https
  • JQGRID , 获取过滤后的所有行

    过滤 JQgrid 后 我无法获取所有行 分页 我试过 gt var myData grid jqGrid getGridParam data var myData grid jqGrid getRowData 但第一个选项给出了所有行 并
  • 崩溃时退出代码

    我想通过 shell 脚本知道应用程序是否崩溃 如果应用程序崩溃 退出代码是什么 应用程序的退出代码将位于 shell 变量中 如果您的应用程序崩溃 即操作系统认为它做了坏事 并导致它终止 向其发送信号 那么这会反映在退出状态中 这是我使用
  • 在 Excel VBA 中使用 COM 插件中的 CLR 类吗?

    我有一个 Excel VSTO COM 插件 我可以成功加载 Excel VBA 中的引用 我可以交换基本类型 如字符串 但我也可以在 VBA 中使用我的外接程序中的复杂类吗 假设我有 C 类 public class TestClass
  • 在 ggplot2 中使用 geom_point 有条件地使用抖动

    I have a graph with 12 variables divided into two groups I can t use facets but using colour and shape I have been able
  • 连接或级联多个预训练的 keras 模型

    我正在尝试构建一组串联或级联 实际上甚至不知道这是否是正确的定义 的模型 为了简单起见 我的基本模型如下所示 Input L1 1 L1 2 Dense
  • 通过 Javascript 解析 JSON 对象(对象列表)并在其中循环?

    好吧 我知道出了点问题 但我不明白是什么 我从我编写的 Web 服务中读取了 Service 的 ArrayList 采用 JSON 媒体类型 访问该地址会返回 json 字符串 现在我正在尝试制作一个网页来显示该值并查看每 3 秒请求一次
  • 状态栏和底部应用栏遮挡 WP 8.1

    我使用以下代码使状态栏显示在内容顶部 并设置背景不透明度 0 var applicationView Windows UI ViewManagement ApplicationView GetForCurrentView applicati
  • jQuery PickMeUp datepicker:禁用日期数组

    我正在使用一个名为的 jQuery 日期选择器插件PickMeUp https github com nazar pc PickMeUp 我的日期选择器可以工作 但无法弄清楚如何禁用其中的日期 我的计划是在日期选择器日历上禁用一系列日期 我
  • Exchange ItemID 与 Outlook 加载项的 GlobalAppointmentID 不同

    我遇到的问题是 使用 Outlook FormRegion 创建的 Outlook 约会的 GlobalAppointmentID 与使用 EWS 托管 API 时的 ItemID 不同 我正在创建一个 Outlook 插件 允许用户将客户
  • 1.7 中 javax.sql.CommonDataSource 添加了新方法

    尝试针对 java 1 7 编译我的应用程序 我发现 javax sql CommonDataSource 以及 j s DataSource 中 添加了一个新方法 getParentLogger 你可以比较一下通用数据源 1 7 http
  • 如何将 Guava ServiceManager 与 Guice 注入结合使用

    如上所述here https plus google com 118010414872916542489 posts 86dUfeQk5dH Guava ServiceManager 可以通过以下方式获取 ServiceManager ma
  • 检查 keyDown event.modifierFlags 会产生错误

    我继承 NSTextView 并覆盖 keyDown 我想检测命令键组合 例如 Command L 苹果的文档 https developer apple com library mac documentation Cocoa Concep
  • 酶测试嵌套组件的方法

    我正在尝试使用 Enzyme 来测试组件的方法 我知道执行此操作的典型方法是使用酶instance method 问题是 这只适用于root组件和我的组件需要包装在两个上下文提供程序中才能渲染 即react router和apollo客户端
  • 将 WPF 窗口附加到另一个进程的窗口

    我想编写一个 WPF 应用程序 该应用程序停靠到在另一个进程中运行的应用程序 这是我无法控制的第 3 方应用程序 理想情况下 我希望能够定义应用程序是停靠在左侧还是右侧 这是我想做的一个例子 我尝试实现以下 2 个示例 但没有成功 将窗口附