diff --git a/Client.Utils/Constants.cs b/Client.Utils/Constants.cs index f1668ea7..d63732eb 100644 --- a/Client.Utils/Constants.cs +++ b/Client.Utils/Constants.cs @@ -45,10 +45,12 @@ namespace Client.Utils public const int HMI_WINDOW_WIDTH = 1024; public const int HMI_WINDOW_HEIGHT = 768; - //KEYBOARD Size & Position + //KEYBOARD Constants public const int KEYB_HEIGHT = 377; public const int KEYB_WIDTH = 1134; public const int KEYB_Y_OFFSET = 15; + public const string KEYB_EXE_NAME = "OSK.EXE"; + public const string KEYB_PROC_NAME = "OSK"; public const string StartingPage = "index.html"; public const string ConfigPage = "api/configuration/client"; diff --git a/Client/Browser_Tools/BrowserJSObject.cs b/Client/Browser_Tools/BrowserJSObject.cs index f2d5325e..e5e53f80 100644 --- a/Client/Browser_Tools/BrowserJSObject.cs +++ b/Client/Browser_Tools/BrowserJSObject.cs @@ -46,6 +46,7 @@ namespace CMS_Client.Browser_Tools AddFunction("getConfiguredProcesses").Execute += getConfiguredProcesses; AddFunction("startNewProcess").Execute += startNewProcess; AddFunction("openOrStartProcess").Execute += openOrStartProcess; + AddFunction("isVirtualKeybConfigured").Execute += isVirtualKeybConfigured; } @@ -156,6 +157,11 @@ namespace CMS_Client.Browser_Tools NcWindow.ForceStepFocus(); } + //Get the option of virtual Keyb configured + private void isVirtualKeybConfigured(object sender, CfrV8HandlerExecuteEventArgs e) + { + e.SetReturnValue((Boolean)Config.ClientConfig.ShowVirtualKeyboard); + } #endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Client/Client.csproj b/Client/Client.csproj index 3e3f5395..e1b876d6 100644 --- a/Client/Client.csproj +++ b/Client/Client.csproj @@ -254,6 +254,9 @@ + + + diff --git a/Client/View/MainForm.cs b/Client/View/MainForm.cs index 88068e36..f62f7fd3 100644 --- a/Client/View/MainForm.cs +++ b/Client/View/MainForm.cs @@ -64,7 +64,6 @@ namespace CMS_Client.View //Setup Wait Cursor Cursor.Current = Cursors.WaitCursor; - //Start following NC Window if (Config.VendorHmiConfig.Enabled) NcWindow.StartNcFollowing(MainHandle, NcHandle, NcFrm.Width, NcFrm.Height); @@ -73,7 +72,6 @@ namespace CMS_Client.View //Load the page Browser.LoadUrl(Config.ConnectionConfig.StartingUrl); - //Set the title of the window in "Loading" SetWindowTitle("Loading..."); ShowLoading("Loading Main View..."); @@ -117,16 +115,23 @@ namespace CMS_Client.View { //Invoke method if is needed or call the method in STD mode if (!this.IsDisposed) - { - //Close the NC HMI && Stop Following Nc - if (Config.VendorHmiConfig.Enabled) - { - NcWindow.CloseNcWindow(); - } - + { + //Show Taskbar NcWindow.ShowTaskBar(); + + //Hide Window this.Hide(); + //Close Virtual Keyboard Runtime + if (Config.ClientConfig.ShowVirtualKeyboard && Environment.OSVersion.Version.Major < 10) + NcWindow.closeVirtualKeyboard(); + + //Close the NC HMI && Stop Following Nc + if (Config.VendorHmiConfig.Enabled) + NcWindow.CloseNcWindow(); + + + //Close Chromium Runtime CfxRuntime.Shutdown(); } @@ -181,9 +186,8 @@ namespace CMS_Client.View Browser.KeyboardHandler.OnKeyEvent += BrowserKeyPress; Browser.ContextMenuHandler.OnBeforeContextMenu += BrowserContextMenu; Browser.DisplayHandler.OnConsoleMessage += BrowserConsoleMessage; - //Filter only < Win_10 Platform - if(Config.ClientConfig.ShowVirtualKeyboard && Environment.OSVersion.Version.Major < 10) + if (Config.ClientConfig.ShowVirtualKeyboard && Environment.OSVersion.Version.Major < 10) ChromiumWebBrowser.RemoteProcessCreated += (e) =>{e.RenderProcessHandler.OnFocusedNodeChanged += BrowserNodeChanged;}; } @@ -372,17 +376,27 @@ namespace CMS_Client.View //Node Changed Handler private void BrowserNodeChanged(object sender, CfrOnFocusedNodeChangedEventArgs ev) { - //Filter if this node is an INPUT Node - if (ev.Node != null && ev.Node.ElementTagName.ToLower().Equals("input")) + if (ev.Node != null) { - String dom = ev.Node.GetElementAttribute("type").ToLower(); + String NodeName = ev.Node.ElementTagName.ToLower(); + //Filter if this node is an INPUT Node + if (NodeName != null && NodeName.Equals("input")) + { + String dom = ev.Node.GetElementAttribute("type").ToLower(); - //Filter if the node Type is TEXT or PASSWORD - if (dom != null && (dom.Equals("text") || dom.Equals("password"))) - openVirtualKeyboard(ev.Node.ElementBounds); + //Filter if the node Type is TEXT or PASSWORD + if (dom != null && (dom.Equals("text") || dom.Equals("password"))) + NcWindow.openVirtualKeyboard(ev.Node.ElementBounds, false); + } + //Filter if this node is TEXTAREA Node + else if (NodeName != null && NodeName.Equals("textarea")) + NcWindow.openVirtualKeyboard(ev.Node.ElementBounds, false); + else + NcWindow.hideVirtualKeyboard(); } else - closeVirtualKeyboard(); + NcWindow.hideVirtualKeyboard(); + } #endregion @@ -562,54 +576,5 @@ namespace CMS_Client.View } } #endregion - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - #region KEYBOARD_METHODS - - void openVirtualKeyboard(CfrRect LastPoint) - { - Process process = new Process(); - process.StartInfo.FileName = "OSK.EXE"; - - //Open & Find Keyboard - Process [] processes = Process.GetProcessesByName("OSK"); - if (processes.Count() == 0) - { - process.Start(); - do{processes = Process.GetProcessesByName("OSK");} - while (processes.Count() == 0 || processes[0].MainWindowHandle == IntPtr.Zero); - process = processes[0]; - } - else - process = processes[0]; - - // Setup position - int keybX = LastPoint.X + (LastPoint.Width / 2) - (Constants.KEYB_WIDTH / 2); - int keybY = LastPoint.Y + LastPoint.Height + Constants.KEYB_Y_OFFSET; - - //Screen Overflow Y - if ((keybY + Constants.KEYB_HEIGHT) > Screen.PrimaryScreen.Bounds.Height) - keybY = LastPoint.Y - Constants.KEYB_Y_OFFSET - Constants.KEYB_HEIGHT; - - //Screen Overflow X - if (keybX < 0) - keybX = 0; - if (keybX + Constants.KEYB_WIDTH > Screen.PrimaryScreen.Bounds.Width) - keybX = Screen.PrimaryScreen.Bounds.Width - Constants.KEYB_WIDTH; - - //Move Window - NcWindow.MoveWindow(process.MainWindowHandle, keybX, keybY, Constants.KEYB_WIDTH, Constants.KEYB_HEIGHT,true); - - - } - - - void closeVirtualKeyboard() - { - Process[] processes = Process.GetProcessesByName("OSK"); - if (processes.Count() > 0) - processes[0].Kill(); - } - #endregion } } diff --git a/Client/View/NcWindow.cs b/Client/View/NcWindow.cs index c7f19fc1..587ed3c4 100644 --- a/Client/View/NcWindow.cs +++ b/Client/View/NcWindow.cs @@ -1,4 +1,5 @@ -using Client.Config; +using Chromium.Remote; +using Client.Config; using Client.Utils; using CMS_Client.Properties; using System; @@ -63,9 +64,15 @@ namespace CMS_Client.View private static WinEventDelegate procDelegate; private static uint LastdwmsEventTime; private static uint LastHookedPID; + private static uint KeyboardPID; private static int TriedTimes; private static bool ProcKilled; private static bool IsNcSiemens; + private static bool KeyboardVisible; + private static IntPtr KeyboardHandle; + private static CfrRect LastKeybPoint; + private static Point LastKeybPosition; + private static Point LastKeybPositionReopen; private static IntPtr ActualHND; private static IntPtr LastHookedHND; @@ -426,6 +433,220 @@ namespace CMS_Client.View #endregion + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + #region PUBLIC_KEYBOARD_METHODS + + //Show virtual Keyboard in last position + public static void reOpenVirtualKeyboard() + { + Task.Run(() => { + Thread.Sleep(100); + if (KeyboardVisible && LastKeybPoint != null && !IsWindowVisible(KeyboardHandle)) + openVirtualKeyboard(LastKeybPoint,true); + }); + } + + + + //Open/Show virtual Keyboard + public static void openVirtualKeyboard(CfrRect LastPoint, Boolean forcedLastPosition) + { + //Save last Point + LastKeybPoint = LastPoint; + + //Elaborate the Keyboard position + Point Position = ElaborateKeyboardPosition(LastPoint, forcedLastPosition); + + //Run in a Task (Don't stop Browser UI) + Task.Run(() => { + + //Open & Find Keyboard + Process[] processes = Process.GetProcessesByName(KEYB_PROC_NAME); + if (processes.Length == 0) + { + //If i don't find the Keyboard -> Start it! + launchProcessKeyboard(); + + //Delete Menu buttons + deleteMenuKeyboard(KeyboardHandle); + + //Move Window + NcWindow.MoveWindow(KeyboardHandle, Position.X, Position.Y, Constants.KEYB_WIDTH, Constants.KEYB_HEIGHT, true); + } + else + { + + //Try to show window + if (KeyboardHandle != IntPtr.Zero) + { + //Move Window + NcWindow.MoveWindow(KeyboardHandle, Position.X, Position.Y, Constants.KEYB_WIDTH, Constants.KEYB_HEIGHT, true); + + //Delete Menu buttons + deleteMenuKeyboard(KeyboardHandle); + + //Try to show window + ShowWindow(KeyboardHandle, SW_SHOWNOACTIVATE); + } + + //Check if window is visible + if (KeyboardHandle == IntPtr.Zero || !IsWindowVisible(KeyboardHandle) ) + { + //Kill actual process + closeVirtualKeyboard(); + + //Start a new one! + launchProcessKeyboard(); + + //Delete Menu buttons + deleteMenuKeyboard(KeyboardHandle); + + //Move Window + NcWindow.MoveWindow(KeyboardHandle, Position.X, Position.Y, Constants.KEYB_WIDTH, Constants.KEYB_HEIGHT, true); + } + } + + // Save PID + GetWindowThreadProcessId(KeyboardHandle, out KeyboardPID); + + //Setup variable "Keyboard visible" + KeyboardVisible = true; + + }); + } + + + + //Close virtual Keyboard + public static void closeVirtualKeyboard() + { + Process[] processes = Process.GetProcessesByName(KEYB_PROC_NAME); + RECT KeybRct = new RECT(); + + //Save last position + if (KeyboardHandle != IntPtr.Zero) + { + GetWindowRect(KeyboardHandle, out KeybRct); + LastKeybPositionReopen = new Point() { X = KeybRct.Left, Y = KeybRct.Top }; + } + + for (int i = 0; i < processes.Length; i++) + processes[i].Kill(); + + KeyboardPID = 0; + KeyboardHandle = IntPtr.Zero; + + } + + + + //Hide virtual keyboard + public static void hideVirtualKeyboard() + { + if (KeyboardHandle != IntPtr.Zero) + ShowWindow(KeyboardHandle, WS_HIDE); + + //Setup variable "Keyboard visible" + KeyboardVisible = false; + LastKeybPosition.X = -1; + LastKeybPosition.Y = -1; + } + + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //Private Methods + + //Elaborates Keyboard position + private static Point ElaborateKeyboardPosition(CfrRect ObjectPoint, Boolean forcedLastPosition) + { + int keybX = 0, keybY = 0; + RECT KeybRct = new RECT(); + + //Find the window position + if (KeyboardHandle != IntPtr.Zero) + GetWindowRect(KeyboardHandle, out KeybRct); + + //If i moved manually the Keyboard -> let where it is, until becomes hide + if (!forcedLastPosition && (KeyboardHandle != IntPtr.Zero && (LastKeybPosition.X != -1 && LastKeybPosition.Y != -1) && (KeybRct.Left != LastKeybPosition.X || KeybRct.Top != LastKeybPosition.Y))) + return new Point() { X = KeybRct.Left, Y = KeybRct.Top }; + + //If have to re-open, move at the point where was before close + else if (forcedLastPosition && LastKeybPositionReopen.X != -1 && LastKeybPositionReopen.Y != -1) + return new Point() { X = LastKeybPositionReopen.X, Y = LastKeybPositionReopen.Y }; + + //In all others calc the position from HTML Node changed + else + { + // + + //Setup position Y + /* + * 1) try to put the keyboard below the html object. If there's not enough space (2) + * 2) try to put above the html object. If there's not enough space yet (3) + * 3) put close to the bottom edge of the screen + */ + keybY = ObjectPoint.Y + ObjectPoint.Height + Constants.KEYB_Y_OFFSET; + if ((keybY + Constants.KEYB_HEIGHT) > Screen.PrimaryScreen.Bounds.Height) + keybY = ObjectPoint.Y - Constants.KEYB_Y_OFFSET - Constants.KEYB_HEIGHT; + if (keybY < 0) + keybY = Screen.PrimaryScreen.Bounds.Height - Constants.KEYB_HEIGHT; + + + //Setup position X + /* + * 1) try to put the keyboard in the middle the html object. If is out of the screen at Left Border (2), at Right Border (3) + * 2) put close to the left edge of the screen + * 3) put close to the right edge of the screen + */ + keybX = ObjectPoint.X + (ObjectPoint.Width / 2) - (Constants.KEYB_WIDTH / 2); + if (keybX < 0) + keybX = 0; + if (keybX + Constants.KEYB_WIDTH > Screen.PrimaryScreen.Bounds.Width) + keybX = Screen.PrimaryScreen.Bounds.Width - Constants.KEYB_WIDTH; + + //Setup the Final Position + LastKeybPosition = new Point() { X = keybX, Y = keybY }; + return LastKeybPosition; + } + + } + + + + //Delete Menu Action of a window + private static void deleteMenuKeyboard(IntPtr Handle) + { + // NO Control-Box + NO resize window + SetWindowLong(Handle, GWL_STYLE, (GetWindowLong(Handle, GWL_STYLE) & ~0x80000 & ~0x40000)); + + } + + + + //Launch new Process OSK + private static void launchProcessKeyboard() + { + Process[] processes = Process.GetProcessesByName(KEYB_PROC_NAME); + Process process = new Process(); + process.StartInfo.FileName = KEYB_EXE_NAME; + process.Start(); + int times = 0; + + //Find the New Window Handle + do { processes = Process.GetProcessesByName(KEYB_PROC_NAME); Thread.Sleep(10); times++; } + while ((processes.Length == 0 || processes[0].MainWindowHandle == IntPtr.Zero) && times < 20); + + //Filter if i can't find the window + if (times == 20) + { + KeyboardHandle = IntPtr.Zero; + return; + } + + //Set the window Handle Parameter + KeyboardHandle = processes[0].MainWindowHandle; + } + #endregion + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #region WINDOWS_EVENT_OVERRIDE @@ -441,9 +662,15 @@ namespace CMS_Client.View //If the PID is the STEP-HMI Process if (ActualPID == MainProcessPID) { - //Hide the TaskBar if (!IsIconic(MainViewHandle)) + { + //Hide the TaskBar HideTaskBar(); + + //Show Virtual keyboard + if (Config.ClientConfig.ShowVirtualKeyboard && Environment.OSVersion.Version.Major < 10) + reOpenVirtualKeyboard(); + } } //If the PID is the NC-HMI Process else if (ActualPID == NcProcessPID) @@ -458,6 +685,10 @@ namespace CMS_Client.View { //Show the TaskBar ShowTaskBar(); + + //Hide Virtual keyboard + if (Config.ClientConfig.ShowVirtualKeyboard && Environment.OSVersion.Version.Major < 10 && KeyboardPID != 0 && ActualPID != KeyboardPID) + closeVirtualKeyboard(); } //Save the Last Hooked PID @@ -806,6 +1037,8 @@ namespace CMS_Client.View private const int SC_CLOSE = 0xF060; private const int SC_MINIMIZE = 0xF020; private const int SC_MAXIMIZE = 0xF030; + private const int HIDE_CLOSE = 0x200; + private const int SC_SIZE = 0xF000; private const int WS_SYSMENU = 0x00080000; private const uint WS_POPUP = 0x80000000; private const int WS_MAXIMIZE = 0x01000000; @@ -856,7 +1089,7 @@ namespace CMS_Client.View [DllImport("user32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.I8)] - private static extern long SetParent(IntPtr hWndChild, IntPtr hWndNewParent); + public static extern long SetParent(IntPtr hWndChild, IntPtr hWndNewParent); [DllImport("user32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.I4)]