winform:将我的 window 附加到另一个应用程序

winform: attach my window to another app

我有我的 winform 应用程序,我希望它的主要 window 附加到 google chrome window。

  1. 它总是在 chrome window 的左侧。宽度为 300px,高度始终与 chrome window 相同。我想我可以通过观看 chrome window 来做到这一点,但我想知道是否有更简单的方法来做到这一点。
  2. 当chrome最大化时,屏幕的前300px应该被我的应用程序占用,然后其余显示chrome window。就好像有主要 window 包装我的应用程序的 window 和 chrome window

WinEvents 似乎是最简单的解决方案。 BrendanMcK 在此线程上的回答作为基础:Setting up Hook on Windows messages

MSDN Event Constants

此代码将跟踪打开的记事本 window。由于记事本 window 是 moved/resized,因此 Form 将固定在记事本 window.

的右侧
using System;
using System.Linq;
using System.Windows;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Text;

namespace WindowTracker {

public class WindowTracker {

    delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime);

    [DllImport("user32.dll")]
    static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr hmodWinEventProc, WinEventDelegate lpfnWinEventProc, uint idProcess, uint idThread, uint dwFlags);

    [DllImport("user32.dll")]
    static extern bool UnhookWinEvent(IntPtr hWinEventHook);

    [DllImport("user32.dll")]
    static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

    const uint EVENT_OBJECT_LOCATIONCHANGE = 0x800B;
    const uint WINEVENT_OUTOFCONTEXT = 0;

    static WinEventDelegate procDelegate = new WinEventDelegate(WinEventProc);
    private static IntPtr hhook;
    private static Form f = null;
    static Process p = null;

    public static void HookNotepad(Form f) {
        WindowTracker.f = f;
        p = Process.GetProcessesByName("Notepad").FirstOrDefault();
        if (p == null)
            throw new Exception("Notepad is not running.");

        f.Show(new SimpleWindow(p.MainWindowHandle));

        hhook = SetWinEventHook(EVENT_OBJECT_LOCATIONCHANGE, EVENT_OBJECT_LOCATIONCHANGE, IntPtr.Zero, procDelegate, (uint) p.Id, 0, WINEVENT_OUTOFCONTEXT);
    }

    private class SimpleWindow : System.Windows.Forms.IWin32Window {
        IntPtr h = IntPtr.Zero;
        public SimpleWindow(IntPtr ptr) {
            h = ptr;
        }
        public IntPtr Handle {
            get { return h; }
        }
    }

    public static void UnhookNotepad() {
        UnhookWinEvent(hhook);
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct RECT {
        public int Left;
        public int Top;
        public int Right;
        public int Bottom;
    }

    static void WinEventProc(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime) {
        if (idObject != 0 || idChild != 0)
            return;

        RECT r = new RECT();
        GetWindowRect(p.MainWindowHandle, out r);
        int h = r.Bottom - r.Top;
        int x = r.Right - f.Width;
        int y = r.Top + ((h - f.Height) / 2);
        f.Location = new System.Drawing.Point(x, y);
    }

    [STAThread]
    static void Main() {
        Form f = new Form();
        WindowTracker.HookNotepad(f);

        System.Windows.Forms.Application.Run(f);
        WindowTracker.UnhookNotepad();
    }
}
}