Added automatic plugin locator on cloned windows.

This commit is contained in:
Lorenz Cuno Klopfenstein 2012-05-30 01:43:29 +02:00
parent c2fafd67e2
commit 849c3c758f
4 changed files with 121 additions and 2 deletions

View file

@ -47,5 +47,9 @@ namespace OnTopReplica.Native {
}
}
public override string ToString() {
return string.Format("{{{0},{1},{2},{3}}}", Left, Top, Right, Bottom);
}
}
}

View file

@ -12,6 +12,9 @@ namespace OnTopReplica.Native {
[DllImport("user32.dll", SetLastError = true)]
public static extern bool GetClientRect(IntPtr handle, out NRectangle rect);
[DllImport("user32.dll", SetLastError = true)]
public static extern bool GetWindowRect(IntPtr handle, out NRectangle rect);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern int GetWindowText(IntPtr hWnd, [Out] StringBuilder lpString, int nMaxCount);

View file

@ -0,0 +1,97 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using OnTopReplica.Native;
namespace OnTopReplica {
/// <summary>
/// Facility class that attempts to locate the region occupied by plugins inside another window.
/// </summary>
class PluginRegionLocator {
static PluginRegionLocator() {
_pluginClassNames = new HashSet<string>() {
"aPluginWinClass", //Opera 11 Flash plugin
"MacromediaFlashPlayerActiveX", //IE 9 Flash plugin
"NativeWindowClass", //Google Chrome Flash plugin
"GeckoPluginWindow", //Firefox 9 Flash plugin
};
}
static readonly HashSet<string> _pluginClassNames;
/// <summary>
/// Attempts to locate a plugin region inside a window.
/// </summary>
/// <param name="handle">The handle to the parent window.</param>
/// <returns>The region where a plugin window is located or null if none found.</returns>
public Rectangle? LocatePluginRegion(WindowHandle handle) {
if (handle == null)
throw new ArgumentNullException();
WindowManagerMethods.EnumChildWindows(handle.Handle, LocatingWndProc, IntPtr.Zero);
if (_selectedHandle != null) {
Console.Out.WriteLine("Selected {0} '{1}' (class {2})", _selectedHandle.Handle, _selectedHandle.Title, _selectedHandle.Class);
NRectangle rect;
WindowMethods.GetWindowRect(_selectedHandle.Handle, out rect);
NRectangle clientRect;
WindowMethods.GetClientRect(_selectedHandle.Handle, out clientRect);
Console.Out.WriteLine("WindowRect: {0}", rect);
NRectangle ownerRect;
WindowMethods.GetWindowRect(handle.Handle, out ownerRect);
Console.Out.WriteLine("Owner WindowRect: {0}", ownerRect);
var ret = new Rectangle {
X = rect.Left - ownerRect.Left,
Y = rect.Top - ownerRect.Top,
Width = clientRect.Width,
Height = clientRect.Height
};
//Safety check (this may happen when the plugin client area is 0 pixel large)
if (ret.Width < 0 || ret.Height < 0)
return null;
Console.Out.WriteLine("Selected region: {0}", ret);
return ret;
}
else {
Console.Out.WriteLine("None found.");
return null;
}
}
WindowHandle _selectedHandle = null;
private bool LocatingWndProc(IntPtr handle, IntPtr lParam) {
//Skip non visible windows
if (!WindowManagerMethods.IsWindowVisible(handle)) {
return true;
}
//Class name check
string cl = WindowMethods.GetWindowClass(handle);
#if DEBUG
Console.Out.WriteLine("Child window, class {0}", cl);
#endif
if (_pluginClassNames.Contains(cl)) {
//Found plugin window, stop now
_selectedHandle = new WindowHandle(handle);
return false;
}
return true;
}
}
}

View file

@ -85,12 +85,16 @@ namespace OnTopReplica {
//No region
var nullRegionItem = new ToolStripMenuItem(Strings.MenuWindowsWholeRegion);
nullRegionItem.Tag = new Tuple<WindowHandle, StoredRegion>(parentHandle, null);
nullRegionItem.Tag = parentHandle;
nullRegionItem.Image = Resources.regions;
nullRegionItem.Click += MenuRegionWindowClickHandler;
nullRegionItem.Click += MenuWindowClickHandler;
parent.DropDownItems.Add(nullRegionItem);
//Video detector
var detectorItem = new ToolStripMenuItem("Autodetect plugin");
detectorItem.Tag = parentHandle;
detectorItem.Click += MenuVideoCropperClickHandler;
parent.DropDownItems.Add(detectorItem);
//Regions (if any)
if (regions == null || regions.Length == 0)
@ -129,8 +133,19 @@ namespace OnTopReplica {
(tuple.Item2 != null) ? (System.Drawing.Rectangle?)tuple.Item2.Bounds : null);
}
PluginRegionLocator _pluginRegionLocator = null;
private void MenuVideoCropperClickHandler(object sender, EventArgs args){
CommonClickHandler();
var tsi = (ToolStripMenuItem)sender;
var handle = (WindowHandle)tsi.Tag;
if (_pluginRegionLocator == null)
_pluginRegionLocator = new PluginRegionLocator();
var detectedRegion = _pluginRegionLocator.LocatePluginRegion(handle);
_owner.SetThumbnail(handle, detectedRegion);
}
private void CommonClickHandler() {