using Client.Config; using CMS_Client.Properties; using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.IO; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Windows.Forms; namespace CMS_Client.View { static class NcWindow { //Const value used for open the Process/Application const String FanucPath = @"\CNCScreenE\CNCScrnE.exe"; const String OsaiPath = @"\OSAI\WinNBI\ProVideo.exe"; const String SiemensPath = @"\Siemens\MotionControl\siemens\sinumerik\hmi\autostart\run_hmi.exe"; const String DemoPath = @"\Nc_Demo_Application.exe"; const String FanucName = "CNCScrnE"; const String OsaiName = "provideo"; const String SiemensName = "slsmhmihost"; const String DemoName = "Nc_Demo_Application"; const String Win7TaskBar = "Shell_TrayWnd"; const String Win7StartBtnCL = "Button"; const String Win7StartBtnTxt= "Start"; const String SiemensTool1Name = "run_hmi"; const String SiemensTool2Name = "slsmsystemmanager"; const int WaitingMs = 500; const int TimesToTryKill = 10; const int TimesToTryOpen = 120; // 120 * 500ms = 60000ms => 1min //Public variables public static bool WindowStarted { get { return windowstarted; } } private static bool windowstarted = false; public static String ProcessName { get { return processname; } } private static String processname = ""; public static String ProcessPath { get { return processpath; } } private static String processpath = ""; public static Process NcProcess { get { return ncprocess; } } private static Process ncprocess; private static int LastX, LastY; private static int LastWidth = 1024, LastHeight = 768; private static IntPtr hhook; private static IntPtr MainViewHandle; private static IntPtr TaskBarHandle; private static IntPtr StartBtnHandle; private static IntPtr PopupHandle; private static uint MainProcessPID; private static uint NcProcessPID; private static uint ActualPID; private static WinEventDelegate procDelegate; private static uint LastdwmsEventTime; private static uint LastHookedPID; private static int TriedTimes; private static bool ProcKilled; private static bool IsNcSiemens; private static IntPtr ActualHND; private static IntPtr LastHookedHND; private static IntPtr NcHND; private static Thread FocusTask; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #region PUBLIC_CUSTOM_METHODS // Start/Open the NC Window public static int StartNcWindow() { Process[] processes; int style; //Setup the variables ProcKilled = false; //Set Window Started = false windowstarted = false; //Setup the Path/Name of the process SetupNcProcess(); //Read if exists a Process with correct name processes = Process.GetProcessesByName(processname); //Save the Taskbar Windows Handle TaskBarHandle = FindWindow(Win7TaskBar, ""); StartBtnHandle = FindWindow(Win7StartBtnCL, Win7StartBtnTxt); //Kill tool processes if they had been started whitout HMI (Only Siemens) if (IsNcSiemens && processes.Length <= 0) { //Kill All Windows KillAllProcessWithName(SiemensTool2Name); } //If exists the Process if (processes.Length > 0) { //Set the first founded process ncprocess = processes[0]; ncprocess.WaitForInputIdle(); //Wait until the process is started TriedTimes = 1; while (processes[0].MainWindowHandle == IntPtr.Zero && TriedTimes < TimesToTryKill) { processes = Process.GetProcessesByName(processname); if (processes[0].MainWindowHandle == IntPtr.Zero) { Thread.Sleep(WaitingMs); TriedTimes++; } } //Kill the process if needed if(TriedTimes == TimesToTryKill) { //Kill the Process CloseNcWindow(); //Setup the Variable ProcKilled = true; } } if (processes.Length <= 0 || ProcKilled) { ncprocess = new Process(); // Check if exists the Nc Path if (!File.Exists(processpath)) return 1; //Setup the Process path ncprocess.StartInfo.FileName = processpath; //Start the Process ncprocess.Start(); ncprocess.WaitForInputIdle(); //Wait until the process is started TriedTimes = 1; while ((processes.Length <= 0 || (processes[0].MainWindowHandle == IntPtr.Zero)) && TriedTimes < TimesToTryOpen) { processes = Process.GetProcessesByName(processname); if(processes.Length <= 0 || (processes[0].MainWindowHandle == IntPtr.Zero)) { Thread.Sleep(WaitingMs); TriedTimes++; } } if (TriedTimes == TimesToTryOpen) return 2; //Set the first founded process ncprocess = processes[0]; } //Set Window Started => true windowstarted = true; //Show the Main Window & Hide the Others (Only Siemens) ShowWindow(ncprocess.MainWindowHandle, WS_SHOW); if(IsNcSiemens) { //Wait 500 ms of Siemens software Thread.Sleep(500); //Hide Second Window hideAllProcWindows(SiemensTool1Name); //Hide first Window hideAllProcWindows(SiemensTool2Name); SetNcIcon(Resources.SinumerikHmi); } //Remove the Frame Border style = GetWindowLong(ncprocess.MainWindowHandle, GWL_STYLE); SetWindowLong(ncprocess.MainWindowHandle, GWL_STYLE, (style & ~WS_CAPTION & ~WS_THICKFRAME)); //Resize the Window ResizeAndMoveNcWindow((Screen.PrimaryScreen.Bounds.Width / 2) - (LastWidth / 2), (Screen.PrimaryScreen.Bounds.Height / 2) - (LastHeight / 2), LastWidth, LastHeight); return 0; } //Kill/Close the NC Window public static void CloseNcWindow() { Process[] processes; //Stop Following Nc StopNcFollowing(); //If the NC is Siemens Exit from Function and let the HMI continue his life (To Be validated) if (IsNcSiemens) { HideNcWindow(); return; } //Kill the Process if (ncprocess != null && !ncprocess.HasExited) ncprocess.Kill(); //Read if exists a Process with correct name processes = Process.GetProcessesByName(processname); //Wait until the process is killed TriedTimes = 1; while (processes.Length > 0 && TriedTimes < TimesToTryKill) { processes = Process.GetProcessesByName(processname); if (processes.Length > 0) { Thread.Sleep(WaitingMs); TriedTimes++; } } //Kill Tool Process if (IsNcSiemens) KillAllProcessWithName(SiemensTool2Name); } //Show Nc Window public static void ShowNcWindow() { if (windowstarted) ShowWindow(ncprocess.MainWindowHandle, SW_SHOWNOACTIVATE); } //Hide Nc Window public static void HideNcWindow() { if (windowstarted) ShowWindow(ncprocess.MainWindowHandle, WS_MINIMIZE); } //Show Windows Taskbar public static void ShowTaskBar() { if (windowstarted) { ShowWindow(TaskBarHandle, WS_SHOW); ShowWindow(StartBtnHandle, WS_SHOW); } } //Hide Windows Taskbar public static void HideTaskBar() { if (windowstarted) { ShowWindow(TaskBarHandle, WS_HIDE); ShowWindow(StartBtnHandle, WS_HIDE); } } //Resize NC Window public static void ResizeNcWindow(int width, int height) { LastWidth = width; LastHeight = height; //Win32 Method if (ncprocess != null && windowstarted) { MoveWindow(ncprocess.MainWindowHandle, LastX, LastY, LastWidth, LastHeight, true); } } //Move NC Window public static void MoveNcWindow(int X, int Y) { LastX = X; LastY = Y; //Win32 Method if (ncprocess != null && windowstarted) { MoveWindow(ncprocess.MainWindowHandle, LastX, LastY, LastWidth, LastHeight, true); } } //Resize & Move NC Window public static void ResizeAndMoveNcWindow(int X, int Y, int width, int height) { LastX = X; LastY = Y; LastWidth = width; LastHeight = height; //Win32 Method if (ncprocess != null && windowstarted) { MoveWindow(ncprocess.MainWindowHandle, LastX, LastY, LastWidth, LastHeight, true); } } //Set NC Icon public static void SetNcIcon(Icon icon) { if (windowstarted) SendMessage(ncprocess.MainWindowHandle, WM_SETICON, ICON_BIG, icon.Handle); } //Force NC Focus public static void ForceNcFocus() { if (windowstarted) ForceFocus(ncprocess.MainWindowHandle); } //Force NC Focus public static void ForceStepFocus() { if (MainViewHandle != IntPtr.Zero) ForceFocus(MainViewHandle); } //Start Step Managing public static void StartStepFollowing(IntPtr Handle) { //Setup the Handle-variable MainViewHandle = Handle; } //Start following Nc Window (bring-to-font the main window) public static void StartNcFollowing(IntPtr Handle, IntPtr NcHandle, int Width, int Height) { //Setup the Handle-variable MainViewHandle = Handle; NcHND = NcHandle; //Set the parent of the window SetParent(ncprocess.MainWindowHandle, NcHandle); MoveWindow(ncprocess.MainWindowHandle, LastX, LastY, LastWidth, LastHeight, true); //Get the Process-Id GetWindowThreadProcessId(MainViewHandle, out MainProcessPID); GetWindowThreadProcessId(ncprocess.MainWindowHandle, out NcProcessPID); //Start the Hook if (MainViewHandle != IntPtr.Zero && ncprocess.MainWindowHandle != IntPtr.Zero && MainProcessPID != 0 && NcProcessPID != 0 && windowstarted) { procDelegate = new WinEventDelegate(WinEventProc); hhook = SetWinEventHook(EVENT_OBJECT_FOCUS, EVENT_OBJECT_FOCUS, IntPtr.Zero, procDelegate, 0, 0, WINEVENT_OUTOFCONTEXT); } } //Stop following Nc Window (bring-to-font the main window) -> ONLY FOR OSAI System! public static void StopNcFollowing() { //Un-parent the window SetParent(ncprocess.MainWindowHandle, IntPtr.Zero); //Detach the hook if (hhook != IntPtr.Zero) UnhookWinEvent(hhook); } #endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #region WINDOWS_EVENT_OVERRIDE //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); ActualHND = hwnd; //Filter if comes multiple event at the same time if (ActualHND != LastHookedHND || dwmsEventTime != LastdwmsEventTime) { //If the PID is the STEP-HMI Process if (ActualPID == MainProcessPID) { //Hide the TaskBar HideTaskBar(); //Resize the Popup opened on Nc Window if (ActualPID != LastHookedPID) { //get the Handle of the Popup PopupHandle = GetLastActivePopup(ncprocess.MainWindowHandle); if (PopupHandle != ncprocess.MainWindowHandle) { ResizeOutofBoundWindow(ncprocess.MainWindowHandle, PopupHandle); } } } else if(ActualPID == NcProcessPID) { //Hide the TaskBar HideTaskBar(); //Disable main manu if is present IntPtr Menu = GetSystemMenu(ActualHND, false); if (Menu != IntPtr.Zero) { DeleteMenu(Menu, SC_MINIMIZE, MF_BYCOMMAND); DeleteMenu(Menu, SC_MAXIMIZE, MF_BYCOMMAND); } } //If the PID is OTHER Process else { //Show the TaskBar ShowTaskBar(); } } //Save the Last Hooked PID LastHookedHND = ActualHND; LastHookedPID = ActualPID; //Save the Last TimeStamp LastdwmsEventTime = dwmsEventTime; } #endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #region PRIVATE_CUSTOM_METHODS //Resize out of Bound window private static void ResizeOutofBoundWindow(IntPtr ParentHandle,IntPtr WindowHandle) { RECT MainRct; RECT ParentRct; int width; int height; int width2; int height2; int newX; int newY; bool move = false; bool resize = false; if (GetWindowRect(WindowHandle, out MainRct) && GetWindowRect(ParentHandle, out ParentRct)) { //Setup resize and move variables width = (MainRct.Right - MainRct.Left + 1); height = (MainRct.Bottom - MainRct.Top + 1); width2 = (ParentRct.Right - ParentRct.Left + 1); height2 = (ParentRct.Bottom - ParentRct.Top + 1); newX = width2 / 2 - width / 2 + ParentRct.Left; newY = height2 / 2 - height / 2 + ParentRct.Top; //Check if i need to resize if (width > width2 || height > height2) resize = true; //Check if i need to move if (MainRct.Left < ParentRct.Left || MainRct.Top < ParentRct.Top || MainRct.Right > ParentRct.Right || MainRct.Bottom > ParentRct.Bottom) move = true; //Move or Resize the Window if (move & !resize) MoveWindow(WindowHandle, newX, newY, width, height, true); else if (resize) MoveWindow(WindowHandle, ParentRct.Left, ParentRct.Top, LastWidth, LastHeight, true); } } //Setup the Path/Name of the process Method private static void SetupNcProcess() { IsNcSiemens = false; switch (Config.VendorHmiConfig.Type) { // 0: Demo case 0: { processname = DemoName; processpath = @"C:\CMS\STEP\DEMO" + DemoPath; };break; // 1: Fanuc case 1: { processname = FanucName; processpath = getProgramFilesx86Path() + FanucPath; }; break; // 2: Siemens case 2: { IsNcSiemens = true; processname = SiemensName; processpath = getProgramFilesx86Path() + SiemensPath; }; break; // 3: Osai case 3: { processname = OsaiName; processpath = getProgramFilesx86Path() + OsaiPath; }; break; } } //Get X86 Program folder private static string getProgramFilesx86Path() { if (8 == IntPtr.Size || (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("PROCESSOR_ARCHITEW6432")))) { return Environment.GetEnvironmentVariable("ProgramFiles(x86)"); } return Environment.GetEnvironmentVariable("ProgramFiles"); } //Hide All windows Process private static void hideAllProcWindows(String ProcessName) { Process [] processes = Process.GetProcessesByName(ProcessName); foreach(Process proc in processes) { if(proc.MainWindowHandle != IntPtr.Zero) ShowWindow(proc.MainWindowHandle, WS_HIDE); } } //Kill All Process Name private static void KillAllProcessWithName(String ProcessName) { Process[] procTool = Process.GetProcessesByName(ProcessName); foreach (Process proc in procTool) { proc.Kill(); //Read if exists a Process with correct name procTool = Process.GetProcessesByName(proc.ProcessName); //Wait until the process is killed TriedTimes = 1; while (procTool.Length > 0 && TriedTimes < TimesToTryKill) { procTool = Process.GetProcessesByName(processname); if (procTool.Length > 0) { Thread.Sleep(500); TriedTimes++; } } } } private static void ForceFocus(IntPtr Handle) { //If is not already handled if (GetForegroundWindow() != Handle) { //If is minimized -> Show it if (IsIconic(Handle)) ShowWindow(Handle, SW_SHOWDEFAULT); //Set as foreground SetForegroundWindow(Handle); } } #endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #region WIN32_METHODS private const int GWL_STYLE = -16; private const int GWL_EXSTYLE = -20; private const int LWA_ALPHA = 0x00000002; private const int LWA_COLORKEY = 0x00000001; private const int WS_EX_LAYERED = 0x00080000; private const int WS_EX_TOOLWINDOW = 0x00000080; private const int WS_CHILD = 0x40000000; private const int WS_BORDER = 0x00800000; private const int WS_DLGFRAME = 0x00400000; private const int WS_CAPTION = WS_BORDER | WS_DLGFRAME; private const int WS_THICKFRAME = 262144; private const int WS_HIDE = 0; private const int WS_SHOW = 5; private const int WS_MINIMIZE = 6; private const int WS_SHOWNORMAL = 1; private const int SW_SHOWMAXIMIZED = 3; private const int SW_SHOWDEFAULT = 10; private const int SW_SHOWNOACTIVATE = 4; private const int WM_SETICON = 0x80; private const int ICON_SMALL = 0; private const int ICON_BIG = 1; private const uint EVENT_OBJECT_FOCUS = 0x8005; private const uint WINEVENT_OUTOFCONTEXT= 0; private const UInt32 SWP_NOSIZE = 0x0001; private const UInt32 SWP_NOMOVE = 0x0002; private const UInt32 SWP_NOACTIVATE = 0x0010; private const UInt32 SWP_SHOWWINDOW = 0x0040; private const UInt32 SWP_NOZORDER = 0x0004; private const UInt32 SWP_NOREDRAW = 0x0008; private const UInt32 SWP_HIDEWINDOW = 0x0080; private const int MF_BYCOMMAND = 0x00000000; private const int SC_CLOSE = 0xF060; private const int SC_MINIMIZE = 0xF020; private const int SC_MAXIMIZE = 0xF030; private const int WS_SYSMENU = 0x00080000; private const uint WS_POPUP = 0x80000000; private const int WS_MAXIMIZE = 0x01000000; 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); [DllImport("user32.dll")] public static extern int DeleteMenu(IntPtr hMenu, int nPosition, int wFlags); [DllImport("user32.dll")] private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert); [DllImport("user32.dll", SetLastError = true)] static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, StringBuilder lParam); [DllImport("user32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool MoveWindow(System.IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint); [DllImport("user32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags); [DllImport("USER32.DLL")] [return: MarshalAs(UnmanagedType.I4)] public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); [DllImport("USER32.DLL")] [return: MarshalAs(UnmanagedType.I4)] public static extern int GetWindowLong(IntPtr hWnd, int nIndex); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] static extern bool IsWindowVisible(IntPtr hWnd); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] static extern bool IsIconic(IntPtr hWnd); [DllImport("user32.dll")] static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, IntPtr lParam); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); [DllImport("user32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.I8)] private static extern long SetParent(IntPtr hWndChild, IntPtr hWndNewParent); [DllImport("user32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.I4)] private static extern int IsZoomed(IntPtr hWnd); [DllImport("user32.dll", SetLastError = true)] private static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.I4)] static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count); [DllImport("user32.dll")] static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr hmodWinEventProc, WinEventDelegate lpfnWinEventProc, uint idProcess,uint idThread, uint dwFlags); delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType,IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] static extern bool UnhookWinEvent(IntPtr hWinEventHook); [DllImport("user32.dll", SetLastError = true)] static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId); [DllImport("user32.dll")] private static extern IntPtr FindWindow(string className, string windowText); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] static extern bool SetWindowText(IntPtr hWnd, string text); [DllImport("user32.dll", SetLastError = true)] static extern IntPtr SetFocus(IntPtr hWnd); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] static extern bool SetForegroundWindow(IntPtr hWnd); [DllImport("user32.dll")] static extern IntPtr GetAncestor(IntPtr hWnd, uint uCmd); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags); [DllImport("user32.dll", SetLastError = true)] static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] static extern bool IsWindow(IntPtr hWnd); [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] [return: MarshalAs(UnmanagedType.I4)] static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); [DllImport("user32.dll")] static extern IntPtr GetLastActivePopup(IntPtr hWnd); [DllImport("user32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect); [DllImport("user32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool ShowOwnedPopups(IntPtr hwnd, bool show); [StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left; // x position of upper-left corner public int Top; // y position of upper-left corner public int Right; // x position of lower-right corner public int Bottom; // y position of lower-right corner } #endregion } }