mirror of
https://github.com/LorenzCK/OnTopReplica.git
synced 2024-05-20 20:33:06 +12:00
Native code refactoring.
Group switching completed and working. Fixed side panel opening.
This commit is contained in:
parent
78917c9c12
commit
bf91b420ab
|
@ -4,8 +4,9 @@ using System.Text;
|
|||
using System.Windows.Forms;
|
||||
using System.Runtime.InteropServices;
|
||||
using VistaControls.Dwm.Helpers;
|
||||
using System.Drawing;
|
||||
using System.ComponentModel;
|
||||
using OnTopReplica.Native;
|
||||
using System.Drawing;
|
||||
|
||||
namespace OnTopReplica {
|
||||
|
||||
|
@ -102,7 +103,7 @@ namespace OnTopReplica {
|
|||
Size = new Size(newWidth, newHeight);
|
||||
int deltaX = Size.Width - origSize.Width;
|
||||
int deltaY = Size.Height - origSize.Height;
|
||||
Location = new Point(Location.X - (deltaX / 2), Location.Y - (deltaY / 2));
|
||||
Location = new System.Drawing.Point(Location.X - (deltaX / 2), Location.Y - (deltaY / 2));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -133,14 +134,14 @@ namespace OnTopReplica {
|
|||
/// Improved with code from: http://stoyanoff.info/blog/2010/06/27/resizing-forms-while-keeping-aspect-ratio/
|
||||
/// </summary>
|
||||
protected override void WndProc(ref Message m) {
|
||||
if (KeepAspectRatio && m.Msg == NativeMethods.WM_SIZING) {
|
||||
var rc = (NativeMethods.Rectangle)Marshal.PtrToStructure(m.LParam, typeof(NativeMethods.Rectangle));
|
||||
if (KeepAspectRatio && m.Msg == MessagingMethods.WM_SIZING) {
|
||||
var rc = (Native.NRectangle)Marshal.PtrToStructure(m.LParam, typeof(Native.NRectangle));
|
||||
int res = m.WParam.ToInt32();
|
||||
|
||||
int width = (rc.Right - rc.Left) - clientSizeConversionWidth - ExtraPadding.Horizontal;
|
||||
int height = (rc.Bottom - rc.Top) - clientSizeConversionHeight - ExtraPadding.Vertical;
|
||||
|
||||
if (res == NativeMethods.WMSZ_LEFT || res == NativeMethods.WMSZ_RIGHT) {
|
||||
if (res == MessagingMethods.WMSZ_LEFT || res == MessagingMethods.WMSZ_RIGHT) {
|
||||
//Left or right resize, adjust top and bottom
|
||||
int targetHeight = (int)(width / AspectRatio);
|
||||
int diffHeight = height - targetHeight;
|
||||
|
@ -148,7 +149,7 @@ namespace OnTopReplica {
|
|||
rc.Top += (int)(diffHeight / 2.0);
|
||||
rc.Bottom = rc.Top + targetHeight + ExtraPadding.Vertical + clientSizeConversionHeight;
|
||||
}
|
||||
else if (res == NativeMethods.WMSZ_TOP || res == NativeMethods.WMSZ_BOTTOM) {
|
||||
else if (res == MessagingMethods.WMSZ_TOP || res == MessagingMethods.WMSZ_BOTTOM) {
|
||||
//Up or down resize, adjust left and right
|
||||
int targetWidth = (int)(height * AspectRatio);
|
||||
int diffWidth = width - targetWidth;
|
||||
|
@ -156,11 +157,11 @@ namespace OnTopReplica {
|
|||
rc.Left += (int)(diffWidth / 2.0);
|
||||
rc.Right = rc.Left + targetWidth + ExtraPadding.Horizontal + clientSizeConversionWidth;
|
||||
}
|
||||
else if (res == NativeMethods.WMSZ_RIGHT + NativeMethods.WMSZ_BOTTOM || res == NativeMethods.WMSZ_LEFT + NativeMethods.WMSZ_BOTTOM) {
|
||||
else if (res == MessagingMethods.WMSZ_RIGHT + MessagingMethods.WMSZ_BOTTOM || res == MessagingMethods.WMSZ_LEFT + MessagingMethods.WMSZ_BOTTOM) {
|
||||
//Lower corner resize, adjust bottom
|
||||
rc.Bottom = rc.Top + (int)(width / AspectRatio) + ExtraPadding.Vertical + clientSizeConversionHeight;
|
||||
}
|
||||
else if (res == NativeMethods.WMSZ_LEFT + NativeMethods.WMSZ_TOP || res == NativeMethods.WMSZ_RIGHT + NativeMethods.WMSZ_TOP) {
|
||||
else if (res == MessagingMethods.WMSZ_LEFT + MessagingMethods.WMSZ_TOP || res == MessagingMethods.WMSZ_RIGHT + MessagingMethods.WMSZ_TOP) {
|
||||
//Upper corner resize, adjust top
|
||||
rc.Top = rc.Bottom - (int)(width / AspectRatio) - ExtraPadding.Vertical - clientSizeConversionHeight;
|
||||
}
|
||||
|
|
2
OnTopReplica/MainForm.Designer.cs
generated
2
OnTopReplica/MainForm.Designer.cs
generated
|
@ -151,7 +151,7 @@
|
|||
this.dualWindowModeToolStripMenuItem.Name = "dualWindowModeToolStripMenuItem";
|
||||
this.dualWindowModeToolStripMenuItem.Size = new System.Drawing.Size(177, 22);
|
||||
this.dualWindowModeToolStripMenuItem.Text = "Dual window mode";
|
||||
this.dualWindowModeToolStripMenuItem.Click += new System.EventHandler(this.Menu_Dual_click);
|
||||
this.dualWindowModeToolStripMenuItem.Click += new System.EventHandler(this.Menu_Group_click);
|
||||
//
|
||||
// menuContextOpacity
|
||||
//
|
||||
|
|
|
@ -5,19 +5,21 @@ using System.Windows.Forms;
|
|||
using OnTopReplica.Properties;
|
||||
using VistaControls.Dwm;
|
||||
using VistaControls.TaskDialog;
|
||||
using System.Collections.Generic;
|
||||
using OnTopReplica.Native;
|
||||
|
||||
namespace OnTopReplica {
|
||||
|
||||
|
||||
partial class MainForm : AspectRatioForm {
|
||||
|
||||
//GUI elements
|
||||
ThumbnailPanel _thumbnailPanel;
|
||||
//GUI elements
|
||||
ThumbnailPanel _thumbnailPanel;
|
||||
SidePanel _currentSidePanel = null;
|
||||
Panel _sidePanelContainer;
|
||||
|
||||
//Window manager
|
||||
WindowManager _windowManager = new WindowManager();
|
||||
WindowHandle _lastWindowHandle = null;
|
||||
WindowHandle _lastWindowHandle = null;
|
||||
|
||||
//Message pump extension
|
||||
MessagePumpManager _msgPumpManager = new MessagePumpManager();
|
||||
|
@ -26,16 +28,16 @@ namespace OnTopReplica {
|
|||
InitializeComponent();
|
||||
KeepAspectRatio = false;
|
||||
|
||||
//Thumbnail panel
|
||||
_thumbnailPanel = new ThumbnailPanel {
|
||||
Location = Point.Empty,
|
||||
Anchor = AnchorStyles.Bottom | AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right,
|
||||
Size = ClientSize
|
||||
//Thumbnail panel
|
||||
_thumbnailPanel = new ThumbnailPanel {
|
||||
Location = Point.Empty,
|
||||
Anchor = AnchorStyles.Bottom | AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right,
|
||||
Size = ClientSize
|
||||
};
|
||||
_thumbnailPanel.CloneClick += new EventHandler<CloneClickEventArgs>(Thumbnail_CloneClick);
|
||||
Controls.Add(_thumbnailPanel);
|
||||
Controls.Add(_thumbnailPanel);
|
||||
|
||||
//Side panel
|
||||
//Side panel
|
||||
_sidePanelContainer = new Panel {
|
||||
Location = new Point(ClientSize.Width, 0),
|
||||
Anchor = AnchorStyles.Right | AnchorStyles.Top | AnchorStyles.Bottom,
|
||||
|
@ -44,12 +46,12 @@ namespace OnTopReplica {
|
|||
Size = new Size(100, ClientSize.Height),
|
||||
Padding = new Padding(4)
|
||||
};
|
||||
Controls.Add(_sidePanelContainer);
|
||||
Controls.Add(_sidePanelContainer);
|
||||
|
||||
//Set native renderer on context menus
|
||||
Asztal.Szótár.NativeToolStripRenderer.SetToolStripRenderer(
|
||||
menuContext, menuWindows, menuOpacity, menuResize, menuLanguages
|
||||
);
|
||||
//Set native renderer on context menus
|
||||
Asztal.Szótár.NativeToolStripRenderer.SetToolStripRenderer(
|
||||
menuContext, menuWindows, menuOpacity, menuResize, menuLanguages
|
||||
);
|
||||
|
||||
//Hook keyboard handler
|
||||
this.KeyUp += new KeyEventHandler(Form_KeyUp);
|
||||
|
@ -68,19 +70,20 @@ namespace OnTopReplica {
|
|||
|
||||
EventHandler RequestClosingHandler;
|
||||
|
||||
const int SidePanelMargin = 2;
|
||||
const int SidePanelMargin = 1;
|
||||
const int ScreenBorderMargin = 10;
|
||||
|
||||
bool _sidePanelDidMoveForm = false;
|
||||
Point _sidePanelPreviousFormLocation;
|
||||
bool _sidePanelDidMoveForm = false;
|
||||
Point _sidePanelPreviousFormLocation;
|
||||
|
||||
/// <summary>
|
||||
/// Opens a new side panel.
|
||||
/// </summary>
|
||||
/// <param name="panel">The side panel to embed.</param>
|
||||
public void SetSidePanel(SidePanel panel) {
|
||||
if (_currentSidePanel != null)
|
||||
if (_currentSidePanel != null) {
|
||||
CloseSidePanel();
|
||||
}
|
||||
|
||||
_currentSidePanel = panel;
|
||||
_currentSidePanel.OnFirstShown(this);
|
||||
|
@ -95,13 +98,17 @@ namespace OnTopReplica {
|
|||
|
||||
//Resize container
|
||||
_sidePanelContainer.ClientSize = new Size(
|
||||
panel.Width + intHorzMargin,
|
||||
panel.MinimumSize.Width + intHorzMargin,
|
||||
ClientSize.Height
|
||||
);
|
||||
|
||||
int rightHorzMargin = _sidePanelContainer.Width + SidePanelMargin; //horz margin between the two controls
|
||||
|
||||
//Resize rest
|
||||
MinimumSize = new Size(
|
||||
20 + panel.MinimumSize.Width + SidePanelMargin + intHorzMargin,
|
||||
panel.MinimumSize.Height + intVertMargin
|
||||
);
|
||||
ClientSize = new Size(
|
||||
ClientSize.Width + rightHorzMargin,
|
||||
ClientSize.Height
|
||||
|
@ -115,10 +122,6 @@ namespace OnTopReplica {
|
|||
ClientSize.Width - rightHorzMargin,
|
||||
0
|
||||
);
|
||||
MinimumSize = new Size(
|
||||
20 + panel.MinimumSize.Width + SidePanelMargin + intHorzMargin,
|
||||
panel.MinimumSize.Height + intVertMargin
|
||||
);
|
||||
|
||||
//Move window if needed
|
||||
var screenCurr = Screen.FromControl(this);
|
||||
|
@ -175,14 +178,14 @@ namespace OnTopReplica {
|
|||
CloseSidePanel();
|
||||
}
|
||||
|
||||
void Thumbnail_CloneClick(object sender, CloneClickEventArgs e) {
|
||||
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.ClientClickLocation, e.IsDoubleClick);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event override
|
||||
#region Event override
|
||||
|
||||
protected override void OnShown(EventArgs e) {
|
||||
base.OnShown(e);
|
||||
|
@ -202,7 +205,7 @@ namespace OnTopReplica {
|
|||
|
||||
protected override void OnResize(EventArgs e) {
|
||||
base.OnResize(e);
|
||||
|
||||
|
||||
this.GlassMargins = (_currentSidePanel != null) ?
|
||||
new Margins(ClientSize.Width - _sidePanelContainer.Width, 0, 0, 0) :
|
||||
new Margins(-1);
|
||||
|
@ -228,22 +231,22 @@ namespace OnTopReplica {
|
|||
protected override void WndProc(ref Message m) {
|
||||
_msgPumpManager.PumpMessage(m);
|
||||
|
||||
switch(m.Msg){
|
||||
case NativeMethods.WM_NCRBUTTONUP:
|
||||
switch (m.Msg) {
|
||||
case MessagingMethods.WM_NCRBUTTONUP:
|
||||
//Open context menu if right button clicked on caption (i.e. all of the window area because of glass)
|
||||
if (m.WParam.ToInt32() == NativeMethods.HTCAPTION) {
|
||||
if (m.WParam.ToInt32() == MessagingMethods.HTCAPTION) {
|
||||
menuContext.Show(MousePosition);
|
||||
|
||||
|
||||
m.Result = IntPtr.Zero;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case NativeMethods.WM_NCLBUTTONDBLCLK:
|
||||
case MessagingMethods.WM_NCLBUTTONDBLCLK:
|
||||
//Toggle fullscreen mode if double click on caption (whole glass area)
|
||||
if (m.WParam.ToInt32() == NativeMethods.HTCAPTION) {
|
||||
if (m.WParam.ToInt32() == MessagingMethods.HTCAPTION) {
|
||||
IsFullscreen = !IsFullscreen;
|
||||
|
||||
|
||||
m.Result = IntPtr.Zero;
|
||||
return;
|
||||
}
|
||||
|
@ -253,7 +256,7 @@ namespace OnTopReplica {
|
|||
base.WndProc(ref m);
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Menu Event Handling
|
||||
|
||||
|
@ -261,46 +264,46 @@ namespace OnTopReplica {
|
|||
this.Close();
|
||||
}
|
||||
|
||||
private void Menu_opening(object sender, CancelEventArgs e) {
|
||||
//Cancel if currently in "fullscreen" mode or a side panel is open
|
||||
if (IsFullscreen || _currentSidePanel != null) {
|
||||
e.Cancel = true;
|
||||
return;
|
||||
}
|
||||
private void Menu_opening(object sender, CancelEventArgs e) {
|
||||
//Cancel if currently in "fullscreen" mode or a side panel is open
|
||||
if (IsFullscreen || _currentSidePanel != null) {
|
||||
e.Cancel = true;
|
||||
return;
|
||||
}
|
||||
|
||||
selectRegionToolStripMenuItem.Enabled = _thumbnailPanel.IsShowingThumbnail;
|
||||
switchToWindowToolStripMenuItem.Enabled = _thumbnailPanel.IsShowingThumbnail;
|
||||
resizeToolStripMenuItem.Enabled = _thumbnailPanel.IsShowingThumbnail;
|
||||
chromeToolStripMenuItem.Checked = (FormBorderStyle == FormBorderStyle.Sizable);
|
||||
forwardClicksToolStripMenuItem.Checked = _thumbnailPanel.ReportThumbnailClicks;
|
||||
}
|
||||
selectRegionToolStripMenuItem.Enabled = _thumbnailPanel.IsShowingThumbnail;
|
||||
switchToWindowToolStripMenuItem.Enabled = _thumbnailPanel.IsShowingThumbnail;
|
||||
resizeToolStripMenuItem.Enabled = _thumbnailPanel.IsShowingThumbnail;
|
||||
chromeToolStripMenuItem.Checked = (FormBorderStyle == FormBorderStyle.Sizable);
|
||||
forwardClicksToolStripMenuItem.Checked = _thumbnailPanel.ReportThumbnailClicks;
|
||||
}
|
||||
|
||||
private void Menu_Close_click(object sender, EventArgs e) {
|
||||
this.Close();
|
||||
}
|
||||
|
||||
private void Menu_About_click(object sender, EventArgs e) {
|
||||
this.Hide();
|
||||
this.Hide();
|
||||
|
||||
using (var box = new AboutForm()) {
|
||||
box.Location = RecenterLocation(this, box);
|
||||
box.ShowDialog();
|
||||
Location = RecenterLocation(box, this);
|
||||
}
|
||||
|
||||
this.Show();
|
||||
|
||||
this.Show();
|
||||
}
|
||||
|
||||
private void Menu_Language_click(object sender, EventArgs e) {
|
||||
ToolStripItem tsi = (ToolStripItem)sender;
|
||||
private void Menu_Language_click(object sender, EventArgs e) {
|
||||
ToolStripItem tsi = (ToolStripItem)sender;
|
||||
|
||||
string langCode = tsi.Tag as string;
|
||||
string langCode = tsi.Tag as string;
|
||||
|
||||
if (Program.ForceGlobalLanguageChange(langCode))
|
||||
this.Close();
|
||||
else
|
||||
MessageBox.Show("Error");
|
||||
}
|
||||
if (Program.ForceGlobalLanguageChange(langCode))
|
||||
this.Close();
|
||||
else
|
||||
MessageBox.Show("Error");
|
||||
}
|
||||
|
||||
void Menu_Windows_itemclick(object sender, EventArgs e) {
|
||||
//Ensure the menu is closed
|
||||
|
@ -309,41 +312,41 @@ namespace OnTopReplica {
|
|||
//Get clicked item and window index from tag
|
||||
ToolStripItem tsi = (ToolStripItem)sender;
|
||||
|
||||
//Handle special "none" window
|
||||
if (tsi.Tag == null) {
|
||||
UnsetThumbnail();
|
||||
return;
|
||||
}
|
||||
//Handle special "none" window
|
||||
if (tsi.Tag == null) {
|
||||
UnsetThumbnail();
|
||||
return;
|
||||
}
|
||||
|
||||
var selectionData = (WindowListHelper.WindowSelectionData)tsi.Tag;
|
||||
SetThumbnail(selectionData.Handle, selectionData.Region);
|
||||
}
|
||||
|
||||
private void Menu_Switch_click(object sender, EventArgs e) {
|
||||
if (_lastWindowHandle == null)
|
||||
return;
|
||||
private void Menu_Switch_click(object sender, EventArgs e) {
|
||||
if (_lastWindowHandle == null)
|
||||
return;
|
||||
|
||||
Program.Platform.HideForm(this);
|
||||
NativeMethods.SetForegroundWindow(_lastWindowHandle.Handle);
|
||||
}
|
||||
|
||||
private void Menu_Dual_click(object sender, EventArgs e) {
|
||||
|
||||
Native.WindowManagerMethods.SetForegroundWindow(_lastWindowHandle.Handle);
|
||||
}
|
||||
|
||||
private void Menu_Forward_click(object sender, EventArgs e) {
|
||||
if (Settings.Default.FirstTimeClickForwarding && !_thumbnailPanel.ReportThumbnailClicks) {
|
||||
private void Menu_Group_click(object sender, EventArgs e) {
|
||||
SetSidePanel(new SidePanels.GroupSwitchPanel());
|
||||
}
|
||||
|
||||
private void Menu_Forward_click(object sender, EventArgs e) {
|
||||
if (Settings.Default.FirstTimeClickForwarding && !_thumbnailPanel.ReportThumbnailClicks) {
|
||||
TaskDialog dlg = new TaskDialog(Strings.InfoClickForwarding, Strings.InfoClickForwardingTitle, Strings.InfoClickForwardingContent) {
|
||||
CommonButtons = TaskDialogButton.Yes | TaskDialogButton.No
|
||||
};
|
||||
if (dlg.Show(this).CommonButton == Result.No)
|
||||
return;
|
||||
if (dlg.Show(this).CommonButton == Result.No)
|
||||
return;
|
||||
|
||||
Settings.Default.FirstTimeClickForwarding = false;
|
||||
}
|
||||
Settings.Default.FirstTimeClickForwarding = false;
|
||||
}
|
||||
|
||||
_thumbnailPanel.ReportThumbnailClicks = !_thumbnailPanel.ReportThumbnailClicks;
|
||||
}
|
||||
_thumbnailPanel.ReportThumbnailClicks = !_thumbnailPanel.ReportThumbnailClicks;
|
||||
}
|
||||
|
||||
private void Menu_Opacity_opening(object sender, CancelEventArgs e) {
|
||||
ToolStripMenuItem[] items = {
|
||||
|
@ -353,12 +356,12 @@ namespace OnTopReplica {
|
|||
toolStripMenuItem4
|
||||
};
|
||||
|
||||
foreach (ToolStripMenuItem i in items) {
|
||||
if ((double)i.Tag == this.Opacity)
|
||||
i.Checked = true;
|
||||
else
|
||||
i.Checked = false;
|
||||
}
|
||||
foreach (ToolStripMenuItem i in items) {
|
||||
if ((double)i.Tag == this.Opacity)
|
||||
i.Checked = true;
|
||||
else
|
||||
i.Checked = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void Menu_Opacity_click(object sender, EventArgs e) {
|
||||
|
@ -371,84 +374,84 @@ namespace OnTopReplica {
|
|||
}
|
||||
}
|
||||
|
||||
private void Menu_Region_click(object sender, EventArgs e) {
|
||||
private void Menu_Region_click(object sender, EventArgs e) {
|
||||
SetSidePanel(new OnTopReplica.SidePanels.RegionPanel());
|
||||
}
|
||||
|
||||
private void Menu_Resize_opening(object sender, CancelEventArgs e) {
|
||||
if (!_thumbnailPanel.IsShowingThumbnail)
|
||||
e.Cancel = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void Menu_Resize_Double(object sender, EventArgs e) {
|
||||
FitToThumbnail(2.0);
|
||||
}
|
||||
private void Menu_Resize_opening(object sender, CancelEventArgs e) {
|
||||
if (!_thumbnailPanel.IsShowingThumbnail)
|
||||
e.Cancel = true;
|
||||
}
|
||||
|
||||
private void Menu_Resize_FitToWindow(object sender, EventArgs e) {
|
||||
FitToThumbnail(1.0);
|
||||
}
|
||||
private void Menu_Resize_Double(object sender, EventArgs e) {
|
||||
FitToThumbnail(2.0);
|
||||
}
|
||||
|
||||
private void Menu_Resize_Half(object sender, EventArgs e) {
|
||||
FitToThumbnail(0.5);
|
||||
}
|
||||
private void Menu_Resize_FitToWindow(object sender, EventArgs e) {
|
||||
FitToThumbnail(1.0);
|
||||
}
|
||||
|
||||
private void Menu_Resize_Quarter(object sender, EventArgs e) {
|
||||
FitToThumbnail(0.25);
|
||||
}
|
||||
private void Menu_Resize_Half(object sender, EventArgs e) {
|
||||
FitToThumbnail(0.5);
|
||||
}
|
||||
|
||||
private void Menu_Resize_Fullscreen(object sender, EventArgs e) {
|
||||
private void Menu_Resize_Quarter(object sender, EventArgs e) {
|
||||
FitToThumbnail(0.25);
|
||||
}
|
||||
|
||||
private void Menu_Resize_Fullscreen(object sender, EventArgs e) {
|
||||
IsFullscreen = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void Menu_Position_TopLeft(object sender, EventArgs e) {
|
||||
var screen = Screen.FromControl(this);
|
||||
private void Menu_Position_TopLeft(object sender, EventArgs e) {
|
||||
var screen = Screen.FromControl(this);
|
||||
|
||||
Location = new Point(
|
||||
Location = new Point(
|
||||
screen.WorkingArea.Left - ChromeBorderHorizontal,
|
||||
screen.WorkingArea.Top - ChromeBorderVertical
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private void Menu_Position_TopRight(object sender, EventArgs e) {
|
||||
var screen = Screen.FromControl(this);
|
||||
private void Menu_Position_TopRight(object sender, EventArgs e) {
|
||||
var screen = Screen.FromControl(this);
|
||||
|
||||
Location = new Point(
|
||||
Location = new Point(
|
||||
screen.WorkingArea.Width - Size.Width + ChromeBorderHorizontal,
|
||||
screen.WorkingArea.Top - ChromeBorderVertical
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private void Menu_Position_BottomLeft(object sender, EventArgs e) {
|
||||
var screen = Screen.FromControl(this);
|
||||
private void Menu_Position_BottomLeft(object sender, EventArgs e) {
|
||||
var screen = Screen.FromControl(this);
|
||||
|
||||
Location = new Point(
|
||||
Location = new Point(
|
||||
screen.WorkingArea.Left - ChromeBorderHorizontal,
|
||||
screen.WorkingArea.Height - Size.Height + ChromeBorderVertical
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private void Menu_Position_BottomRight(object sender, EventArgs e) {
|
||||
var screen = Screen.FromControl(this);
|
||||
private void Menu_Position_BottomRight(object sender, EventArgs e) {
|
||||
var screen = Screen.FromControl(this);
|
||||
|
||||
Location = new Point(
|
||||
screen.WorkingArea.Width - Size.Width + ChromeBorderHorizontal,
|
||||
Location = new Point(
|
||||
screen.WorkingArea.Width - Size.Width + ChromeBorderHorizontal,
|
||||
screen.WorkingArea.Height - Size.Height + ChromeBorderVertical
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private void Menu_Reduce_click(object sender, EventArgs e) {
|
||||
//Hide form in a platform specific way
|
||||
Program.Platform.HideForm(this);
|
||||
}
|
||||
|
||||
private void Menu_Windows_opening(object sender, EventArgs e) {
|
||||
//Refresh window list
|
||||
_windowManager.Refresh(WindowManager.EnumerationMode.TaskWindows);
|
||||
private void Menu_Windows_opening(object sender, EventArgs e) {
|
||||
//Refresh window list
|
||||
_windowManager.Refresh(WindowManager.EnumerationMode.TaskWindows);
|
||||
|
||||
WindowListHelper.PopulateMenu(this, _windowManager, menuWindows, _lastWindowHandle, new EventHandler(Menu_Windows_itemclick));
|
||||
}
|
||||
WindowListHelper.PopulateMenu(this, _windowManager, menuWindows, _lastWindowHandle, new EventHandler(Menu_Windows_itemclick));
|
||||
}
|
||||
|
||||
private void Menu_Chrome_click(object sender, EventArgs e) {
|
||||
private void Menu_Chrome_click(object sender, EventArgs e) {
|
||||
if (FormBorderStyle == FormBorderStyle.Sizable) {
|
||||
FormBorderStyle = FormBorderStyle.None;
|
||||
Location = new Point {
|
||||
|
@ -464,12 +467,12 @@ namespace OnTopReplica {
|
|||
};
|
||||
}
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event handling
|
||||
#region Event handling
|
||||
|
||||
void Form_KeyUp(object sender, KeyEventArgs e) {
|
||||
//ALT
|
||||
|
@ -521,9 +524,9 @@ namespace OnTopReplica {
|
|||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Fullscreen
|
||||
#region Fullscreen
|
||||
|
||||
bool _isFullscreen = false;
|
||||
Point _preFullscreenLocation;
|
||||
|
@ -560,9 +563,9 @@ namespace OnTopReplica {
|
|||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Thumbnail operation
|
||||
#region Thumbnail operation
|
||||
|
||||
/// <summary>
|
||||
/// Sets a new thumbnail.
|
||||
|
@ -571,8 +574,9 @@ namespace OnTopReplica {
|
|||
/// <param name="region">Region of the window to clone.</param>
|
||||
public void SetThumbnail(WindowHandle handle, StoredRegion region) {
|
||||
try {
|
||||
_lastWindowHandle = handle;
|
||||
_thumbnailPanel.SetThumbnailHandle(handle);
|
||||
_lastWindowHandle = handle;
|
||||
_thumbnailPanel.SetThumbnailHandle(handle);
|
||||
|
||||
if (region != null)
|
||||
_thumbnailPanel.SelectedRegion = region.Rect;
|
||||
else
|
||||
|
@ -586,13 +590,32 @@ namespace OnTopReplica {
|
|||
SetAspectRatio(_thumbnailPanel.ThumbnailOriginalSize);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables group mode on a list of window handles.
|
||||
/// </summary>
|
||||
/// <param name="handles">List of window handles.</param>
|
||||
public void SetThumbnailGroup(IList<WindowHandle> handles) {
|
||||
if (handles.Count == 0)
|
||||
return;
|
||||
|
||||
//At last one thumbnail
|
||||
SetThumbnail(handles[0], null);
|
||||
|
||||
//Handle if no real group
|
||||
if (handles.Count == 1)
|
||||
return;
|
||||
|
||||
_lastWindowHandle = null;
|
||||
_msgPumpManager.Get<MessagePumpProcessors.GroupSwitchManager>().EnableGroupMode(handles);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disables the cloned thumbnail.
|
||||
/// </summary>
|
||||
public void UnsetThumbnail(){
|
||||
public void UnsetThumbnail() {
|
||||
//Unset handle
|
||||
_lastWindowHandle = null;
|
||||
_thumbnailPanel.UnsetThumbnail();
|
||||
_lastWindowHandle = null;
|
||||
_thumbnailPanel.UnsetThumbnail();
|
||||
|
||||
//Disable aspect ratio
|
||||
KeepAspectRatio = false;
|
||||
|
@ -632,30 +655,39 @@ namespace OnTopReplica {
|
|||
}
|
||||
}
|
||||
|
||||
private void ThumbnailError(Exception ex, bool suppress, string title){
|
||||
/// <summary>
|
||||
/// Gets the form's message pump manager.
|
||||
/// </summary>
|
||||
public MessagePumpManager MessagePumpManager {
|
||||
get {
|
||||
return _msgPumpManager;
|
||||
}
|
||||
}
|
||||
|
||||
private void ThumbnailError(Exception ex, bool suppress, string title) {
|
||||
if (!suppress) {
|
||||
ShowErrorDialog(title, Strings.ErrorGenericThumbnailHandleError, ex.Message);
|
||||
}
|
||||
|
||||
UnsetThumbnail();
|
||||
}
|
||||
|
||||
/// <summary>Automatically sizes the window in order to accomodate the thumbnail p times.</summary>
|
||||
/// <param name="p">Scale of the thumbnail to consider.</param>
|
||||
private void FitToThumbnail(double p) {
|
||||
try {
|
||||
Size originalSize = _thumbnailPanel.ThumbnailOriginalSize;
|
||||
Size fittedSize = new Size((int)(originalSize.Width * p), (int)(originalSize.Height * p));
|
||||
ClientSize = fittedSize;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
ThumbnailError(ex, false, Strings.ErrorUnableToFit);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Automatically sizes the window in order to accomodate the thumbnail p times.</summary>
|
||||
/// <param name="p">Scale of the thumbnail to consider.</param>
|
||||
private void FitToThumbnail(double p) {
|
||||
try {
|
||||
Size originalSize = _thumbnailPanel.ThumbnailOriginalSize;
|
||||
Size fittedSize = new Size((int)(originalSize.Width * p), (int)(originalSize.Height * p));
|
||||
ClientSize = fittedSize;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
ThumbnailError(ex, false, Strings.ErrorUnableToFit);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GUI stuff
|
||||
#region GUI stuff
|
||||
|
||||
private Point RecenterLocation(Control original, Control final) {
|
||||
int origX = original.Location.X + original.Size.Width / 2;
|
||||
|
@ -702,19 +734,19 @@ namespace OnTopReplica {
|
|||
/// <param name="mainInstruction">Main instruction of the error dialog.</param>
|
||||
/// <param name="explanation">Detailed informations about the error.</param>
|
||||
/// <param name="errorMessage">Expanded error codes/messages.</param>
|
||||
private void ShowErrorDialog(string mainInstruction, string explanation, string errorMessage) {
|
||||
private void ShowErrorDialog(string mainInstruction, string explanation, string errorMessage) {
|
||||
TaskDialog dlg = new TaskDialog(mainInstruction, Strings.ErrorGenericTitle, explanation) {
|
||||
CommonIcon = TaskDialogIcon.Stop,
|
||||
IsExpanded = false
|
||||
};
|
||||
|
||||
if (!string.IsNullOrEmpty(errorMessage)) {
|
||||
dlg.ExpandedInformation = Strings.ErrorGenericInfoText + errorMessage;
|
||||
dlg.ExpandedControlText = Strings.ErrorGenericInfoButton;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(errorMessage)) {
|
||||
dlg.ExpandedInformation = Strings.ErrorGenericInfoText + errorMessage;
|
||||
dlg.ExpandedControlText = Strings.ErrorGenericInfoButton;
|
||||
}
|
||||
|
||||
dlg.Show(this);
|
||||
}
|
||||
dlg.Show(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that the main form is visible (either closing the fullscreen mode or reactivating from task icon).
|
||||
|
@ -765,7 +797,7 @@ namespace OnTopReplica {
|
|||
this.Activate();
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using OnTopReplica.Native;
|
||||
|
||||
namespace OnTopReplica.MessagePumpProcessors {
|
||||
|
||||
class DualModeManager : BaseMessagePumpProcessor {
|
||||
|
||||
public DualModeManager() {
|
||||
_hookMsgId = HookMethods.RegisterWindowMessage("SHELLHOOK");
|
||||
if (_hookMsgId == 0)
|
||||
Console.Error.WriteLine("Failed to register SHELLHOOK Windows message.");
|
||||
}
|
||||
|
||||
uint _hookMsgId;
|
||||
bool _active = false;
|
||||
|
||||
public void EnableDualMode(IEnumerable<WindowHandle> handles) {
|
||||
if (!HookMethods.RegisterShellHookWindow(Form.Handle)) {
|
||||
Console.WriteLine("Failed to register shell hook window.");
|
||||
return;
|
||||
}
|
||||
|
||||
_active = true;
|
||||
}
|
||||
|
||||
public void Disable() {
|
||||
if (!_active)
|
||||
return;
|
||||
|
||||
if (!HookMethods.DeregisterShellHookWindow(Form.Handle))
|
||||
Console.WriteLine("Failed to deregister shell hook window.");
|
||||
|
||||
_active = false;
|
||||
}
|
||||
|
||||
public override void Process(Message msg) {
|
||||
if (msg.Msg == _hookMsgId) {
|
||||
int hookCode = msg.WParam.ToInt32();
|
||||
if (hookCode == HookMethods.HSHELL_WINDOWACTIVATED ||
|
||||
hookCode == HookMethods.HSHELL_RUDEAPPACTIVATED) {
|
||||
IntPtr activeHandle = msg.LParam;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Shutdown() {
|
||||
Disable();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
98
OnTopReplica/MessagePumpProcessors/GroupSwitchManager.cs
Normal file
98
OnTopReplica/MessagePumpProcessors/GroupSwitchManager.cs
Normal file
|
@ -0,0 +1,98 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using OnTopReplica.Native;
|
||||
|
||||
namespace OnTopReplica.MessagePumpProcessors {
|
||||
|
||||
class GroupSwitchManager : BaseMessagePumpProcessor {
|
||||
|
||||
public GroupSwitchManager() {
|
||||
_hookMsgId = HookMethods.RegisterWindowMessage("SHELLHOOK");
|
||||
if (_hookMsgId == 0)
|
||||
Console.Error.WriteLine("Failed to register SHELLHOOK Windows message.");
|
||||
}
|
||||
|
||||
uint _hookMsgId;
|
||||
bool _active = false;
|
||||
IList<WindowHandle> _handles;
|
||||
|
||||
public void EnableGroupMode(IList<WindowHandle> handles) {
|
||||
//Enable new hook
|
||||
if (!_active) {
|
||||
if (!HookMethods.RegisterShellHookWindow(Form.Handle)) {
|
||||
Console.WriteLine("Failed to register shell hook window.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//Okey dokey, will now track handles
|
||||
_handles = handles;
|
||||
_active = true;
|
||||
}
|
||||
|
||||
public void Disable() {
|
||||
if (!_active)
|
||||
return;
|
||||
|
||||
if (!HookMethods.DeregisterShellHookWindow(Form.Handle))
|
||||
Console.WriteLine("Failed to deregister shell hook window.");
|
||||
|
||||
_active = false;
|
||||
}
|
||||
|
||||
public override void Process(Message msg) {
|
||||
if (_active && msg.Msg == _hookMsgId) {
|
||||
int hookCode = msg.WParam.ToInt32();
|
||||
if (hookCode == HookMethods.HSHELL_WINDOWACTIVATED ||
|
||||
hookCode == HookMethods.HSHELL_RUDEAPPACTIVATED) {
|
||||
|
||||
IntPtr activeHandle = msg.LParam;
|
||||
Console.WriteLine("New foreground: {0}", activeHandle);
|
||||
HandleForegroundWindowChange(activeHandle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleForegroundWindowChange(IntPtr activeWindow) {
|
||||
int iActive = -1;
|
||||
for (int i = 0; i < _handles.Count; ++i) {
|
||||
if (_handles[i].Handle == activeWindow)
|
||||
iActive = i;
|
||||
}
|
||||
|
||||
if (iActive < 0) {
|
||||
//new foreground window is not tracked
|
||||
Console.WriteLine("Active window is not tracked.");
|
||||
return;
|
||||
}
|
||||
|
||||
//Get new handle to clone
|
||||
int iNewToClone = (iActive + 1) % _handles.Count;
|
||||
|
||||
Console.WriteLine("Tracked as {0}. Switching to {1}.", iActive, iNewToClone);
|
||||
|
||||
Form.SetThumbnail(_handles[iNewToClone], null);
|
||||
}
|
||||
|
||||
protected override void Shutdown() {
|
||||
Disable();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether the group switch manager ia active.
|
||||
/// </summary>
|
||||
public bool IsActive {
|
||||
get {
|
||||
return _active;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
37
OnTopReplica/Native/ErrorMethods.cs
Normal file
37
OnTopReplica/Native/ErrorMethods.cs
Normal file
|
@ -0,0 +1,37 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OnTopReplica.Native {
|
||||
/// <summary>
|
||||
/// Common Win32 error handling methods.
|
||||
/// </summary>
|
||||
static class ErrorMethods {
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
static extern uint FormatMessage(uint dwFlags, IntPtr lpSource,
|
||||
int dwMessageId, uint dwLanguageId, [Out] StringBuilder lpBuffer,
|
||||
uint nSize, IntPtr Arguments);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a string representation of a Win32 error code.
|
||||
/// </summary>
|
||||
/// <param name="msgCode">ID of the Win32 error code.</param>
|
||||
/// <returns>String representation of the error.</returns>
|
||||
public static string GetErrorMessage(int msgCode) {
|
||||
var sb = new StringBuilder(300);
|
||||
FormatMessage((uint)(0x00001000), IntPtr.Zero, msgCode, 0, sb, 299, IntPtr.Zero);
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a string representation of the last Win32 error on this thread.
|
||||
/// </summary>
|
||||
public static string GetLastErrorMessage() {
|
||||
int errorCode = Marshal.GetLastWin32Error();
|
||||
return GetErrorMessage(errorCode);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
62
OnTopReplica/Native/MessagingMethods.cs
Normal file
62
OnTopReplica/Native/MessagingMethods.cs
Normal file
|
@ -0,0 +1,62 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OnTopReplica.Native {
|
||||
/// <summary>
|
||||
/// Common methods for Win32 messaging.
|
||||
/// </summary>
|
||||
static class MessagingMethods {
|
||||
|
||||
public const int WM_GETICON = 0x7f;
|
||||
public const int WM_SIZING = 0x214;
|
||||
|
||||
public const int WMSZ_LEFT = 1;
|
||||
public const int WMSZ_RIGHT = 2;
|
||||
public const int WMSZ_TOP = 3;
|
||||
public const int WMSZ_BOTTOM = 6;
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
|
||||
public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
[Flags]
|
||||
public enum SendMessageTimeoutFlags : uint {
|
||||
AbortIfHung = 2,
|
||||
Block = 1,
|
||||
Normal = 0
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr SendMessageTimeout(IntPtr hwnd, uint message, IntPtr wparam, IntPtr lparam, SendMessageTimeoutFlags flags, uint timeout, out IntPtr result);
|
||||
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
[DllImport("user32.dll", SetLastError = false)]
|
||||
public static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
public const int HTTRANSPARENT = -1;
|
||||
public const int HTCLIENT = 1;
|
||||
public const int HTCAPTION = 2;
|
||||
|
||||
public const int WM_NCHITTEST = 0x84;
|
||||
public const int WM_NCPAINT = 0x0085;
|
||||
public const int WM_LBUTTONDOWN = 0x0201;
|
||||
public const int WM_LBUTTONUP = 0x0202;
|
||||
public const int WM_LBUTTONDBLCLK = 0x0203;
|
||||
public const int WM_NCLBUTTONUP = 0x00A2;
|
||||
public const int WM_NCLBUTTONDOWN = 0x00A1;
|
||||
public const int WM_NCLBUTTONDBLCLK = 0x00A3;
|
||||
public const int WM_NCRBUTTONUP = 0x00A5;
|
||||
|
||||
public const int MK_LBUTTON = 0x0001;
|
||||
|
||||
public const int WM_SYSCOMMAND = 0x0112;
|
||||
public const int SC_MAXIMIZE = 61458;
|
||||
public const int SC_RESTORE = 61490;
|
||||
|
||||
public static IntPtr MakeLParam(int LoWord, int HiWord) {
|
||||
return new IntPtr((HiWord << 16) | (LoWord & 0xffff));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
36
OnTopReplica/Native/Point.cs
Normal file
36
OnTopReplica/Native/Point.cs
Normal file
|
@ -0,0 +1,36 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OnTopReplica.Native {
|
||||
/// <summary>
|
||||
/// Native Point structure.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct NPoint {
|
||||
public int X, Y;
|
||||
|
||||
public NPoint(int x, int y) {
|
||||
X = x;
|
||||
Y = y;
|
||||
}
|
||||
|
||||
public NPoint(NPoint copy) {
|
||||
X = copy.X;
|
||||
Y = copy.Y;
|
||||
}
|
||||
|
||||
public static NPoint FromPoint(System.Drawing.Point point) {
|
||||
return new NPoint(point.X, point.Y);
|
||||
}
|
||||
|
||||
public System.Drawing.Point ToPoint() {
|
||||
return new System.Drawing.Point(X, Y);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return "{" + X + "," + Y + "}";
|
||||
}
|
||||
}
|
||||
}
|
44
OnTopReplica/Native/Rectangle.cs
Normal file
44
OnTopReplica/Native/Rectangle.cs
Normal file
|
@ -0,0 +1,44 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OnTopReplica.Native {
|
||||
/// <summary>A native Rectangle Structure.</summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
struct NRectangle {
|
||||
public NRectangle(int left, int top, int right, int bottom) {
|
||||
Left = left;
|
||||
Top = top;
|
||||
Right = right;
|
||||
Bottom = bottom;
|
||||
}
|
||||
|
||||
public NRectangle(System.Drawing.Rectangle rect) {
|
||||
Left = rect.X;
|
||||
Top = rect.Y;
|
||||
Right = rect.Right;
|
||||
Bottom = rect.Bottom;
|
||||
}
|
||||
|
||||
public int Left;
|
||||
public int Top;
|
||||
public int Right;
|
||||
public int Bottom;
|
||||
|
||||
public int Width {
|
||||
get {
|
||||
return Right - Left;
|
||||
}
|
||||
}
|
||||
public int Height {
|
||||
get {
|
||||
return Bottom - Top;
|
||||
}
|
||||
}
|
||||
|
||||
public System.Drawing.Rectangle ToRectangle() {
|
||||
return new System.Drawing.Rectangle(Left, Top, Right - Left, Bottom - Top);
|
||||
}
|
||||
}
|
||||
}
|
85
OnTopReplica/Native/WindowManagerMethods.cs
Normal file
85
OnTopReplica/Native/WindowManagerMethods.cs
Normal file
|
@ -0,0 +1,85 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OnTopReplica.Native {
|
||||
/// <summary>
|
||||
/// Common Win32 Window Manager native methods.
|
||||
/// </summary>
|
||||
static class WindowManagerMethods {
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr RealChildWindowFromPoint(IntPtr parent, NPoint point);
|
||||
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool IsWindowVisible(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr GetDesktopWindow();
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
static extern bool ClientToScreen(IntPtr hwnd, ref NPoint point);
|
||||
|
||||
/// <summary>
|
||||
/// Converts a point in client coordinates of a window to screen coordinates.
|
||||
/// </summary>
|
||||
/// <param name="hwnd">Handle to the window of the original point.</param>
|
||||
/// <param name="clientPoint">Point expressed in client coordinates.</param>
|
||||
/// <returns>Point expressed in screen coordinates.</returns>
|
||||
public static NPoint ClientToScreen(IntPtr hwnd, NPoint clientPoint) {
|
||||
NPoint localCopy = new NPoint(clientPoint);
|
||||
|
||||
if (ClientToScreen(hwnd, ref localCopy))
|
||||
return localCopy;
|
||||
else
|
||||
return new NPoint();
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
static extern bool ScreenToClient(IntPtr hwnd, ref NPoint point);
|
||||
|
||||
/// <summary>
|
||||
/// Converts a point in screen coordinates in client coordinates relative to a window.
|
||||
/// </summary>
|
||||
/// <param name="hwnd">Handle of the window whose client coordinate system should be used.</param>
|
||||
/// <param name="screenPoint">Point expressed in screen coordinates.</param>
|
||||
/// <returns>Point expressed in client coordinates.</returns>
|
||||
public static NPoint ScreenToClient(IntPtr hwnd, NPoint screenPoint) {
|
||||
NPoint localCopy = new NPoint(screenPoint);
|
||||
|
||||
if (ScreenToClient(hwnd, ref localCopy))
|
||||
return localCopy;
|
||||
else
|
||||
return new NPoint();
|
||||
}
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
public static extern IntPtr GetParent(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = false)]
|
||||
public static extern bool SetForegroundWindow(IntPtr hwnd);
|
||||
|
||||
public enum GetWindowMode : uint {
|
||||
GW_HWNDFIRST = 0,
|
||||
GW_HWNDLAST = 1,
|
||||
GW_HWNDNEXT = 2,
|
||||
GW_HWNDPREV = 3,
|
||||
GW_OWNER = 4,
|
||||
GW_CHILD = 5,
|
||||
GW_ENABLEDPOPUP = 6
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr GetWindow(IntPtr hwnd, GetWindowMode mode);
|
||||
|
||||
}
|
||||
}
|
87
OnTopReplica/Native/WindowMethods.cs
Normal file
87
OnTopReplica/Native/WindowMethods.cs
Normal file
|
@ -0,0 +1,87 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OnTopReplica.Native {
|
||||
/// <summary>
|
||||
/// Common Win32 methods for operating on windows.
|
||||
/// </summary>
|
||||
static class WindowMethods {
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
public static extern int GetWindowText(IntPtr hWnd, [Out] StringBuilder lpString, int nMaxCount);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
public static extern int GetWindowTextLength(IntPtr hWnd);
|
||||
|
||||
public enum WindowLong {
|
||||
WndProc = (-4),
|
||||
HInstance = (-6),
|
||||
HwndParent = (-8),
|
||||
Style = (-16),
|
||||
ExStyle = (-20),
|
||||
UserData = (-21),
|
||||
Id = (-12)
|
||||
}
|
||||
|
||||
public enum ClassLong {
|
||||
Icon = -14,
|
||||
IconSmall = -34
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum WindowStyles : long {
|
||||
None = 0,
|
||||
Disabled = 0x8000000L,
|
||||
Minimize = 0x20000000L,
|
||||
MinimizeBox = 0x20000L,
|
||||
Visible = 0x10000000L
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum WindowExStyles : long {
|
||||
AppWindow = 0x40000,
|
||||
Layered = 0x80000,
|
||||
NoActivate = 0x8000000L,
|
||||
ToolWindow = 0x80,
|
||||
TopMost = 8,
|
||||
Transparent = 0x20
|
||||
}
|
||||
|
||||
public static IntPtr GetWindowLong(IntPtr hWnd, WindowLong i) {
|
||||
if (IntPtr.Size == 8) {
|
||||
return GetWindowLongPtr64(hWnd, (int)i);
|
||||
}
|
||||
else {
|
||||
return new IntPtr(GetWindowLong32(hWnd, (int)i));
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "GetWindowLong")]
|
||||
static extern int GetWindowLong32(IntPtr hWnd, int nIndex);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "GetWindowLongPtr")]
|
||||
static extern IntPtr GetWindowLongPtr64(IntPtr hWnd, int nIndex);
|
||||
|
||||
public static IntPtr GetClassLongPtr(IntPtr hWnd, ClassLong i) {
|
||||
if (IntPtr.Size == 8) {
|
||||
return GetClassLong64(hWnd, (int)i);
|
||||
}
|
||||
else {
|
||||
return new IntPtr(GetClassLong32(hWnd, (int)i));
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "GetClassLongPtrW")]
|
||||
static extern IntPtr GetClassLong64(IntPtr hWnd, int nIndex);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "GetClassLongW")]
|
||||
static extern int GetClassLong32(IntPtr hWnd, int nIndex);
|
||||
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr GetMenu(IntPtr hwnd);
|
||||
|
||||
}
|
||||
}
|
|
@ -1,312 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OnTopReplica
|
||||
{
|
||||
static class NativeMethods
|
||||
{
|
||||
/// <summary>A native Rectangle Structure.</summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct Rectangle
|
||||
{
|
||||
public Rectangle(int left, int top, int right, int bottom) {
|
||||
Left = left;
|
||||
Top = top;
|
||||
Right = right;
|
||||
Bottom = bottom;
|
||||
}
|
||||
|
||||
public Rectangle(System.Drawing.Rectangle rect) {
|
||||
Left = rect.X;
|
||||
Top = rect.Y;
|
||||
Right = rect.Right;
|
||||
Bottom = rect.Bottom;
|
||||
}
|
||||
|
||||
public int Left;
|
||||
public int Top;
|
||||
public int Right;
|
||||
public int Bottom;
|
||||
|
||||
public int Width {
|
||||
get {
|
||||
return Right - Left;
|
||||
}
|
||||
}
|
||||
public int Height {
|
||||
get {
|
||||
return Bottom - Top;
|
||||
}
|
||||
}
|
||||
|
||||
public System.Drawing.Rectangle ToRectangle() {
|
||||
return new System.Drawing.Rectangle(Left, Top, Right - Left, Bottom - Top);
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct Point {
|
||||
public int X, Y;
|
||||
|
||||
public Point(int x, int y) {
|
||||
X = x;
|
||||
Y = y;
|
||||
}
|
||||
|
||||
public Point(Point copy) {
|
||||
X = copy.X;
|
||||
Y = copy.Y;
|
||||
}
|
||||
|
||||
public static Point FromPoint(System.Drawing.Point point) {
|
||||
return new Point(point.X, point.Y);
|
||||
}
|
||||
|
||||
public System.Drawing.Point ToPoint() {
|
||||
return new System.Drawing.Point(X, Y);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return "{" + X + "," + Y + "}";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr RealChildWindowFromPoint(IntPtr parent, Point point);
|
||||
|
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)]
|
||||
static extern bool GetClientRect(IntPtr hWnd, out Rectangle lpRect);
|
||||
|
||||
public static System.Drawing.Rectangle GetClient(IntPtr hWnd) {
|
||||
Rectangle ret;
|
||||
if (GetClientRect(hWnd, out ret))
|
||||
return ret.ToRectangle();
|
||||
else
|
||||
throw new Exception("Failed to get Client Rectangle.");
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
static extern bool GetWindowRect(IntPtr hWnd, out Rectangle lpRect);
|
||||
|
||||
public static System.Drawing.Rectangle GetWindowBounds(IntPtr hWnd) {
|
||||
Rectangle ret = new Rectangle();
|
||||
if (GetWindowRect(hWnd, out ret))
|
||||
return ret.ToRectangle();
|
||||
else
|
||||
throw new Exception("Failed to get Window Bounds.");
|
||||
}
|
||||
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool IsWindowVisible(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr GetDesktopWindow();
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
static extern bool ClientToScreen(IntPtr hwnd, ref Point point);
|
||||
|
||||
public static Point ClientToScreen(IntPtr hwnd, Point clientPoint) {
|
||||
Point localCopy = new Point(clientPoint);
|
||||
|
||||
if (ClientToScreen(hwnd, ref localCopy))
|
||||
return localCopy;
|
||||
else
|
||||
return new Point();
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
static extern bool ScreenToClient(IntPtr hwnd, ref Point point);
|
||||
|
||||
public static Point ScreenToClient(IntPtr hwnd, Point screenPoint) {
|
||||
Point localCopy = new Point(screenPoint);
|
||||
|
||||
if (ScreenToClient(hwnd, ref localCopy))
|
||||
return localCopy;
|
||||
else
|
||||
return new Point();
|
||||
}
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
public static extern IntPtr GetParent(IntPtr hWnd);
|
||||
|
||||
public enum GetAncestorMode : uint {
|
||||
Parent = 1,
|
||||
Root = 2,
|
||||
RootOwner = 3
|
||||
}
|
||||
|
||||
public enum GetWindowMode : uint {
|
||||
GW_HWNDFIRST = 0,
|
||||
GW_HWNDLAST = 1,
|
||||
GW_HWNDNEXT = 2,
|
||||
GW_HWNDPREV = 3,
|
||||
GW_OWNER = 4,
|
||||
GW_CHILD = 5,
|
||||
GW_ENABLEDPOPUP = 6
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr GetWindow(IntPtr hwnd, GetWindowMode mode);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
public static extern int GetWindowText(IntPtr hWnd, [Out] StringBuilder lpString, int nMaxCount);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
public static extern int GetWindowTextLength(IntPtr hWnd);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public enum WindowLong {
|
||||
WndProc = (-4),
|
||||
HInstance = (-6),
|
||||
HwndParent = (-8),
|
||||
Style = (-16),
|
||||
ExStyle = (-20),
|
||||
UserData = (-21),
|
||||
Id = (-12)
|
||||
}
|
||||
|
||||
public enum ClassLong {
|
||||
Icon = -14,
|
||||
IconSmall = -34
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum WindowStyles : long {
|
||||
None = 0,
|
||||
Disabled = 0x8000000L,
|
||||
Minimize = 0x20000000L,
|
||||
MinimizeBox = 0x20000L,
|
||||
Visible = 0x10000000L
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum WindowExStyles : long {
|
||||
AppWindow = 0x40000,
|
||||
Layered = 0x80000,
|
||||
NoActivate = 0x8000000L,
|
||||
ToolWindow = 0x80,
|
||||
TopMost = 8,
|
||||
Transparent = 0x20
|
||||
}
|
||||
|
||||
public static IntPtr GetWindowLong(IntPtr hWnd, WindowLong i) {
|
||||
if (IntPtr.Size == 8) {
|
||||
return GetWindowLongPtr64(hWnd, (int)i);
|
||||
}
|
||||
else {
|
||||
return new IntPtr(GetWindowLong32(hWnd, (int)i));
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "GetWindowLong")]
|
||||
private static extern int GetWindowLong32(IntPtr hWnd, int nIndex);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "GetWindowLongPtr")]
|
||||
private static extern IntPtr GetWindowLongPtr64(IntPtr hWnd, int nIndex);
|
||||
|
||||
|
||||
public static IntPtr GetClassLongPtr(IntPtr hWnd, ClassLong i) {
|
||||
if (IntPtr.Size == 8) {
|
||||
return GetClassLong64(hWnd, (int)i);
|
||||
}
|
||||
return new IntPtr(GetClassLong32(hWnd, (int)i));
|
||||
}
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "GetClassLongPtrW")]
|
||||
private static extern IntPtr GetClassLong64(IntPtr hWnd, int nIndex);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "GetClassLongW")]
|
||||
private static extern int GetClassLong32(IntPtr hWnd, int nIndex);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
|
||||
public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr SendMessageTimeout(IntPtr hwnd, uint message, IntPtr wparam, IntPtr lparam, SendMessageTimeoutFlags flags, uint timeout, out IntPtr result);
|
||||
|
||||
public const uint WM_GETICON = 0x7f;
|
||||
public const int WM_SIZING = 0x214;
|
||||
|
||||
public const int WMSZ_LEFT = 1;
|
||||
public const int WMSZ_RIGHT = 2;
|
||||
public const int WMSZ_TOP = 3;
|
||||
public const int WMSZ_BOTTOM = 6;
|
||||
|
||||
[Flags]
|
||||
public enum SendMessageTimeoutFlags : uint {
|
||||
AbortIfHung = 2,
|
||||
Block = 1,
|
||||
Normal = 0
|
||||
}
|
||||
|
||||
|
||||
public const int HTTRANSPARENT = -1;
|
||||
public const int HTCLIENT = 1;
|
||||
public const int HTCAPTION = 2;
|
||||
|
||||
public const int WM_NCHITTEST = 0x84;
|
||||
public const int WM_NCPAINT = 0x0085;
|
||||
public const int WM_LBUTTONDOWN = 0x0201;
|
||||
public const int WM_LBUTTONUP = 0x0202;
|
||||
public const int WM_LBUTTONDBLCLK = 0x0203;
|
||||
public const int WM_NCLBUTTONUP = 0x00A2;
|
||||
public const int WM_NCLBUTTONDOWN = 0x00A1;
|
||||
public const int WM_NCLBUTTONDBLCLK = 0x00A3;
|
||||
public const int WM_NCRBUTTONUP = 0x00A5;
|
||||
|
||||
public const int MK_LBUTTON = 0x0001;
|
||||
|
||||
public const int WM_SYSCOMMAND = 0x0112;
|
||||
public const int SC_MAXIMIZE = 61458;
|
||||
public const int SC_RESTORE = 61490;
|
||||
|
||||
public static IntPtr MakeLParam(int LoWord, int HiWord) {
|
||||
return new IntPtr((HiWord << 16) | (LoWord & 0xffff));
|
||||
}
|
||||
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
[DllImport("user32.dll", SetLastError = false)]
|
||||
public static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
|
||||
[DllImport("user32.dll", SetLastError = false)]
|
||||
public static extern bool SetForegroundWindow(IntPtr hwnd);
|
||||
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr GetMenu(IntPtr hwnd);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern short GetKeyState(VirtualKeyState nVirtKey);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
static extern uint FormatMessage(uint dwFlags, IntPtr lpSource,
|
||||
int dwMessageId, uint dwLanguageId, [Out] StringBuilder lpBuffer,
|
||||
uint nSize, IntPtr Arguments);
|
||||
|
||||
public static string GetLastErrorMessage(int msgCode) {
|
||||
var sb = new StringBuilder(300);
|
||||
FormatMessage((uint)(0x00001000), IntPtr.Zero, msgCode, 0, sb, 299, IntPtr.Zero);
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -133,14 +133,26 @@
|
|||
<Compile Include="CloneClickEventArgs.cs" />
|
||||
<Compile Include="CloseRequestEventArgs.cs" />
|
||||
<Compile Include="MessagePumpManager.cs" />
|
||||
<Compile Include="MessagePumpProcessors\DualModeManager.cs" />
|
||||
<Compile Include="MessagePumpProcessors\GroupSwitchManager.cs" />
|
||||
<Compile Include="IMessagePumpProcessor.cs" />
|
||||
<Compile Include="MessagePumpProcessors\BaseMessagePumpProcessor.cs" />
|
||||
<Compile Include="Native\ErrorMethods.cs" />
|
||||
<Compile Include="Native\HookMethods.cs" />
|
||||
<Compile Include="Native\HotKeyMethods.cs" />
|
||||
<Compile Include="Native\MessagingMethods.cs" />
|
||||
<Compile Include="Native\Point.cs" />
|
||||
<Compile Include="Native\Rectangle.cs" />
|
||||
<Compile Include="Native\WindowManagerMethods.cs" />
|
||||
<Compile Include="Native\WindowMethods.cs" />
|
||||
<Compile Include="SidePanel.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="SidePanels\GroupSwitchPanel.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="SidePanels\GroupSwitchPanel.Designer.cs">
|
||||
<DependentUpon>GroupSwitchPanel.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="StoredRegionComparer.cs" />
|
||||
<Compile Include="WindowsSevenMethods.cs" />
|
||||
<None Include="CommonControls.cs" />
|
||||
|
@ -176,7 +188,6 @@
|
|||
<Compile Include="MainForm.Designer.cs">
|
||||
<DependentUpon>MainForm.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="NativeMethods.cs" />
|
||||
<Compile Include="NativeToolStripRenderer.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
|
@ -184,6 +195,10 @@
|
|||
<DependentUpon>AboutForm.cs</DependentUpon>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="SidePanels\GroupSwitchPanel.resx">
|
||||
<DependentUpon>GroupSwitchPanel.cs</DependentUpon>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Strings.cs.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Strings.cs.Designer.cs</LastGenOutput>
|
||||
|
@ -245,7 +260,6 @@
|
|||
<Compile Include="ThumbnailPanel.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="VirtualKeyState.cs" />
|
||||
<Compile Include="Win32Helper.cs" />
|
||||
<Compile Include="WindowHandle.cs" />
|
||||
<Compile Include="WindowListHelper.cs" />
|
||||
|
|
129
OnTopReplica/SidePanels/GroupSwitchPanel.Designer.cs
generated
Normal file
129
OnTopReplica/SidePanels/GroupSwitchPanel.Designer.cs
generated
Normal file
|
@ -0,0 +1,129 @@
|
|||
namespace OnTopReplica.SidePanels {
|
||||
partial class GroupSwitchPanel {
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing) {
|
||||
if (disposing && (components != null)) {
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent() {
|
||||
this.groupBox1 = new System.Windows.Forms.GroupBox();
|
||||
this.buttonCancel = new System.Windows.Forms.Button();
|
||||
this.buttonEnable = new System.Windows.Forms.Button();
|
||||
this.listWindows = new System.Windows.Forms.ListView();
|
||||
this.colName = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.labelStatus = new System.Windows.Forms.Label();
|
||||
this.groupBox1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// groupBox1
|
||||
//
|
||||
this.groupBox1.Controls.Add(this.labelStatus);
|
||||
this.groupBox1.Controls.Add(this.buttonCancel);
|
||||
this.groupBox1.Controls.Add(this.buttonEnable);
|
||||
this.groupBox1.Controls.Add(this.listWindows);
|
||||
this.groupBox1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.groupBox1.Location = new System.Drawing.Point(0, 0);
|
||||
this.groupBox1.Name = "groupBox1";
|
||||
this.groupBox1.Size = new System.Drawing.Size(228, 296);
|
||||
this.groupBox1.TabIndex = 0;
|
||||
this.groupBox1.TabStop = false;
|
||||
this.groupBox1.Text = "Group switch mode";
|
||||
//
|
||||
// buttonCancel
|
||||
//
|
||||
this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.buttonCancel.Location = new System.Drawing.Point(152, 267);
|
||||
this.buttonCancel.Name = "buttonCancel";
|
||||
this.buttonCancel.Size = new System.Drawing.Size(70, 23);
|
||||
this.buttonCancel.TabIndex = 2;
|
||||
this.buttonCancel.Text = "Disable";
|
||||
this.buttonCancel.UseVisualStyleBackColor = true;
|
||||
this.buttonCancel.Click += new System.EventHandler(this.Cancel_click);
|
||||
//
|
||||
// buttonEnable
|
||||
//
|
||||
this.buttonEnable.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.buttonEnable.Image = global::OnTopReplica.Properties.Resources.xiao_ok;
|
||||
this.buttonEnable.Location = new System.Drawing.Point(12, 267);
|
||||
this.buttonEnable.Name = "buttonEnable";
|
||||
this.buttonEnable.Size = new System.Drawing.Size(134, 23);
|
||||
this.buttonEnable.TabIndex = 1;
|
||||
this.buttonEnable.Text = "Enable group mode";
|
||||
this.buttonEnable.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText;
|
||||
this.buttonEnable.UseVisualStyleBackColor = true;
|
||||
this.buttonEnable.Click += new System.EventHandler(this.Enable_click);
|
||||
//
|
||||
// listWindows
|
||||
//
|
||||
this.listWindows.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.listWindows.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
|
||||
this.colName});
|
||||
this.listWindows.FullRowSelect = true;
|
||||
this.listWindows.GridLines = true;
|
||||
this.listWindows.HideSelection = false;
|
||||
this.listWindows.LabelWrap = false;
|
||||
this.listWindows.Location = new System.Drawing.Point(6, 19);
|
||||
this.listWindows.Name = "listWindows";
|
||||
this.listWindows.Size = new System.Drawing.Size(216, 225);
|
||||
this.listWindows.TabIndex = 0;
|
||||
this.listWindows.UseCompatibleStateImageBehavior = false;
|
||||
this.listWindows.View = System.Windows.Forms.View.Details;
|
||||
//
|
||||
// colName
|
||||
//
|
||||
this.colName.Text = "Windows";
|
||||
this.colName.Width = 220;
|
||||
//
|
||||
// labelStatus
|
||||
//
|
||||
this.labelStatus.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.labelStatus.Location = new System.Drawing.Point(3, 247);
|
||||
this.labelStatus.Name = "labelStatus";
|
||||
this.labelStatus.Size = new System.Drawing.Size(219, 17);
|
||||
this.labelStatus.TabIndex = 3;
|
||||
this.labelStatus.Text = "-";
|
||||
this.labelStatus.TextAlign = System.Drawing.ContentAlignment.BottomRight;
|
||||
//
|
||||
// GroupSwitchPanel
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.groupBox1);
|
||||
this.MinimumSize = new System.Drawing.Size(220, 220);
|
||||
this.Name = "GroupSwitchPanel";
|
||||
this.Size = new System.Drawing.Size(228, 296);
|
||||
this.groupBox1.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.GroupBox groupBox1;
|
||||
private System.Windows.Forms.Button buttonCancel;
|
||||
private System.Windows.Forms.Button buttonEnable;
|
||||
private System.Windows.Forms.ListView listWindows;
|
||||
private System.Windows.Forms.ColumnHeader colName;
|
||||
private System.Windows.Forms.Label labelStatus;
|
||||
}
|
||||
}
|
72
OnTopReplica/SidePanels/GroupSwitchPanel.cs
Normal file
72
OnTopReplica/SidePanels/GroupSwitchPanel.cs
Normal file
|
@ -0,0 +1,72 @@
|
|||
using System;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using OnTopReplica.Properties;
|
||||
using System.Collections.Generic;
|
||||
using OnTopReplica.MessagePumpProcessors;
|
||||
|
||||
namespace OnTopReplica.SidePanels {
|
||||
partial class GroupSwitchPanel : SidePanel {
|
||||
|
||||
public GroupSwitchPanel() {
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public override void OnFirstShown(MainForm form) {
|
||||
base.OnFirstShown(form);
|
||||
|
||||
LoadWindowList();
|
||||
|
||||
labelStatus.Text = (ParentForm.MessagePumpManager.Get<GroupSwitchManager>().IsActive) ?
|
||||
"Group switching is active." :
|
||||
"Select multiple windows to enable.";
|
||||
}
|
||||
|
||||
private void LoadWindowList() {
|
||||
var manager = new WindowManager();
|
||||
manager.Refresh(WindowManager.EnumerationMode.TaskWindows);
|
||||
|
||||
var imageList = new ImageList();
|
||||
foreach (var w in manager.Windows) {
|
||||
var item = new ListViewItem(w.Title) {
|
||||
Tag = w
|
||||
};
|
||||
|
||||
if (w.Icon != null) {
|
||||
imageList.Images.Add(w.Icon);
|
||||
item.ImageIndex = imageList.Images.Count - 1;
|
||||
}
|
||||
|
||||
listWindows.Items.Add(item);
|
||||
}
|
||||
listWindows.SmallImageList = imageList;
|
||||
}
|
||||
|
||||
public override void OnClosing(MainForm form) {
|
||||
base.OnClosing(form);
|
||||
|
||||
if (_enableOnClose) {
|
||||
List<WindowHandle> ret = new List<WindowHandle>();
|
||||
foreach (ListViewItem i in listWindows.SelectedItems) {
|
||||
ret.Add((WindowHandle)i.Tag);
|
||||
}
|
||||
form.SetThumbnailGroup(ret);
|
||||
}
|
||||
else {
|
||||
form.MessagePumpManager.Get<GroupSwitchManager>().Disable();
|
||||
}
|
||||
}
|
||||
|
||||
bool _enableOnClose = false;
|
||||
|
||||
private void Enable_click(object sender, EventArgs e) {
|
||||
_enableOnClose = true;
|
||||
OnRequestClosing();
|
||||
}
|
||||
|
||||
private void Cancel_click(object sender, EventArgs e) {
|
||||
OnRequestClosing();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
120
OnTopReplica/SidePanels/GroupSwitchPanel.resx
Normal file
120
OnTopReplica/SidePanels/GroupSwitchPanel.resx
Normal file
|
@ -0,0 +1,120 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
|
@ -6,6 +6,7 @@ using VistaControls.Dwm;
|
|||
using VistaControls.ThemeText;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms.VisualStyles;
|
||||
using OnTopReplica.Native;
|
||||
|
||||
namespace OnTopReplica {
|
||||
|
||||
|
@ -135,9 +136,10 @@ namespace OnTopReplica {
|
|||
base.WndProc(ref m);
|
||||
|
||||
//Make transparent to hit-testing if clicks must not be registered
|
||||
if (m.Msg == NativeMethods.WM_NCHITTEST && m.Result.ToInt32() == NativeMethods.HTCLIENT &&
|
||||
if (m.Msg == MessagingMethods.WM_NCHITTEST && m.Result.ToInt32() == MessagingMethods.HTCLIENT &&
|
||||
!DrawMouseRegions && !ReportThumbnailClicks) {
|
||||
m.Result = new IntPtr(NativeMethods.HTTRANSPARENT);
|
||||
|
||||
m.Result = new IntPtr(MessagingMethods.HTTRANSPARENT);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,195 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace OnTopReplica {
|
||||
|
||||
enum VirtualKeyState : int {
|
||||
VK_LBUTTON = 0x01,
|
||||
VK_RBUTTON = 0x02,
|
||||
VK_CANCEL = 0x03,
|
||||
VK_MBUTTON = 0x04,
|
||||
//
|
||||
VK_XBUTTON1 = 0x05,
|
||||
VK_XBUTTON2 = 0x06,
|
||||
//
|
||||
VK_BACK = 0x08,
|
||||
VK_TAB = 0x09,
|
||||
//
|
||||
VK_CLEAR = 0x0C,
|
||||
VK_RETURN = 0x0D,
|
||||
//
|
||||
VK_SHIFT = 0x10,
|
||||
VK_CONTROL = 0x11,
|
||||
VK_MENU = 0x12,
|
||||
VK_PAUSE = 0x13,
|
||||
VK_CAPITAL = 0x14,
|
||||
//
|
||||
VK_KANA = 0x15,
|
||||
VK_HANGEUL = 0x15, /* old name - should be here for compatibility */
|
||||
VK_HANGUL = 0x15,
|
||||
VK_JUNJA = 0x17,
|
||||
VK_FINAL = 0x18,
|
||||
VK_HANJA = 0x19,
|
||||
VK_KANJI = 0x19,
|
||||
//
|
||||
VK_ESCAPE = 0x1B,
|
||||
//
|
||||
VK_CONVERT = 0x1C,
|
||||
VK_NONCONVERT = 0x1D,
|
||||
VK_ACCEPT = 0x1E,
|
||||
VK_MODECHANGE = 0x1F,
|
||||
//
|
||||
VK_SPACE = 0x20,
|
||||
VK_PRIOR = 0x21,
|
||||
VK_NEXT = 0x22,
|
||||
VK_END = 0x23,
|
||||
VK_HOME = 0x24,
|
||||
VK_LEFT = 0x25,
|
||||
VK_UP = 0x26,
|
||||
VK_RIGHT = 0x27,
|
||||
VK_DOWN = 0x28,
|
||||
VK_SELECT = 0x29,
|
||||
VK_PRINT = 0x2A,
|
||||
VK_EXECUTE = 0x2B,
|
||||
VK_SNAPSHOT = 0x2C,
|
||||
VK_INSERT = 0x2D,
|
||||
VK_DELETE = 0x2E,
|
||||
VK_HELP = 0x2F,
|
||||
//
|
||||
VK_LWIN = 0x5B,
|
||||
VK_RWIN = 0x5C,
|
||||
VK_APPS = 0x5D,
|
||||
//
|
||||
VK_SLEEP = 0x5F,
|
||||
//
|
||||
VK_NUMPAD0 = 0x60,
|
||||
VK_NUMPAD1 = 0x61,
|
||||
VK_NUMPAD2 = 0x62,
|
||||
VK_NUMPAD3 = 0x63,
|
||||
VK_NUMPAD4 = 0x64,
|
||||
VK_NUMPAD5 = 0x65,
|
||||
VK_NUMPAD6 = 0x66,
|
||||
VK_NUMPAD7 = 0x67,
|
||||
VK_NUMPAD8 = 0x68,
|
||||
VK_NUMPAD9 = 0x69,
|
||||
VK_MULTIPLY = 0x6A,
|
||||
VK_ADD = 0x6B,
|
||||
VK_SEPARATOR = 0x6C,
|
||||
VK_SUBTRACT = 0x6D,
|
||||
VK_DECIMAL = 0x6E,
|
||||
VK_DIVIDE = 0x6F,
|
||||
VK_F1 = 0x70,
|
||||
VK_F2 = 0x71,
|
||||
VK_F3 = 0x72,
|
||||
VK_F4 = 0x73,
|
||||
VK_F5 = 0x74,
|
||||
VK_F6 = 0x75,
|
||||
VK_F7 = 0x76,
|
||||
VK_F8 = 0x77,
|
||||
VK_F9 = 0x78,
|
||||
VK_F10 = 0x79,
|
||||
VK_F11 = 0x7A,
|
||||
VK_F12 = 0x7B,
|
||||
VK_F13 = 0x7C,
|
||||
VK_F14 = 0x7D,
|
||||
VK_F15 = 0x7E,
|
||||
VK_F16 = 0x7F,
|
||||
VK_F17 = 0x80,
|
||||
VK_F18 = 0x81,
|
||||
VK_F19 = 0x82,
|
||||
VK_F20 = 0x83,
|
||||
VK_F21 = 0x84,
|
||||
VK_F22 = 0x85,
|
||||
VK_F23 = 0x86,
|
||||
VK_F24 = 0x87,
|
||||
//
|
||||
VK_NUMLOCK = 0x90,
|
||||
VK_SCROLL = 0x91,
|
||||
//
|
||||
VK_OEM_NEC_EQUAL = 0x92, // '=' key on numpad
|
||||
//
|
||||
VK_OEM_FJ_JISHO = 0x92, // 'Dictionary' key
|
||||
VK_OEM_FJ_MASSHOU = 0x93, // 'Unregister word' key
|
||||
VK_OEM_FJ_TOUROKU = 0x94, // 'Register word' key
|
||||
VK_OEM_FJ_LOYA = 0x95, // 'Left OYAYUBI' key
|
||||
VK_OEM_FJ_ROYA = 0x96, // 'Right OYAYUBI' key
|
||||
//
|
||||
VK_LSHIFT = 0xA0,
|
||||
VK_RSHIFT = 0xA1,
|
||||
VK_LCONTROL = 0xA2,
|
||||
VK_RCONTROL = 0xA3,
|
||||
VK_LMENU = 0xA4,
|
||||
VK_RMENU = 0xA5,
|
||||
//
|
||||
VK_BROWSER_BACK = 0xA6,
|
||||
VK_BROWSER_FORWARD = 0xA7,
|
||||
VK_BROWSER_REFRESH = 0xA8,
|
||||
VK_BROWSER_STOP = 0xA9,
|
||||
VK_BROWSER_SEARCH = 0xAA,
|
||||
VK_BROWSER_FAVORITES = 0xAB,
|
||||
VK_BROWSER_HOME = 0xAC,
|
||||
//
|
||||
VK_VOLUME_MUTE = 0xAD,
|
||||
VK_VOLUME_DOWN = 0xAE,
|
||||
VK_VOLUME_UP = 0xAF,
|
||||
VK_MEDIA_NEXT_TRACK = 0xB0,
|
||||
VK_MEDIA_PREV_TRACK = 0xB1,
|
||||
VK_MEDIA_STOP = 0xB2,
|
||||
VK_MEDIA_PLAY_PAUSE = 0xB3,
|
||||
VK_LAUNCH_MAIL = 0xB4,
|
||||
VK_LAUNCH_MEDIA_SELECT = 0xB5,
|
||||
VK_LAUNCH_APP1 = 0xB6,
|
||||
VK_LAUNCH_APP2 = 0xB7,
|
||||
//
|
||||
VK_OEM_1 = 0xBA, // ';:' for US
|
||||
VK_OEM_PLUS = 0xBB, // '+' any country
|
||||
VK_OEM_COMMA = 0xBC, // ',' any country
|
||||
VK_OEM_MINUS = 0xBD, // '-' any country
|
||||
VK_OEM_PERIOD = 0xBE, // '.' any country
|
||||
VK_OEM_2 = 0xBF, // '/?' for US
|
||||
VK_OEM_3 = 0xC0, // '`~' for US
|
||||
//
|
||||
VK_OEM_4 = 0xDB, // '[{' for US
|
||||
VK_OEM_5 = 0xDC, // '\|' for US
|
||||
VK_OEM_6 = 0xDD, // ']}' for US
|
||||
VK_OEM_7 = 0xDE, // ''"' for US
|
||||
VK_OEM_8 = 0xDF,
|
||||
//
|
||||
VK_OEM_AX = 0xE1, // 'AX' key on Japanese AX kbd
|
||||
VK_OEM_102 = 0xE2, // "<>" or "\|" on RT 102-key kbd.
|
||||
VK_ICO_HELP = 0xE3, // Help key on ICO
|
||||
VK_ICO_00 = 0xE4, // 00 key on ICO
|
||||
//
|
||||
VK_PROCESSKEY = 0xE5,
|
||||
//
|
||||
VK_ICO_CLEAR = 0xE6,
|
||||
//
|
||||
VK_PACKET = 0xE7,
|
||||
//
|
||||
VK_OEM_RESET = 0xE9,
|
||||
VK_OEM_JUMP = 0xEA,
|
||||
VK_OEM_PA1 = 0xEB,
|
||||
VK_OEM_PA2 = 0xEC,
|
||||
VK_OEM_PA3 = 0xED,
|
||||
VK_OEM_WSCTRL = 0xEE,
|
||||
VK_OEM_CUSEL = 0xEF,
|
||||
VK_OEM_ATTN = 0xF0,
|
||||
VK_OEM_FINISH = 0xF1,
|
||||
VK_OEM_COPY = 0xF2,
|
||||
VK_OEM_AUTO = 0xF3,
|
||||
VK_OEM_ENLW = 0xF4,
|
||||
VK_OEM_BACKTAB = 0xF5,
|
||||
//
|
||||
VK_ATTN = 0xF6,
|
||||
VK_CRSEL = 0xF7,
|
||||
VK_EXSEL = 0xF8,
|
||||
VK_EREOF = 0xF9,
|
||||
VK_PLAY = 0xFA,
|
||||
VK_ZOOM = 0xFB,
|
||||
VK_NONAME = 0xFC,
|
||||
VK_PA1 = 0xFD,
|
||||
VK_OEM_CLEAR = 0xFE
|
||||
}
|
||||
|
||||
}
|
|
@ -1,8 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using OnTopReplica.Native;
|
||||
|
||||
namespace OnTopReplica {
|
||||
public static class Win32Helper {
|
||||
|
@ -11,19 +10,18 @@ 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, Point clickLocation, bool doubleClick) {
|
||||
NativeMethods.Point scrClickLocation = NativeMethods.ClientToScreen(window,
|
||||
NativeMethods.Point.FromPoint(clickLocation));
|
||||
public static void InjectFakeMouseClick(IntPtr window, System.Drawing.Point clickLocation, bool doubleClick) {
|
||||
NPoint scrClickLocation = WindowManagerMethods.ClientToScreen(window, NPoint.FromPoint(clickLocation));
|
||||
|
||||
//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 = NativeMethods.GetMenu(window);
|
||||
IntPtr hMenu = WindowMethods.GetMenu(window);
|
||||
if (hMenu != IntPtr.Zero)
|
||||
scrClickLocation.Y -= SystemInformation.MenuHeight;
|
||||
scrClickLocation.Y -= System.Windows.Forms.SystemInformation.MenuHeight;
|
||||
|
||||
IntPtr hChild = GetRealChildControlFromPoint(window, scrClickLocation);
|
||||
NativeMethods.Point clntClickLocation = NativeMethods.ScreenToClient(hChild, scrClickLocation);
|
||||
NPoint clntClickLocation = WindowManagerMethods.ScreenToClient(hChild, scrClickLocation);
|
||||
|
||||
if (doubleClick)
|
||||
InjectDoubleLeftMouseClick(hChild, clntClickLocation);
|
||||
|
@ -31,25 +29,25 @@ namespace OnTopReplica {
|
|||
InjectLeftMouseClick(hChild, clntClickLocation);
|
||||
}
|
||||
|
||||
private static void InjectLeftMouseClick(IntPtr child, NativeMethods.Point clientLocation) {
|
||||
IntPtr lParamClickLocation = NativeMethods.MakeLParam(clientLocation.X, clientLocation.Y);
|
||||
private static void InjectLeftMouseClick(IntPtr child, Native.NPoint clientLocation) {
|
||||
IntPtr lParamClickLocation = MessagingMethods.MakeLParam(clientLocation.X, clientLocation.Y);
|
||||
|
||||
NativeMethods.PostMessage(child, NativeMethods.WM_LBUTTONDOWN,
|
||||
new IntPtr(NativeMethods.MK_LBUTTON), lParamClickLocation);
|
||||
MessagingMethods.PostMessage(child, MessagingMethods.WM_LBUTTONDOWN,
|
||||
new IntPtr(MessagingMethods.MK_LBUTTON), lParamClickLocation);
|
||||
|
||||
NativeMethods.PostMessage(child, NativeMethods.WM_LBUTTONUP,
|
||||
new IntPtr(NativeMethods.MK_LBUTTON), lParamClickLocation);
|
||||
MessagingMethods.PostMessage(child, MessagingMethods.WM_LBUTTONUP,
|
||||
new IntPtr(MessagingMethods.MK_LBUTTON), lParamClickLocation);
|
||||
|
||||
#if DEBUG
|
||||
Console.WriteLine("Left click on window #" + child.ToString() + " at " + clientLocation.ToString());
|
||||
#endif
|
||||
}
|
||||
|
||||
private static void InjectDoubleLeftMouseClick(IntPtr child, NativeMethods.Point clientLocation) {
|
||||
IntPtr lParamClickLocation = NativeMethods.MakeLParam(clientLocation.X, clientLocation.Y);
|
||||
private static void InjectDoubleLeftMouseClick(IntPtr child, NPoint clientLocation) {
|
||||
IntPtr lParamClickLocation = MessagingMethods.MakeLParam(clientLocation.X, clientLocation.Y);
|
||||
|
||||
NativeMethods.PostMessage(child, NativeMethods.WM_LBUTTONDBLCLK,
|
||||
new IntPtr(NativeMethods.MK_LBUTTON), lParamClickLocation);
|
||||
MessagingMethods.PostMessage(child, MessagingMethods.WM_LBUTTONDBLCLK,
|
||||
new IntPtr(MessagingMethods.MK_LBUTTON), lParamClickLocation);
|
||||
|
||||
#if DEBUG
|
||||
Console.WriteLine("Double left click on window #" + child.ToString() + " at " + clientLocation.ToString());
|
||||
|
@ -59,10 +57,11 @@ namespace OnTopReplica {
|
|||
/// <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, NativeMethods.Point scrClickLocation) {
|
||||
private static IntPtr GetRealChildControlFromPoint(IntPtr parent, NPoint scrClickLocation) {
|
||||
IntPtr curr = parent, child = IntPtr.Zero;
|
||||
do {
|
||||
child = NativeMethods.RealChildWindowFromPoint(curr, NativeMethods.ScreenToClient(curr, scrClickLocation));
|
||||
child = WindowManagerMethods.RealChildWindowFromPoint(curr,
|
||||
WindowManagerMethods.ScreenToClient(curr, scrClickLocation));
|
||||
|
||||
if (child == IntPtr.Zero || child == curr)
|
||||
break;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Drawing;
|
||||
using OnTopReplica.Native;
|
||||
|
||||
namespace OnTopReplica {
|
||||
|
||||
|
@ -29,7 +30,8 @@ namespace OnTopReplica {
|
|||
//Fetch icon from window
|
||||
IntPtr hIcon;
|
||||
|
||||
if (NativeMethods.SendMessageTimeout(_handle, NativeMethods.WM_GETICON, new IntPtr(2), new IntPtr(0), NativeMethods.SendMessageTimeoutFlags.AbortIfHung | NativeMethods.SendMessageTimeoutFlags.Block, 500, out hIcon) == IntPtr.Zero)
|
||||
if (MessagingMethods.SendMessageTimeout(_handle, MessagingMethods.WM_GETICON, new IntPtr(2), new IntPtr(0),
|
||||
MessagingMethods.SendMessageTimeoutFlags.AbortIfHung | MessagingMethods.SendMessageTimeoutFlags.Block, 500, out hIcon) == IntPtr.Zero)
|
||||
hIcon = IntPtr.Zero;
|
||||
|
||||
if (hIcon.ToInt64() != 0) {
|
||||
|
@ -37,7 +39,7 @@ namespace OnTopReplica {
|
|||
}
|
||||
else {
|
||||
//Fetch icon from window class
|
||||
hIcon = (IntPtr)NativeMethods.GetClassLongPtr(_handle, NativeMethods.ClassLong.IconSmall);
|
||||
hIcon = (IntPtr)WindowMethods.GetClassLongPtr(_handle, WindowMethods.ClassLong.IconSmall);
|
||||
|
||||
if (hIcon.ToInt64() != 0) {
|
||||
_icon = Icon.FromHandle(hIcon);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using OnTopReplica.Native;
|
||||
|
||||
namespace OnTopReplica {
|
||||
/// <summary>A helper class that allows you to easily build and keep a list of Windows (in the form of WindowHandle objects).</summary>
|
||||
|
@ -23,22 +24,22 @@ namespace OnTopReplica {
|
|||
public void Refresh(EnumerationMode mode) {
|
||||
_windows = new List<WindowHandle>();
|
||||
|
||||
NativeMethods.EnumWindowsProc proc = null;
|
||||
WindowManagerMethods.EnumWindowsProc proc = null;
|
||||
switch (mode) {
|
||||
case EnumerationMode.AllVisible:
|
||||
proc = new NativeMethods.EnumWindowsProc(EnumWindowProcAll);
|
||||
proc = new WindowManagerMethods.EnumWindowsProc(EnumWindowProcAll);
|
||||
break;
|
||||
|
||||
case EnumerationMode.AllTopLevel:
|
||||
proc = new NativeMethods.EnumWindowsProc(EnumWindowProcTopLevel);
|
||||
proc = new WindowManagerMethods.EnumWindowsProc(EnumWindowProcTopLevel);
|
||||
break;
|
||||
|
||||
case EnumerationMode.TaskWindows:
|
||||
proc = new NativeMethods.EnumWindowsProc(EnumWindowProcTask);
|
||||
proc = new WindowManagerMethods.EnumWindowsProc(EnumWindowProcTask);
|
||||
break;
|
||||
}
|
||||
|
||||
NativeMethods.EnumWindows(proc, IntPtr.Zero);
|
||||
WindowManagerMethods.EnumWindows(proc, IntPtr.Zero);
|
||||
}
|
||||
|
||||
|
||||
|
@ -51,7 +52,7 @@ namespace OnTopReplica {
|
|||
|
||||
|
||||
private bool EnumWindowProcAll(IntPtr hwnd, IntPtr lParam) {
|
||||
if (NativeMethods.IsWindowVisible(hwnd)) {
|
||||
if (WindowManagerMethods.IsWindowVisible(hwnd)) {
|
||||
string title = GetWindowTitle(hwnd);
|
||||
_windows.Add( new WindowHandle(hwnd, title));
|
||||
}
|
||||
|
@ -59,9 +60,9 @@ namespace OnTopReplica {
|
|||
}
|
||||
|
||||
private bool EnumWindowProcTopLevel(IntPtr hwnd, IntPtr lParam) {
|
||||
if (NativeMethods.IsWindowVisible(hwnd)) {
|
||||
if (WindowManagerMethods.IsWindowVisible(hwnd)) {
|
||||
//Check if window has no parent
|
||||
if ((long)NativeMethods.GetParent(hwnd) == 0 && NativeMethods.GetDesktopWindow() != hwnd) {
|
||||
if ((long)WindowManagerMethods.GetParent(hwnd) == 0 && WindowManagerMethods.GetDesktopWindow() != hwnd) {
|
||||
string title = GetWindowTitle(hwnd);
|
||||
_windows.Add( new WindowHandle(hwnd, title));
|
||||
}
|
||||
|
@ -84,13 +85,13 @@ namespace OnTopReplica {
|
|||
if (string.IsNullOrEmpty(title))
|
||||
return true;
|
||||
|
||||
if (NativeMethods.IsWindowVisible(hwnd)) {
|
||||
if ((long)NativeMethods.GetParent(hwnd) == 0) {
|
||||
bool hasOwner = (long)NativeMethods.GetWindow(hwnd, NativeMethods.GetWindowMode.GW_OWNER) != 0;
|
||||
NativeMethods.WindowExStyles exStyle = (NativeMethods.WindowExStyles)NativeMethods.GetWindowLong(hwnd, NativeMethods.WindowLong.ExStyle);
|
||||
if (WindowManagerMethods.IsWindowVisible(hwnd)) {
|
||||
if ((long)WindowManagerMethods.GetParent(hwnd) == 0) {
|
||||
bool hasOwner = (long)WindowManagerMethods.GetWindow(hwnd, WindowManagerMethods.GetWindowMode.GW_OWNER) != 0;
|
||||
WindowMethods.WindowExStyles exStyle = (WindowMethods.WindowExStyles)WindowMethods.GetWindowLong(hwnd, WindowMethods.WindowLong.ExStyle);
|
||||
|
||||
if (((exStyle & NativeMethods.WindowExStyles.ToolWindow) == 0 && !hasOwner) || //unowned non-tool window
|
||||
((exStyle & NativeMethods.WindowExStyles.AppWindow) == NativeMethods.WindowExStyles.AppWindow && hasOwner)) { //owned application window
|
||||
if (((exStyle & WindowMethods.WindowExStyles.ToolWindow) == 0 && !hasOwner) || //unowned non-tool window
|
||||
((exStyle & WindowMethods.WindowExStyles.AppWindow) == WindowMethods.WindowExStyles.AppWindow && hasOwner)) { //owned application window
|
||||
_windows.Add(new WindowHandle(hwnd, title));
|
||||
}
|
||||
}
|
||||
|
@ -102,11 +103,11 @@ namespace OnTopReplica {
|
|||
#region Auxiliary methods
|
||||
|
||||
private string GetWindowTitle(IntPtr hwnd) {
|
||||
int length = NativeMethods.GetWindowTextLength(hwnd);
|
||||
int length = WindowMethods.GetWindowTextLength(hwnd);
|
||||
|
||||
if (length > 0) {
|
||||
StringBuilder sb = new StringBuilder(length + 1);
|
||||
if (NativeMethods.GetWindowText(hwnd, sb, sb.Capacity) > 0)
|
||||
if (WindowMethods.GetWindowText(hwnd, sb, sb.Capacity) > 0)
|
||||
return sb.ToString();
|
||||
else
|
||||
return String.Empty;
|
||||
|
|
Loading…
Reference in a new issue