Files
cms_thermo_active/Client/View/NcWindow.cs
T
CMS3762\carminatini e043ae2181 Added First version of Process Manager in Client App
Added Javascript TestPage in wwwroot
2017-12-07 09:17:29 +01:00

787 lines
28 KiB
C#

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
}
}