From 9153967bfb0f30d46040cdbaf4fbb3fc89f2158d Mon Sep 17 00:00:00 2001 From: Nicola Carminati Date: Wed, 28 Mar 2018 12:04:22 +0200 Subject: [PATCH] Fix Hotkey functions --- Client/View/MainForm.cs | 112 +++++++++++++++++++--------------------- Client/View/NcWindow.cs | 76 ++++++++++++++++++++++++++- 2 files changed, 128 insertions(+), 60 deletions(-) diff --git a/Client/View/MainForm.cs b/Client/View/MainForm.cs index 3110192f..3375f49d 100644 --- a/Client/View/MainForm.cs +++ b/Client/View/MainForm.cs @@ -33,7 +33,6 @@ namespace CMS_Client.View private static IntPtr MainHandle; private static IntPtr NcHandle; private int X = 0, Y = 0; - private bool CntrlPressed; private string BrokenUrl; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -62,12 +61,14 @@ namespace CMS_Client.View //Initialize the Nc-Form InitializeNcForm(); - + //Load the page Browser.LoadUrl(Config.ConnectionConfig.StartingUrl); //Set the title of the window in "Loading" SetWindowTitle("Loading..."); ShowLoading("Loading Main View..."); + + NcWindow.mainFrm = this; } @@ -82,7 +83,7 @@ namespace CMS_Client.View //On Resize Form private void MainForm_Resize(object sender, EventArgs e) - { + { if (this.WindowState == FormWindowState.Minimized) { NcWindow.ShowTaskBar(); @@ -95,7 +96,7 @@ namespace CMS_Client.View if (Config.VendorHmiConfig.Enabled) NcFrm.Show(); } - + //Refresh Browser Paint Browser.Refresh(); this.Refresh(); @@ -181,9 +182,9 @@ namespace CMS_Client.View Browser.DisplayHandler.OnConsoleMessage += BrowserConsoleMessage; //Filter only < Win_10 Platform if (Config.ClientConfig.ShowVirtualKeyboard && Environment.OSVersion.Version.Major < 10) - ChromiumWebBrowser.RemoteProcessCreated += (e) =>{e.RenderProcessHandler.OnFocusedNodeChanged += BrowserNodeChanged;}; + ChromiumWebBrowser.RemoteProcessCreated += (e) => { e.RenderProcessHandler.OnFocusedNodeChanged += BrowserNodeChanged; }; } - + #endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -195,7 +196,7 @@ namespace CMS_Client.View //Set the Load-Error global variable to TRUE LoadingError.Error = true; LoadingError.ErrorInfo = e.ErrorCode.GetHashCode() + " - " + e.ErrorText; - if(e.FailedUrl != Constants.errorPageUrl) + if (e.FailedUrl != Constants.errorPageUrl) this.BrokenUrl = e.FailedUrl; //write the error in the Title Bar @@ -203,7 +204,7 @@ namespace CMS_Client.View } - + //On browser Load-Changed. Event Handler called by Browser private void BrowserLoadsChanged(object sender, CfxOnLoadingStateChangeEventArgs e) { @@ -255,53 +256,13 @@ namespace CMS_Client.View // on Key-Press Browser private void BrowserKeyPress(object sender, CfxOnKeyEventEventArgs e) { - //Save the Control-Key pressed - if (e.Event.Type == CfxKeyEventType.RawKeydown && e.Event.WindowsKeyCode == (int)Keys.ControlKey) - CntrlPressed = true; - else if (e.Event.Type == CfxKeyEventType.Keyup && e.Event.WindowsKeyCode == (int)Keys.ControlKey) - CntrlPressed = false; - //If is a Key Up do an action - if (e.Event.Type == CfxKeyEventType.Keyup) - { - //Work only if is a Developer mode - if (Config.ClientConfig.DeveloperMode) - { - if (e.Event.WindowsKeyCode == (int)Keys.F1) - Browser.GoBack(); - - if (e.Event.WindowsKeyCode == (int)Keys.F2) - Browser.GoForward(); - - if (e.Event.WindowsKeyCode == (int)Keys.F5) - { - if (Browser.Url.AbsoluteUri != Constants.errorPageUrl) - Browser.Browser.ReloadIgnoreCache(); - else - Browser.LoadUrl(this.BrokenUrl); - } - - if (e.Event.WindowsKeyCode == (int)Keys.F10) - ShowChromeVersion(); - - if (e.Event.WindowsKeyCode == (int)Keys.F11) - ShowChromeGPU(); - - if (e.Event.WindowsKeyCode == (int)Keys.F12) - ShowDevTools(); - } - - //Work everytime - if (CntrlPressed && e.Event.WindowsKeyCode == (int)Keys.R) - Browser.Browser.ReloadIgnoreCache(); - } - - } + } //Show Dev Tools Window - private void ShowDevTools(){ + private void ShowDevTools() { //Setup Dev Window CfxWindowInfo windowInfo = new CfxWindowInfo(); windowInfo.Style = (WindowStyle.WS_OVERLAPPEDWINDOW | WindowStyle.WS_POPUP | WindowStyle.WS_CLIPCHILDREN | WindowStyle.WS_CLIPSIBLINGS | WindowStyle.WS_VISIBLE); @@ -310,7 +271,7 @@ namespace CMS_Client.View windowInfo.X = 1120; windowInfo.Y = 0; windowInfo.Width = 800; - windowInfo.Height = 1080; + windowInfo.Height = 1080; //Show Dev Window Browser.BrowserHost.ShowDevTools(windowInfo, new CfxClient(), new CfxBrowserSettings(), null); @@ -321,7 +282,7 @@ namespace CMS_Client.View //Show Chrome GPU Window private void ShowChromeGPU() { - int w=1600, h=800; + int w = 1600, h = 800; //Setup Window CfxWindowInfo windowInfo = new CfxWindowInfo(); @@ -387,7 +348,7 @@ namespace CMS_Client.View //Filter if the node Type is TEXT or PASSWORD if (dom != null && (dom.Equals("text") || dom.Equals("password"))) - NcWindow.openVirtualKeyboard(ev.Node.ElementBounds,ev.Browser.Identifier > 1, false); + NcWindow.openVirtualKeyboard(ev.Node.ElementBounds, ev.Browser.Identifier > 1, false); } //Filter if this node is TEXTAREA Node else if (NodeName != null && NodeName.Equals("textarea")) @@ -414,7 +375,7 @@ namespace CMS_Client.View if (this.InvokeRequired) this.Invoke((MethodInvoker)delegate () { - if(!String.IsNullOrWhiteSpace(this.BrokenUrl)) + if (!String.IsNullOrWhiteSpace(this.BrokenUrl)) Browser.LoadUrl(this.BrokenUrl); }); else @@ -545,7 +506,7 @@ namespace CMS_Client.View return; //Invoke method if is needed or call the method in STD mode - if(!this.IsDisposed) + if (!this.IsDisposed) { if (this.InvokeRequired) this.Invoke((MethodInvoker)delegate () { @@ -569,7 +530,7 @@ namespace CMS_Client.View } } } - + } @@ -586,7 +547,7 @@ namespace CMS_Client.View if (this.InvokeRequired) this.Invoke((MethodInvoker)delegate () { - if(this.NcFrm.Owner != null) + if (this.NcFrm.Owner != null) { this.NcFrm.Owner = null; this.TopMost = true; @@ -606,6 +567,7 @@ namespace CMS_Client.View } } + //CAlculate Window Position private void CalcWindowPosition() { @@ -615,10 +577,44 @@ namespace CMS_Client.View Screen ps = Screen.AllScreens.FirstOrDefault(S => S.Primary == true); Screen ss = Screen.AllScreens.FirstOrDefault(S => S.Primary == false); X = ps.Bounds.Width; - if(ss.Bounds.Top != 0) + if (ss.Bounds.Top != 0) Y = ss.Bounds.Top; } } + + + //Windows Keys Handler + public void keyPressedHandler(bool altPressed, bool ctrlPressed, bool shiftPressed, int key) + { + //Work only if is a Developer mode + if (Config.ClientConfig.DeveloperMode) + { + if (key == (int)Keys.F1) + Browser.GoBack(); + + if (key == (int)Keys.F2) + Browser.GoForward(); + + if (key == (int)Keys.F5) + { + if (Browser.Url.AbsoluteUri != Constants.errorPageUrl) + Browser.Browser.ReloadIgnoreCache(); + else + Browser.LoadUrl(this.BrokenUrl); + } + + if (key == (int)Keys.F10) + ShowChromeVersion(); + + if (key == (int)Keys.F11) + ShowChromeGPU(); + + if (key == (int)Keys.F12) + ShowDevTools(); + } + } + + #endregion } } diff --git a/Client/View/NcWindow.cs b/Client/View/NcWindow.cs index 25a9d979..250c4b70 100644 --- a/Client/View/NcWindow.cs +++ b/Client/View/NcWindow.cs @@ -56,6 +56,7 @@ namespace CMS_Client.View private static int LastX, LastY; private static int LastWidth = 1024, LastHeight = 768; private static IntPtr hhook; + private static IntPtr keybhook; private static IntPtr MainViewHandle; private static IntPtr TaskBarHandle; private static IntPtr StartBtnHandle; @@ -63,6 +64,7 @@ namespace CMS_Client.View private static uint NcProcessPID; private static uint ActualPID; private static WinEventDelegate procDelegate; + private static keyboardHookProc keybDelegate; private static uint LastdwmsEventTime; private static uint LastHookedPID; private static uint KeyboardPID; @@ -83,6 +85,11 @@ namespace CMS_Client.View private static int ncWindowHeight; private static int ncWindowX; private static int ncWindowY; + private static bool altPressed; + private static bool ctrlPressed; + private static bool shiftPressed; + private static uint KeybPID; + public static MainForm mainFrm; public static NcState State { get { return state; } } private static NcState state; @@ -390,6 +397,12 @@ namespace CMS_Client.View //Resize the Window ResizeAndMoveNcWindow(ncWindowX, ncWindowY, ncWindowWidth, ncWindowHeight); + //Start Keyboard Hook + if (keybhook != IntPtr.Zero) + UnhookWindowsHookEx(keybhook); + keybDelegate = new keyboardHookProc(KeybEventProc); + keybhook = SetWindowsHookEx(WH_KEYBOARD_LL, keybDelegate, IntPtr.Zero, 0); + //Start the Hook if (MainViewHandle != IntPtr.Zero && ncprocess.MainWindowHandle != IntPtr.Zero && MainProcessPID != 0 && NcProcessPID != 0 && windowstarted) { @@ -400,6 +413,7 @@ namespace CMS_Client.View //Attach the new hook procDelegate = new WinEventDelegate(WinEventProc); hhook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, IntPtr.Zero, procDelegate, 0, 0, WINEVENT_OUTOFCONTEXT); + FollowingFocus = true; //Start the new Thread of Image Captutre - in Standby (NICOLA CARMINATI 25/01/2018) @@ -436,6 +450,8 @@ namespace CMS_Client.View UnhookWinEvent(hhook); FollowingFocus = false; } + if (keybhook != IntPtr.Zero) + UnhookWindowsHookEx(keybhook); //Stop the Image-Capture Thread if (CaptureThread != null) @@ -678,7 +694,6 @@ namespace CMS_Client.View //Following Nc Window Method private static void WinEventProc(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime) { - //Read the actual ID of the Process GetWindowThreadProcessId(hwnd, out ActualPID); @@ -724,7 +739,47 @@ namespace CMS_Client.View LastdwmsEventTime = dwmsEventTime; } + + //Hook Keyboard Handle + private static void KeybEventProc(int nCode, IntPtr wParam, IntPtr lParam) + { + int Key = Marshal.ReadInt32(lParam); + + //Elaborate Hotkey + if (wParam == HWND_KEYDOWN || wParam == HWND_SYSKEYDOWN) + { + if (Key == 0xA4 || Key == 0xA5) + altPressed = true; + if (Key == 0xA2 || Key == 0xA3) + ctrlPressed = true; + if (Key == 0xA0 || Key == 0xA1) + shiftPressed = true; + } + if (wParam == HWND_KEYUP || wParam == HWND_SYSKEYUP) + { + if (Key == 0xA4 || Key == 0xA5) + altPressed = false; + if (Key == 0xA2 || Key == 0xA3) + ctrlPressed = false; + if (Key == 0xA0 || Key == 0xA1) + shiftPressed = false; + } + + //Read the actual ID of the Process + GetWindowThreadProcessId(GetForegroundWindow(), out KeybPID); + + //Filter the PID + if (KeybPID == MainProcessPID || KeybPID == NcProcessPID) + { + //Filter if is keydown + if (wParam == HWND_KEYUP) + mainFrm.keyPressedHandler(altPressed, ctrlPressed, shiftPressed, Key); + } + + //Call Newx System Hook + CallNextHookEx(keybhook, nCode, wParam, lParam); + } #endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1095,10 +1150,15 @@ namespace CMS_Client.View private const int WS_SYSMENU = 0x00080000; private const uint WS_POPUP = 0x80000000; private const int WS_MAXIMIZE = 0x01000000; + private const int WH_KEYBOARD_LL = 13; static readonly IntPtr HWND_BOTTOM = new IntPtr(1); static readonly IntPtr HWND_TOP = new IntPtr(0); static readonly IntPtr HWND_TOPMOST = new IntPtr(-1); static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2); + static readonly IntPtr HWND_KEYDOWN = new IntPtr(0x100); + static readonly IntPtr HWND_SYSKEYDOWN = new IntPtr(0x104); + static readonly IntPtr HWND_KEYUP = new IntPtr(0x101); + static readonly IntPtr HWND_SYSKEYUP = new IntPtr(0x105); [DllImport("user32.dll")] public static extern int DeleteMenu(IntPtr hMenu, int nPosition, int wFlags); @@ -1163,6 +1223,18 @@ namespace CMS_Client.View [return: MarshalAs(UnmanagedType.Bool)] static extern bool UnhookWinEvent(IntPtr hWinEventHook); + [DllImport("user32.dll")] + static extern IntPtr SetWindowsHookEx(int idHook, keyboardHookProc callback, IntPtr hInstance, uint threadId); + delegate void keyboardHookProc(int nCode, IntPtr wParam, IntPtr lParam); + + [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] + + private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam); + + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + static extern bool UnhookWindowsHookEx(IntPtr idHook); + [DllImport("user32.dll", SetLastError = true)] static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId); @@ -1221,7 +1293,7 @@ namespace CMS_Client.View CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)] private static extern int GetMenuItemCount(IntPtr hMenu); - + [StructLayout(LayoutKind.Sequential)] public struct RECT