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

c# – 将WPF窗口附加到另一个进程的窗口,第1张

概述我想写一个 WPF应用程序,它停靠在另一个进程中运行的应用程序(这是我无法控制的第三方应用程序).理想情况下,我希望能够定义应用程序是在左侧还是右侧停靠. 这是我想要做的一个例子: 我试图实现以下两个例子但没有成功. Attach window to window of another process – Button_Click给出以下错误: Attach form window to anot 我想写一个 WPF应用程序,它停靠在另一个进程中运行的应用程序(这是我无法控制的第三方应用程序).理想情况下,我希望能够定义应用程序是在左侧还是右侧停靠.

这是我想要做的一个例子:

我试图实现以下两个例子但没有成功.

Attach window to window of another process – button_Click给出以下错误:

Attach form window to another window in C# – 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,BoundsspecifIEd.Location);            //SetwindowPos(new WindowInteropHelper(this).Handle,0);            SetBounds(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();    }}
总结

以上是内存溢出为你收集整理的c# – 将WPF窗口附加到另一个进程的窗口全部内容,希望文章能够帮你解决c# – 将WPF窗口附加到另一个进程的窗口所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1226538.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存