Added right click forwarding.

This commit is contained in:
Lorenz Cuno Klopfenstein 2010-07-01 13:46:01 +02:00
parent 94610f3bc5
commit 0f28a47328
3 changed files with 47 additions and 17 deletions

View file

@ -118,8 +118,7 @@ namespace OnTopReplica {
}
void Thumbnail_CloneClick(object sender, CloneClickEventArgs e) {
//TODO: handle other mouse buttons
Win32Helper.InjectFakeMouseClick(_lastWindowHandle.Handle, e.ClientClickLocation, e.IsDoubleClick);
Win32Helper.InjectFakeMouseClick(_lastWindowHandle.Handle, e);
}
}

View file

@ -14,6 +14,9 @@ namespace OnTopReplica.Native {
public const int LBUTTONDOWN = 0x0201;
public const int LBUTTONUP = 0x0202;
public const int LBUTTONDBLCLK = 0x0203;
public const int RBUTTONDOWN = 0x0204;
public const int RBUTTONUP = 0x0205;
public const int RBUTTONDBLCLK = 0x0206;
public const int NCLBUTTONUP = 0x00A2;
public const int NCLBUTTONDOWN = 0x00A1;
public const int NCLBUTTONDBLCLK = 0x00A3;

View file

@ -2,6 +2,8 @@
using System.Collections.Generic;
using System.Text;
using OnTopReplica.Native;
using System.Drawing;
using System.Windows.Forms;
namespace OnTopReplica {
public static class Win32Helper {
@ -10,50 +12,76 @@ namespace OnTopReplica {
/// <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, System.Drawing.Point clickLocation, bool doubleClick) {
NPoint scrClickLocation = WindowManagerMethods.ClientToScreen(window, NPoint.FromPoint(clickLocation));
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 -= System.Windows.Forms.SystemInformation.MenuHeight;
scrClickLocation.Y -= SystemInformation.MenuHeight;
IntPtr hChild = GetRealChildControlFromPoint(window, scrClickLocation);
NPoint clntClickLocation = WindowManagerMethods.ScreenToClient(hChild, scrClickLocation);
if (doubleClick)
InjectDoubleLeftMouseClick(hChild, clntClickLocation);
else
InjectLeftMouseClick(hChild, clntClickLocation);
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, Native.NPoint clientLocation) {
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);
MessagingMethods.PostMessage(child, WM.LBUTTONDOWN, new IntPtr(MK.LBUTTON), lParamClickLocation);
MessagingMethods.PostMessage(child, WM.LBUTTONUP, new IntPtr(MK.LBUTTON), lParamClickLocation);
#if DEBUG
Console.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
Console.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);
MessagingMethods.PostMessage(child, WM.LBUTTONDBLCLK, new IntPtr(MK.LBUTTON), lParamClickLocation);
#if DEBUG
Console.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
Console.WriteLine("Double right click on window #" + child.ToString() + " at " + clientLocation.ToString());
#endif
}
/// <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>