0

I have my winform app where I want its main window to be attached to google chrome window.

  1. It would always be on the left side of chrome window. The width is 300px, height is always the same as chrome window. I think I can do this by watching chrome window but I am wondering if there is easier way to do this.
  2. When chrome is maximized, the first 300px of the screen should be occupied by my app and then the rest display chrome window. It is as if there is main window wrapping my app's window and chrome window
user21479
  • 1,179
  • 2
  • 13
  • 21

1 Answers1

1

Seems like WinEvents is the easiest solution. BrendanMcK's answer on this thread served as the basis: Setting up Hook on Windows messages

MSDN Event Constants

This code will track an open Notepad window. As the Notepad window is moved/resized, the Form will stay pinned to the right side of the Notepad 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();
    }
}
}
Community
  • 1
  • 1
Loathing
  • 5,109
  • 3
  • 24
  • 35