Files
EgtWPFLib5/EgtFloating/EgtFloatingWindow.vb
T
Emmanuele Sassi 2a34891370 EgtCAM5 + EgtWPFLib5 1.6t1 :
- Aggiunti controlli Floating (prima versione).
2016-08-29 07:31:52 +00:00

175 lines
7.2 KiB
VB.net

' Follow steps 1a or 1b and then 2 to use this custom control in a XAML file.
'
' Step 1a) Using this custom control in a XAML file that exists in the current project.
' Add this XmlNamespace attribute to the root element of the markup file where it is
' to be used:
'
' xmlns:MyNamespace="clr-namespace:EgtCamTest1"
'
'
' Step 1b) Using this custom control in a XAML file that exists in a different project.
' Add this XmlNamespace attribute to the root element of the markup file where it is
' to be used:
'
' xmlns:MyNamespace="clr-namespace:EgtCamTest1;assembly=EgtCamTest1"
'
' You will also need to add a project reference from the project where the XAML file lives
' to this project and Rebuild to avoid compilation errors:
'
' Right click on the target project in the Solution Explorer and
' "Add Reference"->"Projects"->[Browse to and select this project]
'
'
' Step 2)
' Go ahead and use your control in the XAML file. Note that Intellisense in the
' XML editor does not currently work on custom controls and its child elements.
'
' <MyNamespace:EgtFloatingWindow/>
'
Imports System.Runtime.InteropServices
Imports System.Windows.Interop
Namespace EgtFloating
<TemplatePart(Name:="PART_ContentPresenter", Type:=GetType(ContentPresenter))>
Public Class EgtFloatingWindow
Inherits System.Windows.Window
Const GW_HWNDNEXT As UInteger = 2
<DllImport("User32")> _
Private Shared Function GetTopWindow(hWnd As IntPtr) As IntPtr
End Function
<DllImport("User32")> _
Private Overloads Shared Function GetWindow(hWnd As IntPtr, wCmd As UInteger) As IntPtr
End Function
<DllImport("User32")> _
Friend Shared Function GetCursorPos(ByRef pt As Win32Point) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<StructLayout(LayoutKind.Sequential)> _
Friend Structure Win32Point
Public X As Int32
Public Y As Int32
End Structure
Private m_FloatingManager As EgtFloatingManager
Private m_FloatingPanel As EgtFloatingPanel
Private m_IsClicked As Boolean = False
Public Property IsClicked As Boolean
Get
Return m_IsClicked
End Get
Set(value As Boolean)
m_IsClicked = value
End Set
End Property
Private m_IsOnWindow As Boolean = False
Public ReadOnly Property IsOnWindow As Boolean
Get
Return m_IsOnWindow
End Get
End Property
Private m_TrayMouseOver As EgtFloatingTray
Public ReadOnly Property TrayMouseOver As EgtFloatingTray
Get
Return m_TrayMouseOver
End Get
End Property
Private m_MyContentPresenter As ContentPresenter
Public ReadOnly Property MyContentPresenter As ContentPresenter
Get
Return m_MyContentPresenter
End Get
End Property
Shared Sub New()
'This OverrideMetadata call tells the system that this element wants to provide a style that is different than its base class.
'This style is defined in themes\generic.xaml
DefaultStyleKeyProperty.OverrideMetadata(GetType(EgtFloatingWindow), New FrameworkPropertyMetadata(GetType(EgtFloatingWindow)))
End Sub
Public Overrides Sub OnApplyTemplate()
MyBase.OnApplyTemplate()
' Retrieve the Button from the current template
m_MyContentPresenter = TryCast(MyBase.GetTemplateChild("PART_ContentPresenter"), ContentPresenter)
End Sub
Public Sub New(EgtFloatingManager As EgtFloatingManager, EgtFloatingPanel As EgtFloatingPanel)
m_FloatingManager = EgtFloatingManager
m_FloatingPanel = EgtFloatingPanel
'AddHandler EgtFloatingPanel.thmb_Header.PreviewMouseUp, AddressOf EgtFloatingWindow_PreviewMouseUp
End Sub
Public Shared Function GetMousePosition() As Point
Dim w32Mouse As New Win32Point()
GetCursorPos(w32Mouse)
Return New Point(w32Mouse.X, w32Mouse.Y)
End Function
Public Function FindWindowUnderThisAt(screenPoint As Point) As Window
' WPF units (96dpi), not device units
Return (From win In SortWindowsTopToBottom(Application.Current.Windows.OfType(Of Window)()) Where New Rect(win.Left, win.Top, win.Width, win.Height).Contains(screenPoint) AndAlso Not Equals(win, Me) Select win).FirstOrDefault()
End Function
Public Function SortWindowsTopToBottom(unsorted As IEnumerable(Of Window)) As IEnumerable(Of Window)
Dim byHandle = unsorted.ToDictionary(Function(win) New WindowInteropHelper(win).EnsureHandle())
Dim hWnd As IntPtr = GetTopWindow(IntPtr.Zero)
Dim byHandleList As New List(Of Window)
While hWnd <> IntPtr.Zero
If byHandle.ContainsKey(hWnd) Then
byHandleList.Add(byHandle(hWnd))
End If
hWnd = GetWindow(hWnd, GW_HWNDNEXT)
End While
Return byHandleList
End Function
Private Sub EgtFloatingWindow_MouseMove(sender As Object, e As System.Windows.Input.MouseEventArgs) Handles Me.PreviewMouseMove
If e.LeftButton = MouseButtonState.Pressed Then
Me.DragMove()
End If
End Sub
Friend Sub EgtFloatingWindow_LocationChanged(sender As Object, e As EventArgs) Handles Me.LocationChanged
If m_IsClicked Then
Dim nTrayNumber As Integer = m_FloatingManager.FloatingTrayList.Count
Dim absoluteScreenPos = GetMousePosition()
Dim windowUnder = FindWindowUnderThisAt(absoluteScreenPos)
If Not IsNothing(windowUnder) Then
For Each Tray In m_FloatingManager.Items
If Not TypeOf Tray Is EgtFloatingTray Then Continue For
Dim CurrTray As EgtFloatingTray = DirectCast(Tray, EgtFloatingTray)
If windowUnder.Equals(CurrTray.TrayWindow) Then
Dim DockType As Dock = DirectCast(CurrTray.GetValue(DockPanel.DockProperty), Dock)
If (DockType = Dock.Top And m_FloatingPanel.IsTopDockable) Or
(DockType = Dock.Bottom And m_FloatingPanel.IsBottomDockable) Or
(DockType = Dock.Left And m_FloatingPanel.IsLeftDockable) Or
(DockType = Dock.Right And m_FloatingPanel.IsRightDockable) Then
m_TrayMouseOver = CurrTray
m_IsOnWindow = True
CurrTray.TrayWindow.Background = New SolidColorBrush(Color.FromArgb(50, 173, 216, 230))
Exit For
Else
m_TrayMouseOver = Nothing
m_IsOnWindow = False
CurrTray.TrayWindow.Background = Brushes.Transparent
End If
Else
m_TrayMouseOver = Nothing
m_IsOnWindow = False
CurrTray.TrayWindow.Background = Brushes.Transparent
End If
Next
End If
End If
End Sub
End Class
End Namespace