winform:将我的 window 附加到另一个应用程序
winform: attach my window to another app
我有我的 winform 应用程序,我希望它的主要 window 附加到 google chrome window。
- 它总是在 chrome window 的左侧。宽度为 300px,高度始终与 chrome window 相同。我想我可以通过观看 chrome window 来做到这一点,但我想知道是否有更简单的方法来做到这一点。
- 当chrome最大化时,屏幕的前300px应该被我的应用程序占用,然后其余显示chrome window。就好像有主要 window 包装我的应用程序的 window 和 chrome window
WinEvents 似乎是最简单的解决方案。 BrendanMcK 在此线程上的回答作为基础:Setting up Hook on Windows messages
此代码将跟踪打开的记事本 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();
}
}
}
我有我的 winform 应用程序,我希望它的主要 window 附加到 google chrome window。
- 它总是在 chrome window 的左侧。宽度为 300px,高度始终与 chrome window 相同。我想我可以通过观看 chrome window 来做到这一点,但我想知道是否有更简单的方法来做到这一点。
- 当chrome最大化时,屏幕的前300px应该被我的应用程序占用,然后其余显示chrome window。就好像有主要 window 包装我的应用程序的 window 和 chrome window
WinEvents 似乎是最简单的解决方案。 BrendanMcK 在此线程上的回答作为基础:Setting up Hook on Windows messages
此代码将跟踪打开的记事本 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();
}
}
}