Imports System.Collections.ObjectModel Imports System.Threading Imports System.Windows.Threading Imports System.Runtime.InteropServices Imports System.Math Imports EgtUILib Namespace EgtCAM5 Public Class MainWindowViewModel Inherits ViewModelBase #Region "FIELDS" ' EGALTECH ENVIRONMENT FIELDS Private m_objMutex As New Mutex '' '' '' '' '' ''Private m_nInstance As Integer = 0 Private m_sDataRoot As String = String.Empty Private m_sConfigDir As String = String.Empty Private m_nDebug As Integer = 0 ' Opzioni abilitate dalla licenza attiva associata alla chiave 'Private m_nKeyOptions As UInteger Friend Enum KEY_OPT As UInteger BASE = 1 End Enum Private m_ProcEventsCallback As New ProcessEventsCallback(AddressOf ProcessEvents) Private m_OutTextCallback As New OutTextCallback(AddressOf OutText) ' EGALTECH ENVIRONMENT FIELDS WITH PROPERTY ' GRAPHICAL FIELDS ' Event commands ' MainWindow ContentRendered Event Private m_Title As String Public Property Title As String Get Return m_Title End Get Set(value As String) If value <> m_Title Then m_Title = value OnPropertyChanged("Title") End If End Set End Property Private m_AboutBox As Window Public ReadOnly Property AboutBox As Window Get Return New AboutBoxView End Get End Property Private m_cmdMainWindow_ContentRendered As ICommand ' MainWindow Activated Event Private m_cmdMainWindow_Activated As ICommand ' MainWindow Deactivated Event Private m_cmdMainWindow_Deactivated As ICommand ' MainWindow Closing Event Private m_cmdMainWindow_Closing As ICommand Private m_cmdCloseApplication As ICommand ' GRAPHICAL ELEMENTS Private m_TopCommandBar As TopCommandBarView Public ReadOnly Property TopCommandBar As TopCommandBarView Get If IsNothing(m_TopCommandBar) Then m_TopCommandBar = New TopCommandBarView m_TopCommandBar.DataContext = New TopCommandBarViewModel End If Return m_TopCommandBar End Get End Property ' GRAPHICAL FIELDS WITH PROPERTY Private m_StatusBar As StatusBarView Private m_bfirst As Boolean = True Public ReadOnly Property StatusBar As StatusBarView Get If m_bfirst Then m_bfirst = False m_StatusBar = New StatusBarView m_StatusBar.DataContext = New StatusBarViewModel End If Return m_StatusBar End Get End Property Private m_ProjectPage As ProjectView Private m_bFirstProjectPage As Boolean = True Public ReadOnly Property ProjectPage As ProjectView Get If m_bFirstProjectPage Then m_bFirstProjectPage = False m_ProjectPage = New ProjectView m_ProjectPage.DataContext = New ProjectViewModel End If Return m_ProjectPage End Get End Property #End Region #Region "CONSTRUCTOR" Sub New() ' INITIALIZE EGALTECH ENVIRONMENT InitializeEgtEnvironment() RegisterMyMessages() AddHandler Application.Current.MainWindow.KeyDown, AddressOf MainWindow_KeyDown ' INITIALIZE GRAPHICS 'TabList.Add(New ProjectViewModel) 'TabList.Add(New ToolsDbViewModel) 'TabList.Add(New MachiningsDbViewModel) 'SelectedTab = TabList(0) 'OnPropertyChanged("SelectedTab") End Sub #End Region ' Constructor #Region "COMMANDS" #Region "CloseApplicationCommand" ''' ''' Returns a command that manage the MainWindow_Unloaded command ''' Public ReadOnly Property CloseApplicationCommand() As ICommand Get If m_cmdCloseApplication Is Nothing Then m_cmdCloseApplication = New RelayCommand(AddressOf CloseApplication, AddressOf CanCloseApplication) End If Return m_cmdCloseApplication End Get End Property ''' ''' Manage the MainWindow_Unloaded event. This method is invoked by the cmdMainWindow_Unloaded. ''' Public Sub CloseApplication(ByVal param As Object) '' Gestisco eventuale file corrente modificato Application.Msn.NotifyColleagues(Application.MANAGEMODIFIED) If m_allowWindowToClose Then Application.Msn.NotifyColleagues(Application.CLOSEAPPLICATION) ' Salvo posizione Form (se non minimizzato) If Application.Current.MainWindow.WindowState <> WindowState.Minimized Then Dim WinPos As New WinPos WindowToWinPos(Application.Current.MainWindow, WinPos) WritePrivateProfileWinPos(S_GENERAL, K_WINPLACE, WinPos.nFlag, WinPos.nLeft, WinPos.nTop, WinPos.nWidth, WinPos.nHeight) End If ' Terminazione generale di EgtInterface EgtExit() ' Rilascio mutex m_objMutex.Close() ' Aggiorno istanze usate Dim nTmp As Integer = GetPrivateProfileInt(S_GENERAL, K_INSTANCES, 0) nTmp -= (1 << (m_nInstance - 1)) WritePrivateProfileString(S_GENERAL, K_INSTANCES, nTmp.ToString()) ' Salvo impostazione macchina corrente Application.Msn.NotifyColleagues(Application.SAVECURRENTMACHINE) '' Disabilito gestore Idle 'RemoveHandler Application.Idle, AddressOf Application_Idle Application.Current.MainWindow.Close() End If End Sub ''' ''' Returns true if the application can be closed ''' Private Function CanCloseApplication(ByVal param As Object) As Boolean '' Impedisco uscita se script in esecuzione 'If m_bScriptRunning Then ' m_bStopScript = True ' E.Cancel = True ' Return 'End If Return True End Function #End Region ' CloseApplicationCommand #Region "cmdMainWindow_ContentRendered" ''' ''' Returns a command that manage the MainWindow_ContentRendered command ''' Public ReadOnly Property cmdMainWindow_ContentRendered() As ICommand Get If m_cmdMainWindow_ContentRendered Is Nothing Then m_cmdMainWindow_ContentRendered = New RelayCommand(AddressOf MainWindow_ContentRendered) End If Return m_cmdMainWindow_ContentRendered End Get End Property ''' ''' Manage the MainWindow_ContentRendered event. This method is invoked by the cmdMainWindow_ContentRendered. ''' Public Sub MainWindow_ContentRendered(ByVal param As Object) ' Notify the ContentRendered event Application.Msn.NotifyColleagues(Application.MAINWINDOW_CONTENTRENDERED) End Sub #End Region ' ContentRendered Command #Region "cmdMainWindow_Activated" ''' ''' Returns a command that manage the MainWindow_ContentRendered command ''' Public ReadOnly Property cmdMainWindow_Activated() As ICommand Get If m_cmdMainWindow_Activated Is Nothing Then m_cmdMainWindow_Activated = New RelayCommand(AddressOf MainWindow_Activated) End If Return m_cmdMainWindow_Activated End Get End Property ''' ''' Manage the MainWindow_ContentRendered event. This method is invoked by the cmdMainWindow_ContentRendered. ''' Public Sub MainWindow_Activated(ByVal param As Object) ' Notify the ContentRendered event Application.Msn.NotifyColleagues(Application.MAINWINDOW_ACTIVATED) End Sub #End Region ' Activated Command #Region "cmdMainWindow_Deactivated" ''' ''' Returns a command that manage the MainWindow_ContentRendered command ''' Public ReadOnly Property cmdMainWindow_Deactivated() As ICommand Get If m_cmdMainWindow_Deactivated Is Nothing Then m_cmdMainWindow_Deactivated = New RelayCommand(AddressOf MainWindow_Deactivated) End If Return m_cmdMainWindow_Deactivated End Get End Property ''' ''' Manage the MainWindow_ContentRendered event. This method is invoked by the cmdMainWindow_ContentRendered. ''' Public Sub MainWindow_Deactivated(ByVal param As Object) ' Notify the ContentRendered event Application.Msn.NotifyColleagues(Application.MAINWINDOW_DEACTIVATED) End Sub #End Region ' Deactivated Command #End Region #Region "METHODS" Private Sub RegisterMyMessages() Application.Msn.Register(Application.CLOSEAPPLICATIONCOMMAND, Sub() Application.Msn.NotifyColleagues(Application.CLOSEAPPLICATION) ' Terminazione generale di EgtInterface EgtExit() ' Rilascio mutex m_objMutex.Close() ' Aggiorno istanze usate Dim nTmp As Integer = GetPrivateProfileInt(S_GENERAL, K_INSTANCES, 0) nTmp -= (1 << (m_nInstance - 1)) WritePrivateProfileString(S_GENERAL, K_INSTANCES, nTmp.ToString()) Application.Current.Shutdown() End Sub) Application.Msn.Register(Application.ALLOWWINDOWTOCLOSE, Sub(bBoolean As Boolean) m_allowWindowToClose = bBoolean End Sub) Application.Msn.Register(Application.UPDATEMAINWINDOWTITLE, Sub(sString As String) Title = sString End Sub) End Sub ''' ''' Method that initialize EgalTech environment ''' Private Sub InitializeEgtEnvironment() '' Abilito drag and drop 'Me.AllowDrop = True '' Title Application.Msn.NotifyColleagues(Application.EMITTITLE) ' Impostazione path radice per i dati m_sDataRoot = System.AppDomain.CurrentDomain.BaseDirectory If EgtUILib.GetPrivateProfileString(S_DATA, K_DATAROOT, "", m_sDataRoot, m_sDataRoot & "\" & DAT_FILE_NAME) = 0 Then m_sDataRoot = System.AppDomain.CurrentDomain.BaseDirectory End If ' Impostazione direttorio di configurazione m_sConfigDir = m_sDataRoot & "\" & CONF_DIR ' Impostazione direttorio per file temporanei m_sTempDir = m_sDataRoot & "\" & TEMP_DIR ' Impostazione path Ini file m_sIniFile = m_sConfigDir & "\" & INI_FILE_NAME ' Impostazione direttorio per le macchine If GetPrivateProfileString(S_MACH, K_MACHINESDIR, "", m_sMachinesRoot) = 0 Then m_sMachinesRoot = m_sDataRoot & "\" & MACHINES_DFL_DIR End If IniFile.m_sMachinesRoot = m_sMachinesRoot ' Verifico indice di istanza ManageIstance() ' Imposto tipo di chiave EgtSetLockType(KEY_TYPE.HW) ' Leggo e imposto chiave di protezione Dim sLicFileName As String = String.Empty GetPrivateProfileString(S_GENERAL, K_LICENCE, LIC_FILE_NAME, sLicFileName) Dim sLicFile As String = m_sConfigDir & "\" & sLicFileName Dim sKey As String = String.Empty EgtUILib.GetPrivateProfileString(S_LICENCE, K_KEY, "", sKey, sLicFile) EgtSetKey(sKey) ' Recupero livello e opzioni della chiave Dim bKey As Boolean = EgtGetKeyLevel(3279, 16, 1, m_nKeyLevel) And EgtGetKeyOptions(3279, 16, 1, m_nKeyOptions) ' Inizializzazione generale di EgtInterface m_nDebug = GetPrivateProfileInt(S_GENERAL, K_DEBUG, 0) Dim sLogFile As String = m_sTempDir & "\" & GENLOG_FILE_NAME.Replace("#", m_nInstance.ToString()) Dim sLogMsg As String = "User " & Environment.UserName & "\" & Environment.MachineName & " (" & m_nInstance.ToString() & ")" & vbLf & My.Application.Info.Description.ToString() & " ver. " & My.Application.Info.Version.ToString() EgtInit(m_nDebug, sLogFile, sLogMsg) ' Leggo direttorio dei messaggi (se manca uso direttorio di configurazione) Dim sMsgDir As String = String.Empty If GetPrivateProfileString(S_GENERAL, K_MESSAGESDIR, "", sMsgDir) = 0 Then sMsgDir = m_sConfigDir End If ' Leggo file messaggi Dim sMsgFile As String = String.Empty GetPrivateProfileString(S_GENERAL, K_MESSAGES, "", sMsgFile) Dim sMsgFilePath As String = sMsgDir & "\" & sMsgFile If Not EgtLoadMessages(sMsgFilePath) Then EgtOutLog("Error in EgtLoadMessages") End If ' Leggo e imposto livello utilizzatore m_nUserLevel = Math.Min(m_nKeyLevel, GetPrivateProfileInt(S_GENERAL, K_USERLEVEL, 1)) ' imposto dir font Nfe e font default Dim sNfeDir As String = String.Empty GetPrivateProfileString(S_GEOMDB, K_NFEFONTDIR, "", sNfeDir) Dim sDefFont As String = String.Empty GetPrivateProfileString(S_GEOMDB, K_DEFAULTFONT, "", sDefFont) EgtSetFont(sNfeDir, sDefFont) ' imposto dir di default per libreria Lua e lancio libreria di base Dim sLuaLibsDir As String = String.Empty GetPrivateProfileString(S_LUA, K_LIBSDIR, "", sLuaLibsDir) EgtSetLuaLibs(sLuaLibsDir) Dim sLuaBaseLib As String = String.Empty GetPrivateProfileString(S_LUA, K_BASELIB, "EgtBase", sLuaBaseLib) EgtLuaRequire(sLuaBaseLib) '' Impostazioni MruLists 'm_MruFiles.Init(m_sIniFile, S_MRUFILES, 8) 'm_MruScripts.Init(m_sIniFile, S_MRUSCRIPTS, 8) ' Installo funzione gestione eventi per lua EgtSetProcessEvents(m_ProcEventsCallback) ' Installo funzione output testo su status per lua EgtSetOutText(m_OutTextCallback) ' Info su opzioni chiave EgtOutLog("KeyOptions : " & bKey.ToString() & " " & m_nKeyOptions.ToString()) End Sub ''' ''' Funzione che permette di gestire il numero di istanze del programma attive contemporaneamente ''' Private Sub ManageIstance() Dim bCreated As Boolean Try m_objMutex = New Mutex(False, "Global\EgtCAM5", bCreated) Catch bCreated = False End Try If bCreated Then ' Prima istanza m_nInstance = 1 ' Aggiorno stato istanze attive WritePrivateProfileString(S_GENERAL, K_INSTANCES, m_nInstance.ToString) Else ' Leggo il massimo numero di istanze ammesse Dim nMaxInst As Integer = GetPrivateProfileInt(S_GENERAL, K_MAXINST, 1) nMaxInst = Max(1, Min(nMaxInst, 32)) ' Cerco il primo indice di istanza libero (max 32) Dim nTmp As Integer = GetPrivateProfileInt(S_GENERAL, K_INSTANCES, 0) m_nInstance = 1 Dim nMask As Integer = 1 While (nTmp And nMask) <> 0 And m_nInstance <= m_nInstance m_nInstance += 1 nMask *= 2 End While ' Se l'indice supera il massimo If m_nInstance > nMaxInst Then ' porto in primo piano la prima istanza Dim bFound As Boolean = False ' processi del programma a 32 bit Dim localProc As Process() = Process.GetProcessesByName("EgtCAM5R32") For Each p As Process In localProc If p.Id <> Process.GetCurrentProcess().Id Then bFound = True ShowWindow(p.MainWindowHandle, SW.SHOWMAXIMIZED) Exit For End If Next ' se non trovati processi a 32 bit provo a 64 bit If Not bFound Then localProc = Process.GetProcessesByName("EgtCAM5R64") For Each p As Process In localProc If p.Id <> Process.GetCurrentProcess().Id Then bFound = True ShowWindow(p.MainWindowHandle, SW.SHOWMAXIMIZED) Exit For End If Next End If ' esco dal programma End End If ' Aggiorno stato istanze attive nTmp += (1 << (m_nInstance - 1)) WritePrivateProfileString(S_GENERAL, K_INSTANCES, nTmp.ToString()) End If End Sub Public Function ProcessEvents(ByVal nProg As Integer, ByVal nPause As Integer) As Integer ' Se previsto, imposto progress If nProg > 0 Then Application.Msn.NotifyColleagues(Application.NOTIFYSTATUSPROGRESS, nProg) End If ' Costringo ad aggiornare Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, New Action(Sub() End Sub)) ' Eventuale attesa Thread.Sleep(nPause) ' Ritorno eventuale stop If m_bStopScript Then m_bStopScript = False Return 0 Else Return 1 End If End Function Public Function OutText(ByRef psText As IntPtr) As Boolean Application.Msn.NotifyColleagues(Application.NOTIFYSTATUSOUTPUT, Marshal.PtrToStringUni(psText)) Return True End Function #End Region #Region "Events" Private Sub MainWindow_KeyDown(ByVal sender As System.Object, ByVal e As KeyEventArgs) ' Con ESC esco dall'azione corrente If e.Key = Key.Escape Then ' reset Azione corrente Application.Msn.NotifyColleagues(Application.RESETSTATUS) ' reset Analisi e Distanza 'chkAnalyze.Checked = False 'chkGetDist.Checked = False ' pulisco output Application.Msn.NotifyColleagues(Application.NOTIFYSTATUSOUTPUT, "") Application.Msn.NotifyColleagues(Application.RESETINPUTBOX) End If End Sub #End Region #Region "Verify closing" ''' ''' Should we let our window close? ''' Private m_allowWindowToClose As Boolean = False #End Region End Class End Namespace