mirror of
https://github.com/mRemoteNG/mRemoteNG.git
synced 2026-02-17 22:11:48 +08:00
moved a number of focus logic window events out of frmmain
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
using mRemoteNG.App;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Connection.Protocol;
|
||||
using mRemoteNG.Messages;
|
||||
using mRemoteNG.UI.Tabs;
|
||||
using Message = System.Windows.Forms.Message;
|
||||
|
||||
namespace mRemoteNG.UI.FocusHelpers
|
||||
{
|
||||
@@ -17,13 +19,14 @@ namespace mRemoteNG.UI.FocusHelpers
|
||||
private bool _childProcessHeldLastFocus;
|
||||
private bool _mainWindowFocused;
|
||||
private bool _connectionReleasingFocus;
|
||||
private bool _inSizeMove;
|
||||
private bool _fixingMainWindowFocus;
|
||||
|
||||
/// <summary>
|
||||
/// TRUE if any part of mrng has focus - the main window or child processes
|
||||
/// </summary>
|
||||
public bool MrngFocused => MainWindowFocused || ChildProcessFocused;
|
||||
|
||||
public bool FixingMainWindowFocus { get; private set; }
|
||||
|
||||
public bool MainWindowFocused
|
||||
{
|
||||
@@ -81,7 +84,7 @@ namespace mRemoteNG.UI.FocusHelpers
|
||||
ExternalWindowDefocused();
|
||||
}
|
||||
|
||||
private void ProtocolOnDisconnected(object sender, string disconnectedmessage, int? reasoncode)
|
||||
private void ProtocolOnDisconnected(object sender, string disconnectedMessage, int? reasonCode)
|
||||
{
|
||||
if (!(sender is ExternalProcessProtocolBase prot))
|
||||
return;
|
||||
@@ -116,16 +119,16 @@ namespace mRemoteNG.UI.FocusHelpers
|
||||
return;
|
||||
}
|
||||
|
||||
//FixingMainWindowFocus = true;
|
||||
_fixingMainWindowFocus = true;
|
||||
//_focusMainWindowAction();
|
||||
//FixingMainWindowFocus = false;
|
||||
_fixingMainWindowFocus = false;
|
||||
|
||||
ifc.Protocol.Focus();
|
||||
//var conFormWindow = ifc.FindForm();
|
||||
//((ConnectionTab) conFormWindow)?.RefreshInterfaceController();
|
||||
}
|
||||
|
||||
public int KeyboardHookCallback(int msg, NativeMethods.KBDLLHOOKSTRUCT kbd)
|
||||
private int KeyboardHookCallback(int msg, NativeMethods.KBDLLHOOKSTRUCT kbd)
|
||||
{
|
||||
var key = (Keys)kbd.vkCode;
|
||||
// Alt + Tab
|
||||
@@ -142,28 +145,37 @@ namespace mRemoteNG.UI.FocusHelpers
|
||||
}
|
||||
|
||||
// Alt + `
|
||||
if (key.HasFlag(Keys.Oem3) && kbd.flags.HasFlag(NativeMethods.KBDLLHOOKSTRUCTFlags.LLKHF_ALTDOWN))
|
||||
{
|
||||
if (msg != NativeMethods.WM_SYSKEYUP && msg != NativeMethods.WM_KEYUP)
|
||||
return 0;
|
||||
//if (key.HasFlag(Keys.Oem3) && kbd.flags.HasFlag(NativeMethods.KBDLLHOOKSTRUCTFlags.LLKHF_ALTDOWN))
|
||||
//{
|
||||
// if (msg != NativeMethods.WM_SYSKEYUP && msg != NativeMethods.WM_KEYUP)
|
||||
// return 0;
|
||||
|
||||
if (ChildProcessFocused)
|
||||
{
|
||||
_connectionReleasingFocus = true;
|
||||
var focused = NativeMethods.SetForegroundWindow(_mainWindowHandle);
|
||||
_connectionReleasingFocus = false;
|
||||
return 1;
|
||||
}
|
||||
// if (ChildProcessFocused)
|
||||
// {
|
||||
// _connectionReleasingFocus = true;
|
||||
// var focused = NativeMethods.SetForegroundWindow(_mainWindowHandle);
|
||||
// _connectionReleasingFocus = false;
|
||||
// return 1;
|
||||
// }
|
||||
|
||||
if (!MainWindowFocused)
|
||||
return 0;
|
||||
ActivateConnection();
|
||||
return 1;
|
||||
}
|
||||
// if (!MainWindowFocused)
|
||||
// return 0;
|
||||
// ActivateConnection();
|
||||
// return 1;
|
||||
//}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void ForceExtAppToGiveUpFocus()
|
||||
{
|
||||
if (!ChildProcessHeldLastFocus)
|
||||
return;
|
||||
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.DebugMsg, "Forcing extpp to give up focus.");
|
||||
ChildProcessHeldLastFocus = false;
|
||||
}
|
||||
|
||||
private void FixExternalAppAltTab()
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.DebugMsg, "FIXING ALT-TAB FOR EXTAPP");
|
||||
@@ -188,6 +200,7 @@ namespace mRemoteNG.UI.FocusHelpers
|
||||
private void ExternalWindowFocused()
|
||||
{
|
||||
_extFocusCount++;
|
||||
ChildProcessHeldLastFocus = true;
|
||||
}
|
||||
|
||||
private void ExternalWindowDefocused()
|
||||
@@ -195,5 +208,86 @@ namespace mRemoteNG.UI.FocusHelpers
|
||||
_extFocusCount--;
|
||||
ChildProcessHeldLastFocus = !MainWindowFocused && !ChildProcessFocused;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Give the <see cref="ExternalProcessFocusHelper"/> a chance to
|
||||
/// hook into a system window's WndProc message handler. Returns
|
||||
/// true if an action has been taken which should override the
|
||||
/// base windows own WndProc handling.
|
||||
/// </summary>
|
||||
/// <param name="m"></param>
|
||||
/// <returns>
|
||||
/// Returns true if an action has been taken which should override the
|
||||
/// base windows own WndProc handling.
|
||||
/// </returns>
|
||||
public bool HandleWndProc(ref Message m)
|
||||
{
|
||||
// ReSharper disable once SwitchStatementMissingSomeCases
|
||||
switch (m.Msg)
|
||||
{
|
||||
case NativeMethods.WM_PARENTNOTIFY:
|
||||
var notifyType = m.WParam.ToInt32();
|
||||
// ignore non-click notify events
|
||||
if (notifyType == NativeMethods.WM_CREATE || notifyType == NativeMethods.WM_DESTROY)
|
||||
break;
|
||||
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.DebugMsg, "Main window clicked");
|
||||
// when the main window is clicked, assume the user wants the main window focused
|
||||
ForceExtAppToGiveUpFocus();
|
||||
break;
|
||||
case NativeMethods.WM_ACTIVATEAPP:
|
||||
if (_fixingMainWindowFocus)
|
||||
break;
|
||||
|
||||
// main window is being deactivated
|
||||
if (m.WParam.ToInt32() == 0)
|
||||
{
|
||||
MainWindowFocused = false;
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.DebugMsg, $"mRemoteNG main window lost focus (_childProcessHeldLastFocus={ChildProcessHeldLastFocus})");
|
||||
break;
|
||||
}
|
||||
|
||||
MainWindowFocused = true;
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.DebugMsg, $"mRemoteNG main window received focus (_childProcessHeldLastFocus={ChildProcessHeldLastFocus})");
|
||||
|
||||
break;
|
||||
case NativeMethods.WM_NCACTIVATE:
|
||||
// Never allow the mRemoteNG window to display itself as inactive. By doing this,
|
||||
// we ensure focus events can propagate to child connection windows
|
||||
NativeMethods.DefWindowProc(_mainWindowHandle, Convert.ToUInt32(m.Msg), (IntPtr)1, m.LParam);
|
||||
m.Result = (IntPtr)1;
|
||||
return true;
|
||||
|
||||
// handle re-focusing connection when the main window moves or resizes
|
||||
case NativeMethods.WM_ENTERSIZEMOVE:
|
||||
_inSizeMove = true;
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.DebugMsg, "Begin app window move/resize");
|
||||
break;
|
||||
case NativeMethods.WM_EXITSIZEMOVE:
|
||||
_inSizeMove = false;
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.DebugMsg, "End app window move/resize");
|
||||
// This handles activations from clicks that started a size/move operation
|
||||
ActivateConnection();
|
||||
break;
|
||||
case NativeMethods.WM_WINDOWPOSCHANGED:
|
||||
// Ignore this message if the window wasn't activated
|
||||
if (!MainWindowFocused)
|
||||
break;
|
||||
|
||||
var windowPos = (NativeMethods.WINDOWPOS)Marshal.PtrToStructure(m.LParam, typeof(NativeMethods.WINDOWPOS));
|
||||
if ((windowPos.flags & NativeMethods.SWP_NOACTIVATE) == 0)
|
||||
{
|
||||
if (!MainWindowFocused && !_inSizeMove)
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.DebugMsg, "WM_WINDOWPOSCHANGED DONE");
|
||||
ActivateConnection();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
2
mRemoteV1/UI/Forms/frmMain.Designer.cs
generated
2
mRemoteV1/UI/Forms/frmMain.Designer.cs
generated
@@ -205,8 +205,6 @@
|
||||
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.frmMain_FormClosing);
|
||||
this.Load += new System.EventHandler(this.frmMain_Load);
|
||||
this.Shown += new System.EventHandler(this.frmMain_Shown);
|
||||
this.ResizeBegin += new System.EventHandler(this.frmMain_ResizeBegin);
|
||||
this.ResizeEnd += new System.EventHandler(this.frmMain_ResizeEnd);
|
||||
this.Resize += new System.EventHandler(this.frmMain_Resize);
|
||||
this.msMain.ResumeLayout(false);
|
||||
this.msMain.PerformLayout();
|
||||
|
||||
@@ -8,11 +8,14 @@ using mRemoteNG.Config.DataProviders;
|
||||
using mRemoteNG.Config.Putty;
|
||||
using mRemoteNG.Config.Settings;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Connection.Protocol;
|
||||
using mRemoteNG.Messages;
|
||||
using mRemoteNG.Messages.MessageWriters;
|
||||
using mRemoteNG.Themes;
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.UI.FocusHelpers;
|
||||
using mRemoteNG.UI.Menu;
|
||||
using mRemoteNG.UI.Panels;
|
||||
using mRemoteNG.UI.Tabs;
|
||||
using mRemoteNG.UI.TaskDialog;
|
||||
using mRemoteNG.UI.Window;
|
||||
@@ -23,13 +26,8 @@ using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using mRemoteNG.Connection.Protocol;
|
||||
using mRemoteNG.UI.FocusHelpers;
|
||||
using mRemoteNG.UI.Panels;
|
||||
using WeifenLuo.WinFormsUI.Docking;
|
||||
using Message = System.Windows.Forms.Message;
|
||||
|
||||
@@ -42,8 +40,6 @@ namespace mRemoteNG.UI.Forms
|
||||
public static FrmMain Default { get; } = new FrmMain();
|
||||
|
||||
private static ClipboardchangeEventHandler _clipboardChangedEvent;
|
||||
private bool _inSizeMove;
|
||||
private bool _inMouseActivate;
|
||||
private IntPtr _fpChainedWindowHandle;
|
||||
private bool _usingSqlServer;
|
||||
private string _connectionsFileName;
|
||||
@@ -457,13 +453,6 @@ namespace mRemoteNG.UI.Forms
|
||||
#endregion
|
||||
|
||||
#region Window Overrides and DockPanel Stuff
|
||||
|
||||
private void frmMain_ResizeBegin(object sender, EventArgs e)
|
||||
{
|
||||
_inSizeMove = true;
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.DebugMsg, "Begin app window move/resize");
|
||||
}
|
||||
|
||||
private void frmMain_Resize(object sender, EventArgs e)
|
||||
{
|
||||
if (WindowState == FormWindowState.Minimized)
|
||||
@@ -482,15 +471,6 @@ namespace mRemoteNG.UI.Forms
|
||||
}
|
||||
}
|
||||
|
||||
private void frmMain_ResizeEnd(object sender, EventArgs e)
|
||||
{
|
||||
_inSizeMove = false;
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.DebugMsg, "End app window move/resize");
|
||||
// This handles activations from clicks that started a size/move operation
|
||||
_focusHelper.ActivateConnection();
|
||||
}
|
||||
|
||||
|
||||
// Maybe after starting putty, remove its ability to show up in alt-tab?
|
||||
// SetWindowLong(this.Handle, GWL_EXSTYLE, (GetWindowLong(this.Handle,GWL_EXSTYLE) | WS_EX_TOOLWINDOW) & ~WS_EX_APPWINDOW);
|
||||
protected override void WndProc(ref Message m)
|
||||
@@ -498,13 +478,13 @@ namespace mRemoteNG.UI.Forms
|
||||
// Listen for and handle operating system messages
|
||||
try
|
||||
{
|
||||
if (_focusHelper?.HandleWndProc(ref m) == true)
|
||||
return;
|
||||
|
||||
// ReSharper disable once SwitchStatementMissingSomeCases
|
||||
switch (m.Msg)
|
||||
{
|
||||
case NativeMethods.WM_MOUSEACTIVATE:
|
||||
_inMouseActivate = true;
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.DebugMsg, $"_inMouseActivate = {_inMouseActivate}");
|
||||
|
||||
var controlThatWasClicked2 = FromChildHandle(NativeMethods.WindowFromPoint(MousePosition))
|
||||
?? GetChildAtPoint(MousePosition);
|
||||
|
||||
@@ -512,29 +492,6 @@ namespace mRemoteNG.UI.Forms
|
||||
break;
|
||||
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.DebugMsg, $"Clicked control: {controlThatWasClicked2}");
|
||||
break;
|
||||
case NativeMethods.WM_ACTIVATEAPP:
|
||||
if (_focusHelper.FixingMainWindowFocus)
|
||||
break;
|
||||
|
||||
if (m.WParam.ToInt32() == 0) // mRemoteNG is being deactivated
|
||||
{
|
||||
_inMouseActivate = false;
|
||||
_focusHelper.MainWindowFocused = false;
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.DebugMsg, $"mRemoteNG main window lost focus (_childProcessHeldLastFocus={_focusHelper.ChildProcessHeldLastFocus})");
|
||||
break;
|
||||
}
|
||||
|
||||
_focusHelper.MainWindowFocused = true;
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.DebugMsg, $"mRemoteNG main window received focus (_childProcessHeldLastFocus={_focusHelper.ChildProcessHeldLastFocus})");
|
||||
|
||||
//var candidateTabToFocus = FromChildHandle(NativeMethods.WindowFromPoint(MousePosition))
|
||||
// ?? GetChildAtPoint(MousePosition);
|
||||
//if (candidateTabToFocus is InterfaceControl)
|
||||
//{
|
||||
// candidateTabToFocus.Parent.Focus();
|
||||
//}
|
||||
|
||||
break;
|
||||
case NativeMethods.WM_ACTIVATE:
|
||||
if (NativeMethods.LOWORD(m.WParam) == NativeMethods.WA_ACTIVE)
|
||||
@@ -554,50 +511,28 @@ namespace mRemoteNG.UI.Forms
|
||||
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.DebugMsg, $"Click activate: {controlThatWasClicked}");
|
||||
|
||||
if (controlThatWasClicked is TreeView ||
|
||||
controlThatWasClicked is ComboBox ||
|
||||
controlThatWasClicked is TextBox ||
|
||||
controlThatWasClicked is FrmMain ||
|
||||
controlThatWasClicked is AutoHideStripBase)
|
||||
{
|
||||
controlThatWasClicked.Focus();
|
||||
}
|
||||
else if (controlThatWasClicked.CanSelect ||
|
||||
controlThatWasClicked is MenuStrip ||
|
||||
controlThatWasClicked is ToolStrip)
|
||||
{
|
||||
// Simulate a mouse event since one wasn't generated by Windows
|
||||
SimulateClick(controlThatWasClicked);
|
||||
controlThatWasClicked.Focus();
|
||||
}
|
||||
//if (controlThatWasClicked is TreeView ||
|
||||
// controlThatWasClicked is ComboBox ||
|
||||
// controlThatWasClicked is TextBox ||
|
||||
// controlThatWasClicked is FrmMain ||
|
||||
// controlThatWasClicked is AutoHideStripBase)
|
||||
//{
|
||||
// controlThatWasClicked.Focus();
|
||||
//}
|
||||
//else if (controlThatWasClicked.CanSelect ||
|
||||
// controlThatWasClicked is MenuStrip ||
|
||||
// controlThatWasClicked is ToolStrip)
|
||||
//{
|
||||
// // Simulate a mouse event since one wasn't generated by Windows
|
||||
// SimulateClick(controlThatWasClicked);
|
||||
// controlThatWasClicked.Focus();
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// // This handles activations from clicks that did not start a size/move operation
|
||||
// ActivateConnection();
|
||||
//}
|
||||
|
||||
break;
|
||||
case NativeMethods.WM_NCACTIVATE:
|
||||
//// Never allow the mRemoteNG window to display itself as inactive. By doing this,
|
||||
//// we ensure focus events can propagate to child connection windows
|
||||
NativeMethods.DefWindowProc(Handle, Convert.ToUInt32(m.Msg), (IntPtr)1, m.LParam);
|
||||
m.Result = (IntPtr)1;
|
||||
return;
|
||||
case NativeMethods.WM_WINDOWPOSCHANGED:
|
||||
// Ignore this message if the window wasn't activated
|
||||
if (!_inMouseActivate)
|
||||
break;
|
||||
|
||||
var windowPos = (NativeMethods.WINDOWPOS)Marshal.PtrToStructure(m.LParam, typeof(NativeMethods.WINDOWPOS));
|
||||
if ((windowPos.flags & NativeMethods.SWP_NOACTIVATE) == 0)
|
||||
{
|
||||
if (!_inMouseActivate && !_inSizeMove)
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.DebugMsg, "WM_WINDOWPOSCHANGED DONE");
|
||||
_focusHelper.ActivateConnection();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case NativeMethods.WM_SYSCOMMAND:
|
||||
var screen = _screenSystemMenu.GetScreenById(m.WParam.ToInt32());
|
||||
|
||||
Reference in New Issue
Block a user