mirror of
https://github.com/LorenzCK/OnTopReplica.git
synced 2024-05-20 20:33:06 +12:00
127 lines
5.2 KiB
C#
127 lines
5.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using OnTopReplica.Native;
|
|
using System.Drawing;
|
|
using System.Windows.Forms;
|
|
|
|
namespace OnTopReplica {
|
|
public static class Win32Helper {
|
|
|
|
#region Injection
|
|
|
|
/// <summary>Inject a fake left mouse click on a target window, on a location expressed in client coordinates.</summary>
|
|
/// <param name="window">Target window to click on.</param>
|
|
/// <param name="clickLocation">Location of the mouse click expressed in client coordiantes of the target window.</param>
|
|
/// <param name="doubleClick">True if a double click should be injected.</param>
|
|
public static void InjectFakeMouseClick(IntPtr window, CloneClickEventArgs clickArgs) {
|
|
NPoint clientClickLocation = NPoint.FromPoint(clickArgs.ClientClickLocation);
|
|
NPoint scrClickLocation = WindowManagerMethods.ClientToScreen(window, clientClickLocation);
|
|
|
|
//HACK (?)
|
|
//If target window has a Menu (which appears on the thumbnail) move the clicked location down
|
|
//in order to adjust (the menu isn't part of the window's client rect).
|
|
IntPtr hMenu = WindowMethods.GetMenu(window);
|
|
if (hMenu != IntPtr.Zero)
|
|
scrClickLocation.Y -= SystemInformation.MenuHeight;
|
|
|
|
IntPtr hChild = GetRealChildControlFromPoint(window, scrClickLocation);
|
|
NPoint clntClickLocation = WindowManagerMethods.ScreenToClient(hChild, scrClickLocation);
|
|
|
|
if (clickArgs.Buttons == MouseButtons.Left) {
|
|
if(clickArgs.IsDoubleClick)
|
|
InjectDoubleLeftMouseClick(hChild, clntClickLocation);
|
|
else
|
|
InjectLeftMouseClick(hChild, clntClickLocation);
|
|
}
|
|
else if (clickArgs.Buttons == MouseButtons.Right) {
|
|
if(clickArgs.IsDoubleClick)
|
|
InjectDoubleRightMouseClick(hChild, clntClickLocation);
|
|
else
|
|
InjectRightMouseClick(hChild, clntClickLocation);
|
|
}
|
|
}
|
|
|
|
private static void InjectLeftMouseClick(IntPtr child, NPoint clientLocation) {
|
|
IntPtr lParamClickLocation = MessagingMethods.MakeLParam(clientLocation.X, clientLocation.Y);
|
|
|
|
MessagingMethods.PostMessage(child, WM.LBUTTONDOWN, new IntPtr(MK.LBUTTON), lParamClickLocation);
|
|
MessagingMethods.PostMessage(child, WM.LBUTTONUP, new IntPtr(MK.LBUTTON), lParamClickLocation);
|
|
|
|
#if DEBUG
|
|
System.Diagnostics.Debug.WriteLine("Left click on window #" + child.ToString() + " at " + clientLocation.ToString());
|
|
#endif
|
|
}
|
|
|
|
private static void InjectRightMouseClick(IntPtr child, NPoint clientLocation) {
|
|
IntPtr lParamClickLocation = MessagingMethods.MakeLParam(clientLocation.X, clientLocation.Y);
|
|
|
|
MessagingMethods.PostMessage(child, WM.RBUTTONDOWN, new IntPtr(MK.RBUTTON), lParamClickLocation);
|
|
MessagingMethods.PostMessage(child, WM.RBUTTONUP, new IntPtr(MK.RBUTTON), lParamClickLocation);
|
|
|
|
#if DEBUG
|
|
System.Diagnostics.Debug.WriteLine("Right click on window #" + child.ToString() + " at " + clientLocation.ToString());
|
|
#endif
|
|
}
|
|
|
|
private static void InjectDoubleLeftMouseClick(IntPtr child, NPoint clientLocation) {
|
|
IntPtr lParamClickLocation = MessagingMethods.MakeLParam(clientLocation.X, clientLocation.Y);
|
|
|
|
MessagingMethods.PostMessage(child, WM.LBUTTONDBLCLK, new IntPtr(MK.LBUTTON), lParamClickLocation);
|
|
|
|
#if DEBUG
|
|
System.Diagnostics.Debug.WriteLine("Double left click on window #" + child.ToString() + " at " + clientLocation.ToString());
|
|
#endif
|
|
}
|
|
|
|
private static void InjectDoubleRightMouseClick(IntPtr child, NPoint clientLocation) {
|
|
IntPtr lParamClickLocation = MessagingMethods.MakeLParam(clientLocation.X, clientLocation.Y);
|
|
|
|
MessagingMethods.PostMessage(child, WM.RBUTTONDBLCLK, new IntPtr(MK.RBUTTON), lParamClickLocation);
|
|
|
|
#if DEBUG
|
|
System.Diagnostics.Debug.WriteLine("Double right click on window #" + child.ToString() + " at " + clientLocation.ToString());
|
|
#endif
|
|
}
|
|
|
|
#endregion
|
|
|
|
/// <summary>Returns the child control of a window corresponding to a screen location.</summary>
|
|
/// <param name="parent">Parent window to explore.</param>
|
|
/// <param name="scrClickLocation">Child control location in screen coordinates.</param>
|
|
private static IntPtr GetRealChildControlFromPoint(IntPtr parent, NPoint scrClickLocation) {
|
|
IntPtr curr = parent, child = IntPtr.Zero;
|
|
do {
|
|
child = WindowManagerMethods.RealChildWindowFromPoint(curr,
|
|
WindowManagerMethods.ScreenToClient(curr, scrClickLocation));
|
|
|
|
if (child == IntPtr.Zero || child == curr)
|
|
break;
|
|
|
|
//Update for next loop
|
|
curr = child;
|
|
}
|
|
while (true);
|
|
|
|
//Safety check, shouldn't happen
|
|
if (curr == IntPtr.Zero)
|
|
curr = parent;
|
|
|
|
return curr;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a handle to the window that currently is in the foreground.
|
|
/// </summary>
|
|
/// <returns>May return null if call fails or no valid window selected.</returns>
|
|
public static WindowHandle GetCurrentForegroundWindow() {
|
|
IntPtr handle = WindowManagerMethods.GetForegroundWindow();
|
|
if (handle == IntPtr.Zero)
|
|
return null;
|
|
|
|
return new WindowHandle(handle);
|
|
}
|
|
|
|
}
|
|
}
|