c# – 将WPF窗口附加到另一个进程的窗口
发布时间:2020-12-15 20:55:43 所属栏目:百科 来源:网络整理
导读:我想写一个 WPF应用程序,它停靠在另一个进程中运行的应用程序(这是我无法控制的第三方应用程序).理想情况下,我希望能够定义应用程序是在左侧还是右侧停靠. 这是我想要做的一个例子: 我试图实现以下两个例子但没有成功. Attach window to window of another
我想写一个
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(); } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |