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

时间:2015-03-23 22:18:10

标签: winforms user-interface

我有我的winform应用程序,我希望它的主窗口附加到谷歌浏览器窗口。

  1. 它始终位于镀铬窗口的左侧。宽度为300px,高度始终与镀铬窗口相同。我想我可以通过观看chrome窗口来做到这一点,但我想知道是否有更简单的方法来做到这一点。
  2. 当Chrome最大化时,屏幕的前300px应由我的应用程序占用,然后其余部分显示chrome窗口。好像有一个主窗口包裹我的应用程序的窗口和镀铬窗口

1 个答案:

答案 0 :(得分:1)

似乎WinEvents是最简单的解决方案。 BrendanMcK在这个帖子上的回答是基础:Setting up Hook on Windows messages

MSDN Event Constants

此代码将跟踪打开的记事本窗口。随着记事本窗口的移动/调整大小,Form将保持固定在记事本窗口的右侧。

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();
    }
}
}