Imports System.Runtime.InteropServices Imports System.Text Imports System.Windows.Interop Imports System.Xml.Serialization Public Class EgtWindowV Private Const WM_GETMINMAXINFO As Integer = &H24 Private Const MONITOR_DEFAULTTONEAREST As UInteger = &H2 Private Const SW_SHOWNORMAL As Integer = 1 Private Const SW_SHOWMINIMIZED As Integer = 2 Public Structure RECT Public Left As Integer Public Top As Integer Public Right As Integer Public Bottom As Integer Public Sub New(ByVal left As Integer, ByVal top As Integer, ByVal right As Integer, ByVal bottom As Integer) Me.Left = left Me.Top = top Me.Right = right Me.Bottom = bottom End Sub End Structure Public Structure MONITORINFO Public cbSize As Integer Public rcMonitor As RECT Public rcWork As RECT Public dwFlags As UInteger End Structure Public Structure POINT Public X As Integer Public Y As Integer Public Sub New(ByVal x As Integer, ByVal y As Integer) Me.X = x Me.Y = y End Sub End Structure Public Structure MINMAXINFO Public ptReserved As POINT Public ptMaxSize As POINT Public ptMaxPosition As POINT Public ptMinTrackSize As POINT Public ptMaxTrackSize As POINT End Structure Public Structure WINDOWPLACEMENT Public length As Integer Public flags As Integer Public showCmd As Integer Public minPosition As POINT Public maxPosition As POINT Public normalPosition As RECT End Structure Private Shared encoding As Encoding = New UTF8Encoding() Private Shared serializer As XmlSerializer = New XmlSerializer(GetType(WINDOWPLACEMENT)) #Region "CONSTRUCTOR" Sub New() ' Funzione che interpreta l'xaml InitializeComponent() AddHandler Me.Loaded, AddressOf MainWindowV_Loaded AddHandler Me.ContentRendered, AddressOf MainWindowV_ContentRendered 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 #Region "METHODS" Private Shared Function MonitorFromWindow(ByVal handle As IntPtr, ByVal flags As UInteger) As IntPtr End Function Private Shared Function GetMonitorInfo(ByVal hMonitor As IntPtr, ByRef lpmi As MONITORINFO) As Boolean End Function Private Shared Function SetWindowPlacement(ByVal hWnd As IntPtr, <[In]> ByRef lpwndpl As WINDOWPLACEMENT) As Boolean End Function Private Shared Function GetWindowPlacement(ByVal hWnd As IntPtr, ByRef lpwndpl As WINDOWPLACEMENT) As Boolean End Function Protected Overrides Sub OnSourceInitialized(ByVal e As EventArgs) MyBase.OnSourceInitialized(e) CType(PresentationSource.FromVisual(Me), HwndSource).AddHook(AddressOf HookProc) Dim sPlacement As String = "" GetMainPrivateProfileString(S_GENERAL, K_WINPLACE, "", sPlacement) If Not String.IsNullOrWhiteSpace(sPlacement) Then SetPlacement(sPlacement) End If End Sub Public Shared Function HookProc(ByVal hwnd As IntPtr, ByVal msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr, ByRef handled As Boolean) As IntPtr If msg = WM_GETMINMAXINFO Then Dim mmi As MINMAXINFO = CType(Marshal.PtrToStructure(lParam, GetType(MINMAXINFO)), MINMAXINFO) Dim monitor As IntPtr = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST) If monitor <> IntPtr.Zero Then Dim monitorInfo As MONITORINFO = New MONITORINFO() monitorInfo.cbSize = Marshal.SizeOf(GetType(MONITORINFO)) GetMonitorInfo(monitor, monitorInfo) Dim rcWorkArea As RECT = monitorInfo.rcWork Dim rcMonitorArea As RECT = monitorInfo.rcMonitor mmi.ptMaxPosition.X = Math.Abs(rcWorkArea.Left - rcMonitorArea.Left) mmi.ptMaxPosition.Y = Math.Abs(rcWorkArea.Top - rcMonitorArea.Top) mmi.ptMaxSize.X = Math.Abs(rcWorkArea.Right - rcWorkArea.Left) mmi.ptMaxSize.Y = Math.Abs(rcWorkArea.Bottom - rcWorkArea.Top) End If Marshal.StructureToPtr(mmi, lParam, True) End If Return IntPtr.Zero End Function Shared Sub SetPlacement(ByVal windowHandle As IntPtr, ByVal placementXml As String) If String.IsNullOrEmpty(placementXml) Then Return End If Dim placement As WINDOWPLACEMENT Try placement = StringToPlacement(placementXml) 'Using memoryStream As TextReader = New StringReader(placementXml) ' placement = CType(serializer.Deserialize(memoryStream), WINDOWPLACEMENT) 'End Using placement.length = Marshal.SizeOf(GetType(WINDOWPLACEMENT)) placement.flags = 0 placement.showCmd = (If(placement.showCmd = SW_SHOWMINIMIZED, SW_SHOWNORMAL, placement.showCmd)) SetWindowPlacement(windowHandle, placement) Catch __unusedInvalidOperationException1__ As InvalidOperationException End Try End Sub Private Shared Function PlacementToString(Placement As WINDOWPLACEMENT) As String Dim sPlacement As String = "" sPlacement = Placement.length.ToString() & ";" & Placement.flags.ToString() & ";" & Placement.showCmd.ToString() & ";" sPlacement &= PointToString(Placement.minPosition) & ";" sPlacement &= PointToString(Placement.maxPosition) & ";" sPlacement &= RectToString(Placement.normalPosition) Return sPlacement End Function Private Shared Function PointToString(Point As POINT) As String Dim sPoint As String = "" sPoint = Point.X.ToString() & "," & Point.Y.ToString() Return sPoint End Function Private Shared Function RectToString(Rect As RECT) As String Dim sRect As String = "" sRect = Rect.Left.ToString() & "," & Rect.Top.ToString() & "," & Rect.Right.ToString() & "," & Rect.Bottom.ToString() Return sRect End Function Shared Function GetPlacement(ByVal windowHandle As IntPtr) As String Dim placement As WINDOWPLACEMENT = New WINDOWPLACEMENT() GetWindowPlacement(windowHandle, placement) Return PlacementToString(placement) 'Using TextWriter As StringWriter = New StringWriter() ' serializer.Serialize(TextWriter, placement) ' Return TextWriter.ToString().Replace(Environment.NewLine, "") 'End Using End Function Private Shared Function StringToPlacement(sPlacement As String) As WINDOWPLACEMENT Dim Placement As WINDOWPLACEMENT Dim sPlacementArray As String() = sPlacement.Split(";"c) If sPlacementArray.Length < 5 Then Placement.normalPosition = New RECT(100, 100, 800, 800) Return Placement End If Integer.TryParse(sPlacementArray(0), Placement.length) Integer.TryParse(sPlacementArray(1), Placement.flags) Integer.TryParse(sPlacementArray(2), Placement.showCmd) Placement.minPosition = StringToPoint(sPlacementArray(3)) Placement.maxPosition = StringToPoint(sPlacementArray(4)) Placement.normalPosition = StringToRect(sPlacementArray(5)) Return Placement End Function Private Shared Function StringToPoint(sPoint As String) As POINT Dim sPointArray As String() = sPoint.Split(","c) Dim nX As Integer = 0 Dim nY As Integer = 0 Integer.TryParse(sPointArray(0), nX) Integer.TryParse(sPointArray(1), nY) Return New POINT(nX, nY) End Function Private Shared Function StringToRect(sRect As String) As RECT Dim sRectArray As String() = sRect.Split(","c) Dim nLeft As Integer = 0 Dim nTop As Integer = 0 Dim nRight As Integer = 0 Dim nBottom As Integer = 0 Integer.TryParse(sRectArray(0), nLeft) Integer.TryParse(sRectArray(1), nTop) Integer.TryParse(sRectArray(2), nRight) Integer.TryParse(sRectArray(3), nBottom) Return New RECT(nLeft, nTop, nRight, nBottom) End Function Public Sub SetPlacement(ByVal placementXml As String) SetPlacement(New WindowInteropHelper(Me).Handle, placementXml) End Sub Public Function GetPlacement() As String Return GetPlacement(New WindowInteropHelper(Me).Handle) End Function 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 #End Region ' METHODS #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_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 WriteMainPrivateProfileString(S_GENERAL, K_WINPLACE, GetPlacement()) End Sub Private Sub MainWindowV_Closed(sender As Object, e As EventArgs) EgtOutLog("Exit") End Sub #End Region ' EVENTS End Class