From f23608580f25d93c1d5d55bcd8f47db9cd815f89 Mon Sep 17 00:00:00 2001 From: Emmanuele Sassi Date: Tue, 3 Sep 2024 11:27:59 +0200 Subject: [PATCH] - corretto indice di creazione macchine per comunicazione - gestito posizionamento e dimensione finestra - aggiunta funzione SplitStrign per lua - aggiunta barra sopra in MainWindow - gestita finestra con riposizionamento, dimensioni, ecc - gestita esecuzione asincrona - aggiunta verifica esecuzione macchina stati --- Supervisor.Plugin.Interface/IHost.vb | 2 + Supervisor/Comms/MachineManager.vb | 2 +- Supervisor/Constants/ConstIni.vb | 1 + Supervisor/FiniteStateMachine.vb | 11 +- .../FiniteStateMachineManager.vb | 5 +- Supervisor/LUA/Lua_Aux.vb | 14 +++ Supervisor/LUA/Lua_General.vb | 20 +++- Supervisor/MEFPlugin/SupervisorFunctions.vb | 9 ++ Supervisor/MainWindow/MainWindowV.xaml | 93 +++++++++++++++-- Supervisor/MainWindow/MainWindowV.xaml.vb | 58 ++++++++++- Supervisor/MainWindow/MainWindowVM.vb | 16 +-- Supervisor/Resources/Icon.png | Bin 0 -> 21836 bytes Supervisor/Supervisor.vbproj | 6 ++ Supervisor/Utility/Dictionary.xaml | 95 ++++++++++++++++-- Supervisor/Utility/ExecProcessManager.vb | 30 ++++++ Supervisor/Utility/GenInterface.vb | 53 ++++++++++ Supervisor/Utility/IniFile.vb | 8 ++ Supervisor/Utility/WinPos.vb | 94 +++++++++++++++++ 18 files changed, 492 insertions(+), 25 deletions(-) create mode 100644 Supervisor/Resources/Icon.png create mode 100644 Supervisor/Utility/WinPos.vb diff --git a/Supervisor.Plugin.Interface/IHost.vb b/Supervisor.Plugin.Interface/IHost.vb index abcd531..d0f2e67 100644 --- a/Supervisor.Plugin.Interface/IHost.vb +++ b/Supervisor.Plugin.Interface/IHost.vb @@ -10,6 +10,8 @@ Public Interface IHost Function PlgGetPrivateProfileString(lpAppName As String, lpKeyName As String, lpDefault As String, ByRef lpString As String, lpFileName As String) As Integer Function PlgWritePrivateProfileString(lpAppName As String, lpKeyName As String, lpString As String, lpFileName As String) As Boolean Function PlgExecProcess(sFileName As String, sMainLuaPath As String, sArguments As String) As Boolean + Function PlgExecProcessAsync(sFileName As String, sMainLuaPath As String, sArguments As String) As Boolean + Function PlgCheckExecProcessAsync(ByRef bHasExited As Boolean, ByRef nExitCode As Integer) As Boolean Function ComReadShortVar(nVarAddr As Integer, ByRef nResult As Short, nMachine As Integer) As Boolean Function ComReadBitVar(nVarAddr As Integer, nBit As Integer, ByRef bResult As Boolean, nMachine As Integer) As Boolean Function ComReadDoubleVar(nVarAddr As Integer, ByRef dResult As Double, nMachine As Integer) As Boolean diff --git a/Supervisor/Comms/MachineManager.vb b/Supervisor/Comms/MachineManager.vb index 7a511e7..a0a1158 100644 --- a/Supervisor/Comms/MachineManager.vb +++ b/Supervisor/Comms/MachineManager.vb @@ -36,7 +36,7 @@ Public Class MachineManager If sMachineSplit.Count >= 2 AndAlso Not String.IsNullOrWhiteSpace(sMachineSplit(1)) Then Dim NewOsaiOpen As New NC.OsaiOpen NewOsaiOpen.Connect(sMachineSplit(1)) - m_MachineList(nMachineIndex) = NewOsaiOpen + m_MachineList(nMachineIndex - 1) = NewOsaiOpen End If End Select End If diff --git a/Supervisor/Constants/ConstIni.vb b/Supervisor/Constants/ConstIni.vb index 532396a..de10007 100644 --- a/Supervisor/Constants/ConstIni.vb +++ b/Supervisor/Constants/ConstIni.vb @@ -25,6 +25,7 @@ Module ConstIni Public Const K_MACHINESTATE As String = "MachineState" Public Const K_INITLUA As String = "InitLua" Public Const K_PLUGINNAME As String = "PluginName" + Public Const K_WINPLACE = "WinPlace" Public Const S_REDIS As String = "Redis" Public Const K_ENABLED As String = "Enabled" diff --git a/Supervisor/FiniteStateMachine.vb b/Supervisor/FiniteStateMachine.vb index 604bcc5..8ee2764 100644 --- a/Supervisor/FiniteStateMachine.vb +++ b/Supervisor/FiniteStateMachine.vb @@ -1,6 +1,14 @@ Public Class FiniteStateMachine + Private m_bLuaExecuted As Boolean + Public ReadOnly Property bLuaExecuted As Boolean + Get + Return m_bLuaExecuted + End Get + End Property + Private m_State As Integer + Private m_sLuaPath As String Friend ReadOnly Property sLuaPath As String Get @@ -10,7 +18,8 @@ Sub New(sLuaPath As String) m_sLuaPath = sLuaPath - LuaManager.ExecFile(Map.refMainWindowVM.MainWindowM.sScriptDir & "\" & sLuaPath) + m_bLuaExecuted = LuaManager.ExecFile(Map.refMainWindowVM.MainWindowM.sScriptDir & "\" & sLuaPath) + EgtOutLog(m_sLuaPath & " execution " & If(m_bLuaExecuted, "ok", "failed")) End Sub End Class diff --git a/Supervisor/FiniteStateMachineManager/FiniteStateMachineManager.vb b/Supervisor/FiniteStateMachineManager/FiniteStateMachineManager.vb index 9b4db36..d6e0a71 100644 --- a/Supervisor/FiniteStateMachineManager/FiniteStateMachineManager.vb +++ b/Supervisor/FiniteStateMachineManager/FiniteStateMachineManager.vb @@ -66,8 +66,11 @@ Public Class FiniteStateMachineManager 'm_bFiniteStateMachineExecuting = True ' lancio esecuzione macchine a stati For nMachineIndex = 0 To m_FiniteStateMachineList.Count - 1 - LuaManager.ExecLuaFunction("MACHINE" & (nMachineIndex + 1).ToString() & "_Tick", -1, Nothing) + If m_FiniteStateMachineList(nMachineIndex).bLuaExecuted Then + LuaManager.ExecLuaFunction("MACHINE" & (nMachineIndex + 1).ToString() & "_Tick", -1, Nothing) + End If Next + '' lancio esecuzione preprocessore 'LuaManager.SetGlobVar("PREPROC.ERROR", 0) 'LuaManager.SetGlobVar("PREPROC.ERROR_MSG", "") diff --git a/Supervisor/LUA/Lua_Aux.vb b/Supervisor/LUA/Lua_Aux.vb index 31a7fe6..912b201 100644 --- a/Supervisor/LUA/Lua_Aux.vb +++ b/Supervisor/LUA/Lua_Aux.vb @@ -107,6 +107,20 @@ Public Module Lua_Aux Return True End Function + Friend Function LuaSetParam(state As Lua, ByRef sValue() As String) As Boolean + Try + Dim nSize As Integer = sValue.Count() + state.CreateTable(nSize, 0) + For nIndex = 0 To nSize - 1 + state.PushString(sValue(nIndex)) + state.RawSetInteger(-2, nIndex) + Next + Catch ex As Exception + Return False + End Try + Return True + End Function + Friend Function LuaGetTabFieldParam(state As Lua, nIndex As Integer, sVarName As String, ByRef bValue As Boolean) As Boolean If Not state.IsTable(nIndex) Then Return False state.GetField(nIndex, sVarName) diff --git a/Supervisor/LUA/Lua_General.vb b/Supervisor/LUA/Lua_General.vb index 91e09a1..d5b1b5b 100644 --- a/Supervisor/LUA/Lua_General.vb +++ b/Supervisor/LUA/Lua_General.vb @@ -31,6 +31,7 @@ Public Module Lua_General Friend func_EntGetNumberFromIni As LuaFunction = AddressOf Lua_EntGetNumberFromIni Friend func_EntGetStringFromIni As LuaFunction = AddressOf Lua_EntGetStringFromIni Friend func_EntWriteStringToIni As LuaFunction = AddressOf Lua_EntWriteStringToIni + Friend func_EntSplitString As LuaFunction = AddressOf Lua_EntSplitString Friend func_EntExecProcess As LuaFunction = AddressOf Lua_EntExecProcess Friend func_RdsStringGet As LuaFunction = AddressOf Lua_RdsStringGet Friend func_RdsStringSetAsync As LuaFunction = AddressOf Lua_RdsStringSetAsync @@ -129,9 +130,9 @@ Public Module Lua_General LuaCheckParam(state, 3, dDef) LuaCheckParam(state, 4, sIniFile) LuaClearStack(state) - Dim nResult As Integer = GetPrivateProfileInt(sSec, sKey, dDef, sIniFile) + Dim dResult As Double = GetPrivateProfileDouble(sSec, sKey, dDef, sIniFile) ' restituisco il risultato - LuaSetParam(state, nResult) + LuaSetParam(state, dResult) Return 1 End Function @@ -172,6 +173,20 @@ Public Module Lua_General Return 1 End Function + Private Function Lua_EntSplitString(ByVal p As IntPtr) As Integer + Dim state = Lua.FromIntPtr(p) + ' 4 parametri: sSec, sKey, sVal, sIniFile + Dim sVal As String = "" + Dim sSeparator As Char = ","c + LuaCheckParam(state, 1, sVal) + LuaGetParam(state, 2, sSeparator) + LuaClearStack(state) + Dim sSplitString() As String = sVal.Split(sSeparator) + ' restituisco il risultato + LuaSetParam(state, sSplitString) + Return 1 + End Function + Private Function Lua_RdsStringGet(ByVal p As IntPtr) As Integer Dim state = Lua.FromIntPtr(p) If IsNothing(Map.refMainWindowVM.RedisManager) OrElse IsNothing(Map.refMainWindowVM.RedisManager.Subscriber) Then @@ -359,6 +374,7 @@ Public Module Lua_General state.Register("EntGetNumberFromIni", func_EntGetNumberFromIni) state.Register("EntGetStringFromIni", func_EntGetStringFromIni) state.Register("EntWriteStringToIni", func_EntWriteStringToIni) + state.Register("EntSplitString", func_EntSplitString) state.Register("EntExecProcess", func_EntExecProcess) state.Register("RdsStringGet", func_RdsStringGet) state.Register("RdsStringSetAsync", func_RdsStringSetAsync) diff --git a/Supervisor/MEFPlugin/SupervisorFunctions.vb b/Supervisor/MEFPlugin/SupervisorFunctions.vb index 38b275e..17227bc 100644 --- a/Supervisor/MEFPlugin/SupervisorFunctions.vb +++ b/Supervisor/MEFPlugin/SupervisorFunctions.vb @@ -32,6 +32,15 @@ Public Class SupervisorFunctions Public Function PlgExecProcess(sFileName As String, sMainLuaPath As String, sArguments As String) As Boolean Implements IHost.PlgExecProcess Return ExecProcessManager.ExecProcess(sFileName, sMainLuaPath, sArguments) End Function + + Public Function PlgExecProcessAsync(sFileName As String, sMainLuaPath As String, sArguments As String) As Boolean Implements IHost.PlgExecProcessAsync + Return ExecProcessManager.ExecProcessAsync(sFileName, sMainLuaPath, sArguments) + End Function + + Public Function PlgCheckExecProcessAsync(ByRef bHasExited As Boolean, ByRef nExitCode As Integer) As Boolean Implements IHost.PlgCheckExecProcessAsync + Return ExecProcessManager.CheckExecProcessAsync(bHasExited, nExitCode) + End Function + Public Function ComReadShortVar(nVarAddr As Integer, ByRef nResult As Short, nMachine As Integer) As Boolean Implements IHost.ComReadShortVar If Map.refMainWindowVM.MachineManager.MachineList.Count >= nMachine AndAlso Not IsNothing(Map.refMainWindowVM.MachineManager.MachineList(nMachine - 1)) Then Return Map.refMainWindowVM.MachineManager.MachineList(nMachine - 1).ReadShortVar(nVarAddr, nResult) diff --git a/Supervisor/MainWindow/MainWindowV.xaml b/Supervisor/MainWindow/MainWindowV.xaml index 93290fe..9dec1cf 100644 --- a/Supervisor/MainWindow/MainWindowV.xaml +++ b/Supervisor/MainWindow/MainWindowV.xaml @@ -1,13 +1,94 @@  - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Supervisor/MainWindow/MainWindowV.xaml.vb b/Supervisor/MainWindow/MainWindowV.xaml.vb index 224e738..601de32 100644 --- a/Supervisor/MainWindow/MainWindowV.xaml.vb +++ b/Supervisor/MainWindow/MainWindowV.xaml.vb @@ -1,4 +1,6 @@ -Class MainWindowV +Imports System.Windows.Interop + +Class MainWindowV Private m_MainWindowVM As MainWindowVM @@ -9,15 +11,69 @@ InitializeComponent() ' Assegno al riferimento locale al VM il VM preso dal DataContext m_MainWindowVM = DirectCast(Me.DataContext, MainWindowVM) + AddHandler Me.Loaded, AddressOf MainWindowV_Loaded + AddHandler Me.StateChanged, AddressOf Window_StateChanged + AddHandler Me.Closing, AddressOf MainWindowV_Closing AddHandler Me.Closed, AddressOf MainWindowV_Closed + Me.RefreshMaximizeRestoreButton() End Sub #End Region ' CONSTRUCTOR + Private Sub RefreshMaximizeRestoreButton() + If Me.WindowState = WindowState.Maximized Then + Me.maximizeButton.Visibility = Visibility.Collapsed + Me.restoreButton.Visibility = Visibility.Visible + Else + Me.maximizeButton.Visibility = Visibility.Visible + Me.restoreButton.Visibility = Visibility.Collapsed + End If + End Sub + +#Region "EVENTS" + + Private Sub OnMinimizeButtonClick(ByVal sender As Object, ByVal e As RoutedEventArgs) + Me.WindowState = WindowState.Minimized + End Sub + + Private Sub OnMaximizeRestoreButtonClick(ByVal sender As Object, ByVal e As RoutedEventArgs) + If Me.WindowState = WindowState.Maximized Then + Me.WindowState = WindowState.Normal + Else + Me.WindowState = WindowState.Maximized + End If + End Sub + + Private Sub Window_StateChanged(ByVal sender As Object, ByVal e As EventArgs) + Me.RefreshMaximizeRestoreButton() + End Sub + + Private Sub OnCloseButtonClick(ByVal sender As Object, ByVal e As RoutedEventArgs) + Me.Close() + End Sub + + Private Sub MainWindowV_Loaded(sender As Object, e As RoutedEventArgs) + ' Carico e imposto posizione finestra + WinPosFromIniToWindow(S_GENERAL, K_WINPLACE, Me) + End Sub + + Private Sub MainWindowV_Closing(sender As Object, e As System.ComponentModel.CancelEventArgs) + If (Keyboard.Modifiers And ModifierKeys.Alt) = ModifierKeys.Alt OrElse Keyboard.IsKeyDown(Key.F4) Then + e.Cancel = True + Return + End If + ' Salvo posizione finestra (se non minimizzata) + If WindowState <> WindowState.Minimized Then + WinPosFromWindowToIni(Me, S_GENERAL, K_WINPLACE) + End If + End Sub + Private Sub MainWindowV_Closed(sender As Object, e As EventArgs) If Not IsNothing(m_MainWindowVM) AndAlso Not IsNothing(m_MainWindowVM.FiniteStateMachineManager) Then m_MainWindowVM.FiniteStateMachineManager.ResetFiniteStateMachineTimer() LuaManager.Close() EgtOutLog("Exit") End Sub +#End Region ' EVENTS + End Class diff --git a/Supervisor/MainWindow/MainWindowVM.vb b/Supervisor/MainWindow/MainWindowVM.vb index 01147d5..c6a8617 100644 --- a/Supervisor/MainWindow/MainWindowVM.vb +++ b/Supervisor/MainWindow/MainWindowVM.vb @@ -40,13 +40,17 @@ Public Class MainWindowVM End Property Private m_ContentPanel As Panel - Public Property ContentPanel As Panel + Public ReadOnly Property ContentPanel As Panel Get Return m_ContentPanel End Get - Set(value As Panel) - m_ContentPanel = value - End Set + End Property + + Private m_ContentMenu As Panel + Public ReadOnly Property ContentMenu As Panel + Get + Return m_ContentMenu + End Get End Property Sub New() @@ -74,13 +78,13 @@ Public Class MainWindowVM Application.Current.Resources.MergedDictionaries.Add(PluginDictionary) '' aggiungo MainMenu dal plugin Dim PluginMainMenu As IPluginControl = GetControlByName(Of IPluginControl)(sPluginName, "MainMenu") - 'ContentPanel = PluginMainMenu + m_ContentMenu = PluginMainMenu '' aggiungo manager delle funzioni Lua del Plugin Dim PluginLuaManager As IPluginLuaManager = Map.refMainWindowVM.GetLuaManager(Of IPluginLuaManager)(sPluginName) PluginLuaManager.PlgInit(LuaManager.state) ' aggiungo Project dal plugin Dim ProjectPlugin As IPluginControl = GetControlByName(Of IPluginControl)(sPluginName, "Project") - ContentPanel = ProjectPlugin + m_ContentPanel = ProjectPlugin End If End Sub diff --git a/Supervisor/Resources/Icon.png b/Supervisor/Resources/Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..209a58e4337ee3f850131d8107530a0d482cb691 GIT binary patch literal 21836 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 d|K^z + ..\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll True @@ -132,6 +133,7 @@ ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + @@ -168,6 +170,7 @@ + MSBuild:Compile Designer @@ -256,6 +259,9 @@ false + + + diff --git a/Supervisor/Utility/Dictionary.xaml b/Supervisor/Utility/Dictionary.xaml index bfe5035..b12342a 100644 --- a/Supervisor/Utility/Dictionary.xaml +++ b/Supervisor/Utility/Dictionary.xaml @@ -60,8 +60,10 @@ + + + + diff --git a/Supervisor/Utility/ExecProcessManager.vb b/Supervisor/Utility/ExecProcessManager.vb index 6facc09..b5299c1 100644 --- a/Supervisor/Utility/ExecProcessManager.vb +++ b/Supervisor/Utility/ExecProcessManager.vb @@ -1,5 +1,7 @@ Module ExecProcessManager + Private m_ExecProcess As Process + Friend Function ExecProcess(sFileName As String, sMainLuaPath As String, sArguments As String) As Boolean ' lancio esecuzione programma Dim bResult As Boolean = True @@ -25,4 +27,32 @@ Return bResult End Function + Friend Function ExecProcessAsync(sFileName As String, sMainLuaPath As String, sArguments As String) As Boolean + If Not IsNothing(m_ExecProcess) Then + If Not m_ExecProcess.HasExited Then + m_ExecProcess.Kill() + End If + End If + ' lancio esecuzione programma + Dim bResult As Boolean = True + m_ExecProcess = New Process() + m_ExecProcess.StartInfo.FileName = sFileName + m_ExecProcess.StartInfo.RedirectStandardInput = False + m_ExecProcess.StartInfo.RedirectStandardOutput = False + m_ExecProcess.StartInfo.Arguments = 1.ToString() & " """ & sMainLuaPath & """ """ & sArguments & """" + m_ExecProcess.StartInfo.UseShellExecute = False + m_ExecProcess.StartInfo.CreateNoWindow = True + Return m_ExecProcess.Start() + End Function + + Friend Function CheckExecProcessAsync(ByRef bHasExited As Boolean, ByRef nExitCode As Integer) As Boolean + If IsNothing(m_ExecProcess) Then Return False + bHasExited = m_ExecProcess.HasExited + If bHasExited Then + nExitCode = m_ExecProcess.ExitCode + End If + Threading.Thread.Sleep(100) + Return True + End Function + End Module diff --git a/Supervisor/Utility/GenInterface.vb b/Supervisor/Utility/GenInterface.vb index f7bf24d..cc0386e 100644 --- a/Supervisor/Utility/GenInterface.vb +++ b/Supervisor/Utility/GenInterface.vb @@ -52,6 +52,45 @@ Public Module GenInterface Return nRet End Function + Public Function GetPrivateProfileWinPos( + lpAppName As String, + lpKeyName As String, + ByRef nFlag As Integer, + ByRef nLeft As Integer, + ByRef nTop As Integer, + ByRef nWidth As Integer, + ByRef nHeight As Integer, + lpFileName As String) As Boolean + Dim sVal As String = String.Empty + GetPrivateProfileString(lpAppName, lpKeyName, "", sVal, lpFileName) + Dim sItems() As String = sVal.Split(",".ToCharArray) + If sItems.Count() >= 5 Then + Dim bOk As Boolean = True + If Not Integer.TryParse(sItems(0), nFlag) Then + nFlag = 0 + bOk = False + End If + If Not Integer.TryParse(sItems(1), nLeft) Then + nLeft = 0 + bOk = False + End If + If Not Integer.TryParse(sItems(2), nTop) Then + nTop = 0 + bOk = False + End If + If Not Integer.TryParse(sItems(3), nWidth) Then + nWidth = 1024 + bOk = False + End If + If Not Integer.TryParse(sItems(4), nHeight) Then + nHeight = 768 + bOk = False + End If + Return bOk + End If + Return False + End Function + '-------------------------------- IniFile : Write ------------------------------------------------ Public Function WritePrivateProfileString( @@ -61,6 +100,20 @@ Public Module GenInterface lpFileName As String) As Boolean End Function + Public Function WritePrivateProfileWinPos( + lpAppName As String, + lpKeyName As String, + nFlag As Integer, + nLeft As Integer, + nTop As Integer, + nWidth As Integer, + nHeight As Integer, + lpFileName As String) As Boolean + Dim sVal As String + sVal = nFlag.ToString & "," & nLeft.ToString & "," & nTop.ToString & "," & nWidth.ToString & "," & nHeight.ToString + Return WritePrivateProfileString(lpAppName, lpKeyName, sVal, lpFileName) + End Function + '-------------------------------- Windows -------------------------------------------------------- Public Enum SW As Integer HIDE = 0 diff --git a/Supervisor/Utility/IniFile.vb b/Supervisor/Utility/IniFile.vb index 2e61f35..febc606 100644 --- a/Supervisor/Utility/IniFile.vb +++ b/Supervisor/Utility/IniFile.vb @@ -39,6 +39,10 @@ Public Module IniFile Return GetPrivateProfileString(IpAppName, IpKeyName, IpDefault, IpString, m_sPath) End Function + Public Function GetMainPrivateProfileWinPos(IpAppName As String, IpKeyName As String, ByRef nFlag As Integer, ByRef nLeft As Integer, ByRef nTop As Integer, ByRef nWidth As Integer, ByRef nHeight As Integer) As Boolean + Return GetPrivateProfileWinPos(IpAppName, IpKeyName, nFlag, nLeft, nTop, nWidth, nHeight, m_sPath) + End Function + 'Public Function GetPrivateProfileLanguage(lpAppName As String, lpKeyName As String, lpFileName As String) As Language ' Dim sVal As String = String.Empty ' GetPrivateProfileString(lpAppName, lpKeyName, "", sVal, lpFileName) @@ -63,4 +67,8 @@ Public Module IniFile Return WritePrivateProfileString(IpAppName, IpKeyName, IpString, m_sPath) End Function + Public Function WriteMainPrivateProfileWinPos(IpAppName As String, IpKeyName As String, ByRef nFlag As Integer, ByRef nLeft As Integer, ByRef nTop As Integer, ByRef nWidth As Integer, ByRef nHeight As Integer) As Boolean + Return WritePrivateProfileWinPos(IpAppName, IpKeyName, nFlag, nLeft, nTop, nWidth, nHeight, m_sPath) + End Function + End Module diff --git a/Supervisor/Utility/WinPos.vb b/Supervisor/Utility/WinPos.vb new file mode 100644 index 0000000..7eda759 --- /dev/null +++ b/Supervisor/Utility/WinPos.vb @@ -0,0 +1,94 @@ +'---------------------------------------------------------------------------- +' EgalTech 2017-2017 +'---------------------------------------------------------------------------- +' File : WinPos.vb Data : 08.04.17 Versione : 1.8d1 +' Contenuto : Classe WinPos per gestione posizione e dimensioni finestra. +' +' +' +' Modifiche : 08.04.17 ES Creazione modulo. +' +' +'---------------------------------------------------------------------------- + +Public Module WinPosition + + Public Class WinPos + ' Membri + Public nFlag As Integer + Public nLeft As Integer + Public nTop As Integer + Public nWidth As Integer + Public nHeight As Integer + + Public Sub ToWindow(Window As Window) + ' Verifico che il punto in alto a sinistra stia nello schermo + Dim PtTL = New System.Drawing.Point(nLeft, nTop) + Dim s As System.Windows.Forms.Screen = System.Windows.Forms.Screen.FromPoint(PtTL) + If Not s.Bounds.Contains(PtTL) Then Return + ' Imposto posizione e dimensioni + Window.WindowStartupLocation = WindowStartupLocation.Manual + Window.Top = nTop + Window.Left = nLeft + Window.Height = nHeight + Window.Width = nWidth + Window.WindowState = If(nFlag = 1, WindowState.Maximized, WindowState.Normal) + End Sub + + Public Sub FromWindow(Window As Window) + nTop = CInt(Window.Top) + nLeft = CInt(Window.Left) + nHeight = CInt(Window.Height) + nWidth = CInt(Window.Width) + nFlag = If(Window.WindowState = WindowState.Maximized, 1, 0) + If Window.WindowState = WindowState.Maximized Then + nHeight = CInt(Window.RestoreBounds.Height) + nWidth = CInt(Window.RestoreBounds.Width) + End If + End Sub + + Public Overloads Function FromIni(sSection As String, sKey As String) As Boolean + Return GetMainPrivateProfileWinPos(sSection, sKey, nFlag, nLeft, nTop, nWidth, nHeight) + End Function + + Public Overloads Function FromIni(sSection As String, sKey As String, IpFileName As String) As Boolean + Return GetMainPrivateProfileWinPos(sSection, sKey, nFlag, nLeft, nTop, nWidth, nHeight) + End Function + + Public Overloads Function ToIni(sSection As String, sKey As String) As Boolean + Return WriteMainPrivateProfileWinPos(sSection, sKey, nFlag, nLeft, nTop, nWidth, nHeight) + End Function + + Public Overloads Function ToIni(sSection As String, sKey As String, IpFileName As String) As Boolean + Return WriteMainPrivateProfileWinPos(sSection, sKey, nFlag, nLeft, nTop, nWidth, nHeight) + End Function + + End Class + + Public Function WinPosFromIniToWindow(sSection As String, sKey As String, Window As Window) As Boolean + Dim WinPos As New WinPos + If Not WinPos.FromIni(sSection, sKey) Then Return False + WinPos.ToWindow(Window) + Return True + End Function + + Public Function WinPosFromIniToWindow(sSection As String, sKey As String, Window As Window, IpFileName As String) As Boolean + Dim WinPos As New WinPos + If Not WinPos.FromIni(sSection, sKey, IpFileName) Then Return False + WinPos.ToWindow(Window) + Return True + End Function + + Public Function WinPosFromWindowToIni(Window As Window, sSection As String, sKey As String) As Boolean + Dim WinPos As New WinPos + WinPos.FromWindow(Window) + Return WinPos.ToIni(sSection, sKey) + End Function + + Public Function WinPosFromWindowToIni(Window As Window, sSection As String, sKey As String, IpFileName As String) As Boolean + Dim WinPos As New WinPos + WinPos.FromWindow(Window) + Return WinPos.ToIni(sSection, sKey, IpFileName) + End Function + +End Module