#Region " Imports" Imports System Imports System.Text Imports System.Security Imports System.Security.Permissions Imports Microsoft.Win32.SafeHandles Imports System.Runtime.ConstrainedExecution Imports System.Runtime.InteropServices Imports System.ComponentModel Imports EgtUILib #End Region Module M_MMFiles 'Riferimento alla MainWindow Private m_MainWindow As MainWindow = Application.Current.MainWindow Private Const N_R_VAR As Integer = 12 #Region " Structures" _ Structure SiemensSendStruct Public n_Flag As Integer Public n_Command As Short Public n_param1 As Integer Public n_param2 As Integer Public l_param1 As Long Public l_param2 As Long Public d_param1 As Double Public d_param2 As Double _ Public sz_string As String _ Public sz_string_2 As String End Structure Private SiemensSend As SiemensSendStruct _ Structure SiemensRetStruct Public b_busy As Boolean Public n_result As Short Public n_param1 As Integer Public n_param2 As Integer Public l_param1 As Long Public l_param2 As Long Public d_param1 As Double Public d_param2 As Double Public b_interf_G24 As Boolean Public b_interf_G71 As Boolean Public n_interf_spindle_override As Short Public l_interf_Feed_override As Long Public d_interf_spindle_prog As Double Public d_interf_Prog_Feed As Double Public d_interf_spindle_power As Double Public d_interf_var_value As Double Public b_is_water_ON As Boolean Public b_is_laser_ON As Boolean Public b_is_spindle_ON As Boolean _ Public d_interf_axis_position() As Double _ Public d_interf_axis_delta() As Double _ Public d_interf_variable_values() As Double _ Public sz_interf_error_message As String _ Public lst_NC_messages As String End Structure Public SiemensRet As SiemensRetStruct #End Region #Region " MMFiles constants" ' In terminal services: The name can have a "Global\" or "Local\" prefix to ' explicitly create the object in the global or session namespace. The ' remainder of the name can contain any character except the backslash ' character (\). Friend Const MapPrefix As String = "Local\" Friend Const MapName As String = "SampleMap" Friend Const MapName2 As String = "SampleMap2" Friend Const FullMapName As String = MapPrefix & MapName Friend Const FullMapName2 As String = MapPrefix & MapName2 ' Max size of the file mapping object. Friend Const MapSize As UInt32 = &H10000 ' File offset where the view is to begin. Friend Const ViewOffset As UInt32 = 0 ' The number of bytes of a file mapping to map to the view. All bytes of the ' view must be within the maximum size of the file mapping object (MAP_SIZE). ' If VIEW_SIZE is 0, the mapping extends from the offset (VIEW_OFFSET) to ' the end of the file mapping. Friend Const ViewSize As UInt32 = &H1000 #End Region ' '---------------------------------------------------------------------------------------------------------- ' #Region "ENUM States and Local Constants" Const RETURN_OK As Short = 0 Const RETURN_BAD As Short = 1 Const TIMER_INTERVAL As Integer = 100 Const COPY_MAX_AXES As Short = 5 Const COPY_MAX_VAR As Short = 12 #End Region #Region "local vars " Private aTimer As System.Timers.Timer Private b_busy As Boolean = False #End Region #Region " MMFiles mapping vars" Dim hMapFile As SafeFileMappingHandle = Nothing Dim hMapFile2 As SafeFileMappingHandle = Nothing Dim pView As IntPtr = IntPtr.Zero Dim pView2 As IntPtr = IntPtr.Zero #End Region #Region " Commands constants" Enum CMD As Short CMD_Download_NC_prog = 1 CMD_ActivateProgram = 2 CMD_Delete_NC_prog = 3 CMD_CycleStart = 4 CMD_FeedHold = 5 CMD_Reset = 6 CMD_WriteCncMode = 7 CMD_DPOsition_ReadOnce = 8 CMD_MDI_command = 9 CMD_set_OP_OM = 10 CMD_read_active_mode = 11 CMD_Is_G24_active = 12 CMD_Is_G71_active = 13 CMD_Read_Nc_var = 14 CMD_SHUTDOWN = 99 End Enum Enum State As Short Command_on = 1 Busy_On = 2 Command_off = 3 Busy_Off = 4 End Enum Const COMMAND_ON As Short = 1 Const COMMAND_OFF As Short = 0 #End Region ' '---------------------------------------------------------------------------------------------------------- ' Sub init() MMFile_init() Timer_init() End Sub Sub MMFile_init() Try ' Create the file mapping object -- File comandi hMapFile = NativeMethod.CreateFileMapping( _ INVALID_HANDLE_VALUE, _ IntPtr.Zero, _ FileProtection.PAGE_READWRITE, _ 0, _ MapSize, _ FullMapName) If (hMapFile.IsInvalid) Then Throw New Win32Exception End If ' Create the file mapping object2 . hMapFile2 = NativeMethod.CreateFileMapping( _ INVALID_HANDLE_VALUE, _ IntPtr.Zero, _ FileProtection.PAGE_READWRITE, _ 0, _ MapSize, _ FullMapName2) If (hMapFile2.IsInvalid) Then Throw New Win32Exception End If ' Map a view of the file mapping into the address space of the current process. pView = NativeMethod.MapViewOfFile( _ hMapFile, _ FileMapAccess.FILE_MAP_ALL_ACCESS, _ 0, _ ViewOffset, _ ViewSize) If (pView = IntPtr.Zero) Then Throw New Win32Exception End If ' Map a view of the file mapping into the address space of the current process. pView2 = NativeMethod.MapViewOfFile( _ hMapFile2, _ FileMapAccess.FILE_MAP_READ, _ 0, _ ViewOffset, _ ViewSize) If (pView = IntPtr.Zero) Then Throw New Win32Exception End If Catch ex As Exception EgtOutLog("Errore nell'init dell'm_mmFiles") End Try End Sub Function Stop_Connection() As Boolean Try aTimer.Stop() SiemensSend.n_Command = CMD.CMD_SHUTDOWN ' shutdown SiemensSend.n_Flag = COMMAND_ON ' alzo il comando ' scrivo !!!!! Marshal.StructureToPtr(SiemensSend, pView, False) ' execute_command() System.Threading.Thread.Sleep(2000) If (Not hMapFile Is Nothing) Then If (pView <> IntPtr.Zero) Then NativeMethod.UnmapViewOfFile(pView) ' Unmap the file view. pView = IntPtr.Zero End If hMapFile.Close() ' Close the file mapping object. hMapFile = Nothing End If If (Not hMapFile2 Is Nothing) Then If (pView2 <> IntPtr.Zero) Then NativeMethod.UnmapViewOfFile(pView2) ' Unmap the file view. pView2 = IntPtr.Zero End If hMapFile2.Close() ' Close the file mapping object. hMapFile2 = Nothing End If Return True Catch ex As Exception EgtOutLog("Errore nella stop connection dell'm_mmFiles") Return False End Try End Function ' '---------------------------------------------------------------------------------------------------------- ' Function ActivateProgram(ByVal sz_part_program As String) As Short EgtOutLog("ActivateProgram start dell'm_mmFiles") SiemensSend.n_Command = CMD.CMD_ActivateProgram SiemensSend.sz_string = sz_part_program execute_command() EgtOutLog("ActivateProgram end dell'm_mmFiles") Return SiemensRet.n_result End Function Function Delete_NC_prog(ByVal sz_filename As String) As Short EgtOutLog("Delete_NC_prog start dell'm_mmFiles") SiemensSend.n_Command = CMD.CMD_Delete_NC_prog SiemensSend.sz_string = sz_filename execute_command() EgtOutLog("Delete_NC_prog end dell'm_mmFiles") Return SiemensRet.n_result End Function Function CycleStart() As Short EgtOutLog("CycleStart start dell'm_mmFiles") SiemensSend.n_Command = CMD.CMD_CycleStart execute_command() EgtOutLog("CycleStart end dell'm_mmFiles") Return SiemensRet.n_result End Function Function FeedHold() As Short EgtOutLog("FeedHold start dell'm_mmFiles") SiemensSend.n_Command = CMD.CMD_FeedHold execute_command() EgtOutLog("FeedHold end dell'm_mmFiles") Return SiemensRet.n_result End Function Function Reset() As Short EgtOutLog("Reset start dell'm_mmFiles") SiemensSend.n_Command = CMD.CMD_Reset execute_command() EgtOutLog("Reset end dell'm_mmFiles") Return SiemensRet.n_result End Function Function WriteCncMode(ByVal nmode As Short) As Short EgtOutLog("WriteCncMode start dell'm_mmFiles") SiemensSend.n_Command = CMD.CMD_WriteCncMode SiemensSend.n_param1 = nmode execute_command() EgtOutLog("WriteCncMode end dell'm_mmFiles") Return SiemensRet.n_result End Function Function Download_NC_prog(ByVal sz_Pc_file_name As String, ByVal sz_NC_filen As String) As Short EgtOutLog("Download_NC_prog start dell'm_mmFiles") SiemensSend.n_Command = CMD.CMD_Download_NC_prog SiemensSend.sz_string = sz_Pc_file_name SiemensSend.sz_string_2 = sz_NC_filen execute_command() EgtOutLog("Download_NC_prog end dell'm_mmFiles") Return SiemensRet.n_result End Function Function DPOsition_ReadOnce() As Short EgtOutLog("DPOsition_ReadOnce single dell'm_mmFiles") Return 1 End Function Function MDI_command(sz_command As String) As Short EgtOutLog("MDI_command start dell'm_mmFiles") SiemensSend.n_Command = CMD.CMD_MDI_command SiemensSend.sz_string = sz_command execute_command() EgtOutLog("MDI_command end dell'm_mmFiles") Return SiemensRet.n_result End Function Sub set_OP_OM(ByVal n As Short) EgtOutLog("set_OP_OM start dell'm_mmFiles") SiemensSend.n_Command = CMD.CMD_set_OP_OM SiemensSend.n_param1 = n execute_command() EgtOutLog("set_OP_OM end dell'm_mmFiles") End Sub Function read_active_mode() As Int16 EgtOutLog("read_active_mode start dell'm_mmFiles") SiemensSend.n_Command = CMD.CMD_read_active_mode execute_command() EgtOutLog("read_active_mode end dell'm_mmFiles") Return SiemensRet.n_result End Function Function Is_G24_active() As Boolean EgtOutLog("Is_G24_active single dell'm_mmFiles") Return False End Function Function Is_G71_active() As Boolean EgtOutLog("Is_G71_active single dell'm_mmFiles") Return False End Function Function Read_Nc_var(n_var As Short) As Short EgtOutLog("Read_Nc_var start dell'm_mmFiles") SiemensSend.n_Command = CMD.CMD_Read_Nc_var SiemensSend.n_param1 = n_var execute_command() m_MainWindow.m_CNCommunication.m_CN.d_DReadELS_value = SiemensRet.d_param1 EgtOutLog("Read_Nc_var end dell'm_mmFiles") Return SiemensRet.n_result End Function ' '---------------------------------------------------------------------------------------------------------- ' Sub execute_command() Try ' Attesa eventuale busy iniziale Dim bEnd As Boolean = False While Not bEnd If SiemensRet.b_busy Then System.Threading.Thread.Sleep(50) Else bEnd = True End If End While ' Alzo il comando SiemensSend.n_Flag = COMMAND_ON ' scrivo Marshal.StructureToPtr(SiemensSend, pView, False) ' Ciclo di attesa della risposta Dim nState As State = State.Command_on bEnd = False While Not bEnd Select Case nState Case State.Command_on ' alzato il comando attendo il busy If SiemensRet.b_busy Then nState = State.Busy_On Else System.Threading.Thread.Sleep(50) End If Case State.Busy_On ' trovato il busy abbasso il comando SiemensSend.n_Flag = COMMAND_OFF ' abbasso il comando ' scrivo !!!!! Marshal.StructureToPtr(SiemensSend, pView, False) nState = State.Command_off Case State.Command_off If Not SiemensRet.b_busy Then ' abbassato il comando attendo il busy basso nState = State.Busy_Off Else System.Threading.Thread.Sleep(50) End If Case State.Busy_Off bEnd = True End Select End While EgtOutLog("Eseguito comando :" & SiemensSend.n_Command.ToString()) Catch ex As Exception EgtOutLog("Errore nell'esecuzione di un comando :" & ex.ToString()) End Try End Sub ' '---------------------------------------------------------------------------------------------------------- ' #Region " Timer" ' '--------------------------------------------------------------------------------------------- ' timer rinfresco assi e varie ' Sub Timer_init() ' Create a timer and set an half second interval. aTimer = New System.Timers.Timer() aTimer.Interval = TIMER_INTERVAL ' !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ' Hook up the Elapsed event for the timer. AddHandler aTimer.Elapsed, AddressOf OnTimedEvent aTimer.AutoReset = True ' Have the timer fire repeated events (true is the default) aTimer.Enabled = True ' Start the timer End Sub Private Sub OnTimedEvent(ByVal source As Object, ByVal e As System.Timers.ElapsedEventArgs) If Not b_busy Then aTimer.Enabled = False b_busy = True TimerProcessing() b_busy = False aTimer.Enabled = True End If End Sub Sub TimerProcessing() Try 'EgtOutLog("Siemens TimerProcessing start") SiemensRet = Marshal.PtrToStructure(pView2, SiemensRet.GetType) Dim CurrCN As CN_Siemens = m_MainWindow.m_CNCommunication.m_CN ' Se macchina in pollici, allora valori assi lineari in pollici Dim LinCoeff As Double = If(m_MainWindow.m_CNCommunication.GetMachineInInches(), ONEINCH, ONEMM) ' Copia delle quote degli assi For n As Short = 0 To COPY_MAX_AXES - 1 ' agli assi lineari devo applicare il coefficiente If n < 3 Then CurrCN.d_axis_position(n) = SiemensRet.d_interf_axis_position(n) * LinCoeff CurrCN.d_axis_delta(n) = SiemensRet.d_interf_axis_delta(n) * LinCoeff ' gli assi rotanti sono sempre in gradi Else CurrCN.d_axis_position(n) = SiemensRet.d_interf_axis_position(n) CurrCN.d_axis_delta(n) = SiemensRet.d_interf_axis_delta(n) End If Next ' Copia variabili R For n = 0 To (N_R_VAR - 1) CurrCN.d_Dvariable_values(n) = SiemensRet.d_interf_variable_values(n) Next ' copy spindle current CurrCN.d_spindle_power = SiemensRet.d_interf_spindle_power CurrCN.n_spindle_override(0) = SiemensRet.n_interf_spindle_override CurrCN.d_DInterpo_Feed_override = (Convert.ToDouble(SiemensRet.l_interf_Feed_override)) CurrCN.l_channel_override(0) = SiemensRet.l_interf_Feed_override CurrCN.d_spindle_prog(0) = SiemensRet.d_interf_spindle_prog CurrCN.d_DInterpo_Prog_Feed = SiemensRet.d_interf_Prog_Feed * LinCoeff CurrCN.bSpindleState = SiemensRet.b_is_spindle_ON CurrCN.bCoolantState = SiemensRet.b_is_water_ON CurrCN.bLaserState = SiemensRet.b_is_laser_ON ' copy alarms CurrCN.b_NC_error = False SyncLock CurrCN CurrCN.sz_NC_error_messages.Clear() If Not String.IsNullOrEmpty(SiemensRet.lst_NC_messages) Then CurrCN.sz_NC_error_messages.Add(SiemensRet.lst_NC_messages) CurrCN.b_NC_error = True End If End SyncLock 'EgtOutLog("stop") Catch ex As Exception EgtOutLog("Errore nella lettura delle quote e simili variabili" & ex.ToString) End Try End Sub #End Region ' '---------------------------------------------------------------------------------------------------------- ' #Region "Native API Signatures and Types" ''' ''' Memory Protection Constants ''' http://msdn.microsoft.com/en-us/library/aa366786.aspx ''' ''' Public Enum FileProtection As UInt32 PAGE_NOACCESS = &H1 PAGE_READONLY = &H2 PAGE_READWRITE = &H4 PAGE_WRITECOPY = &H8 PAGE_EXECUTE = &H10 PAGE_EXECUTE_READ = &H20 PAGE_EXECUTE_READWRITE = &H40 PAGE_EXECUTE_WRITECOPY = &H80 PAGE_GUARD = &H100 PAGE_NOCACHE = &H200 PAGE_WRITECOMBINE = &H400 SEC_FILE = &H800000 SEC_IMAGE = &H1000000 SEC_RESERVE = &H4000000 SEC_COMMIT = &H8000000 SEC_NOCACHE = &H10000000 End Enum ''' ''' Access rights for file mapping objects ''' http://msdn.microsoft.com/en-us/library/aa366559.aspx ''' ''' Public Enum FileMapAccess FILE_MAP_COPY = 1 FILE_MAP_WRITE = 2 FILE_MAP_READ = 4 FILE_MAP_ALL_ACCESS = &HF001F End Enum ''' ''' Represents a wrapper class for a file mapping handle. ''' ''' Friend NotInheritable Class SafeFileMappingHandle Inherits SafeHandleZeroOrMinusOneIsInvalid Private Sub New() MyBase.New(True) End Sub Public Sub New(handle As IntPtr, ownsHandle As Boolean) MyBase.New(ownsHandle) MyBase.SetHandle(handle) End Sub Private Shared Function CloseHandle(handle As IntPtr) As Boolean End Function Protected Overrides Function ReleaseHandle() As Boolean Return SafeFileMappingHandle.CloseHandle(MyBase.handle) End Function End Class Friend ReadOnly INVALID_HANDLE_VALUE As New IntPtr(-1) ''' ''' The class exposes Windows APIs used in this code sample. ''' ''' Friend Class NativeMethod ''' ''' Creates or opens a named or unnamed file mapping object for a ''' specified file. ''' ''' ''' A handle to the file from which to create a file mapping object. ''' ''' ''' A pointer to a SECURITY_ATTRIBUTES structure that determines whether ''' a returned handle can be inherited by child processes. ''' ''' ''' Specifies the page protection of the file mapping object. All mapped ''' views of the object must be compatible with this protection. ''' ''' ''' The high-order DWORD of the maximum size of the file mapping object. ''' ''' ''' The low-order DWORD of the maximum size of the file mapping object. ''' ''' ''' The name of the file mapping object. ''' ''' ''' If the function succeeds, the return value is a handle to the newly ''' created file mapping object. ''' Public Shared Function CreateFileMapping( hFile As IntPtr, lpAttributes As IntPtr, flProtect As FileProtection, dwMaximumSizeHigh As UInt32, dwMaximumSizeLow As UInt32, lpName As String) As SafeFileMappingHandle End Function ''' ''' Opens a named file mapping object. ''' ''' ''' The access to the file mapping object. This access is checked against ''' any security descriptor on the target file mapping object. ''' ''' ''' If this parameter is TRUE, a process created by the CreateProcess ''' function can inherit the handle; otherwise, the handle cannot be ''' inherited. ''' ''' ''' The name of the file mapping object to be opened. ''' ''' ''' If the function succeeds, the return value is an open handle to the ''' specified file mapping object. ''' Public Shared Function OpenFileMapping( dwDesiredAccess As FileMapAccess, bInheritHandle As Boolean, lpName As String) As SafeFileMappingHandle End Function ''' ''' Maps a view of a file mapping into the address space of a calling ''' process. ''' ''' ''' A handle to a file mapping object. The CreateFileMapping and ''' OpenFileMapping functions return this handle. ''' ''' ''' The type of access to a file mapping object, which determines the ''' protection of the pages. ''' ''' ''' A high-order DWORD of the file offset where the view begins. ''' ''' ''' A low-order DWORD of the file offset where the view is to begin. ''' ''' ''' The number of bytes of a file mapping to map to the view. All bytes ''' must be within the maximum size specified by CreateFileMapping. ''' ''' ''' If the function succeeds, the return value is the starting address of ''' the mapped view. ''' Public Shared Function MapViewOfFile( hFileMappingObject As SafeFileMappingHandle, dwDesiredAccess As FileMapAccess, dwFileOffsetHigh As UInt32, dwFileOffsetLow As UInt32, dwNumberOfBytesToMap As UInt32) As IntPtr End Function ''' ''' Unmaps a mapped view of a file from the calling process's address ''' space. ''' ''' ''' A pointer to the base address of the mapped view of a file that is to ''' be unmapped. ''' ''' Public Shared Function UnmapViewOfFile( lpBaseAddress As IntPtr) As Boolean End Function End Class #End Region End Module