OnTopReplica/OnTopReplica/Win32Helper.cs
Lorenz Cuno Klopfenstein 6dfa6615d3 Added ThumbnailRegion class to support relative regions.
Refactored XML serialization for stored regions.
Refactored several thumbnail cloning (and region) methods.
Removed PluginRegionLocator.
Moved to System.Diagnostics.Trace for debug messaging.
2012-11-14 14:50:22 +01:00

127 lines
5.4 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);
}
}
}