diff --git a/Message/EventBus.vb b/Message/EventBus.vb new file mode 100644 index 00000000..fed4b4da --- /dev/null +++ b/Message/EventBus.vb @@ -0,0 +1,63 @@ +Imports System.Reflection + +''' +''' A Simple EventBus for .NET +''' https://stackoverflow.com/questions/368265/a-simple-event-bus-for-net +''' +Public Class EventBus + Private Shared _Instance As EventBus + Private _Listeners As List(Of EventListenerWrapper) = New List(Of EventListenerWrapper)() + + Public Shared ReadOnly Property Instance As EventBus + Get + If IsNothing(_Instance) Then + _Instance = New EventBus() + End If + Return _Instance + End Get + End Property + + Public Sub Register(ByVal listener As Object) + If Not _Listeners.Any(Function(l) l.Listener.Equals(listener)) Then + _Listeners.Add(New EventListenerWrapper(listener)) + End If + End Sub + + Public Sub Unregister(ByVal listener As Object) + _Listeners.RemoveAll(Function(l) l.Listener = listener) + End Sub + + Public Sub PostEvent(ByVal e As Object) + _Listeners. + Where(Function(l) l.EventType = e.[GetType]()). + ToList(). + ForEach(Sub(l) l.PostEvent(e)) + End Sub + + + + Private Class EventListenerWrapper + Public Property Listener As Object + Public Property EventType As Type + Private _method As MethodBase + + Public Sub New(ByVal listener As Object) + Me.Listener = listener + Dim oType As Type = listener.[GetType]() + _method = oType.GetMethod("OnEvent") + If _method Is Nothing Then + Throw New ArgumentException("Class " & oType.Name & " does not containt method OnEvent") + End If + Dim oParameters As ParameterInfo() = _method.GetParameters() + + If oParameters.Length <> 1 Then + Throw New ArgumentException("Method OnEvent of class " & oType.Name & " have invalid number of parameters (should be one)") + End If + EventType = oParameters(0).ParameterType + End Sub + + Public Sub PostEvent(ByVal e As Object) + _method.Invoke(Listener, {e}) + End Sub + End Class +End Class diff --git a/Message/Messaging.vbproj b/Message/Messaging.vbproj index a26b52c0..2aed5974 100644 --- a/Message/Messaging.vbproj +++ b/Message/Messaging.vbproj @@ -82,6 +82,7 @@ + True diff --git a/Modules/ZooFlow/ClassProfileFilter.vb b/Modules/ZooFlow/ClassProfileFilter.vb deleted file mode 100644 index bb00d69b..00000000 --- a/Modules/ZooFlow/ClassProfileFilter.vb +++ /dev/null @@ -1,483 +0,0 @@ -Imports System.Drawing -Imports System.Windows.Forms -Imports System.Text.RegularExpressions -Imports DigitalData.Modules.Logging -Imports DigitalData.Modules.Windows -Imports DigitalData.Modules.Language.Utils -Imports DigitalData.Modules.ZooFlow.Params - -Public Class ClassProfileFilter - Private _ProfileTable As DataTable - Private _ProcessTable As DataTable - Private _WindowTable As DataTable - Private _ControlTable As DataTable - Private _Profiles As List(Of ProfileData) - Private _Logger As Logger - Private _TreeView As TreeView - Private _Window As Window - - Public ReadOnly Property Profiles As List(Of ProfileData) - Get - Return _Profiles - End Get - End Property - - Public Sub New(LogConfig As LogConfig, ProfileDatatable As DataTable, ProcessTable As DataTable, WindowDatatable As DataTable, ControlDatatable As DataTable, ImageList As ImageList) - Try - _Logger = LogConfig.GetLogger() - _ProfileTable = ProfileDatatable - _ProcessTable = ProcessTable - _WindowTable = WindowDatatable - _ControlTable = ControlDatatable - _Profiles = TransformProfiles() - _Window = New Window(LogConfig) - - _TreeView.Nodes.Clear() - _TreeView.ImageList = ImageList - _TreeView.SelectedImageIndex = 0 - Catch ex As Exception - _Logger.Error(ex) - Throw ex - End Try - End Sub - - Public Function ToList() As List(Of ProfileData) - Return _Profiles - End Function - - Private Function FindNode(ByVal Node As TreeNode, SearchTerm As String) - Dim oNode As TreeNode - For Each oNode In Node.Nodes - If oNode.Text = SearchTerm Then - Return oNode - End If - Next - Return Node - End Function - - Private Function GetLowestNode(ByVal Node As TreeNode) As TreeNode - If Node.GetNodeCount(False) = 1 Then - Return GetLowestNode(Node.Nodes.Item(0)) - Else - Return Node - End If - End Function - - Public Function FilterProfilesByClipboardRegex(Profiles As List(Of ProfileData), ClipboardContents As String) As List(Of ProfileData) - Dim oFilteredProfiles As New List(Of ProfileData) - For Each oProfile In Profiles - _Logger.Debug("Current Profile: {0}", oProfile.Name) - - Try - Dim oRegex As New Regex(oProfile.Regex) - Dim oMatch = oRegex.Match(ClipboardContents) - If oMatch.Success Then - _Logger.Debug("FilterProfilesByClipboardRegex: Clipboard Regex Matched: {0}", ClipboardContents) - 'TODO: Add Debug Data - oFilteredProfiles.Add(oProfile) - oProfile.IsMatched = True - Dim oNode As New TreeNode($"Profile: {oProfile.Name}") - oNode.ImageIndex = 0 - Dim f = New Font("Tahoma", 9, FontStyle.Bold) - oNode.NodeFont = f - _TreeView.Nodes.Add(oNode) - Dim oSubnode As New TreeNode($"MATCH on Global Clipboard Regex: {oProfile.Regex}") - oSubnode.ImageIndex = 1 - oSubnode.Tag = oProfile.Name & "-REGEX" - oNode.Nodes.Add(oSubnode) - - End If - Catch ex As Exception - _Logger.Warn("Regex '{0}' could not be processed for input '{1}'", oProfile.Regex, ClipboardContents) - _Logger.Error(ex) - End Try - Next - - Return oFilteredProfiles - End Function - Public Function FilterProfilesByProcess(Profiles As List(Of ProfileData), CurrentProcessName As String) As List(Of ProfileData) - Dim oFilteredProfiles As New List(Of ProfileData) - Try - For Each oProfile In Profiles - Dim oGuid = oProfile.Guid - - If oProfile.IsMatched = False Then - Continue For - End If - - - Dim oProcesses As New List(Of ProfileData.ProcessData) - For Each oProcessDef As ProfileData.ProcessData In oProfile.Processes - If oProcessDef.ProfileId <> oGuid Then - Continue For - End If - _Logger.Debug($"FilterProfilesByProcess: Checking Profile: {oProfile.Name} ...") - If oProcessDef.ProcessName.ToLower = CurrentProcessName.ToLower Then - _Logger.Debug($"Yes...Processname Matched: {oProcessDef.ProcessName}") - 'oProfile.MATCH_PROCESSNAME = $"Processname Matched: {oProfile.ProcessName}" - 'TODO: Add Debug Data - oFilteredProfiles.Add(oProfile) - oProfile.MatchedProcessID = oProcessDef.Guid - oProcessDef.IsMatched = True - oProcesses.Add(oProcessDef) - oProfile.IsMatched = True - oProfile.MatchedProcessID = oProcessDef.Guid - Dim oParentNode As TreeNode - Dim oExit = False - For Each oTreeNode As TreeNode In _TreeView.Nodes - For Each oNodes As TreeNode In oTreeNode.Nodes - If oExit = True Then Exit For - If oNodes.Tag = oProfile.Name & "-REGEX" Then - oParentNode = oNodes - oExit = True - Exit For - End If - Next - Next - - If Not IsNothing(oParentNode) Then - Dim oNode As New TreeNode($"MATCH on Process: {oProcessDef.ProcessName}") - oNode.ImageIndex = 4 - oNode.Tag = oProfile.Name & "-PROCESS" - oParentNode.Nodes.Add(oNode) - End If - End If - Next - If oFilteredProfiles.Count > 0 Then - oProfile.Processes = oProcesses - End If - Next - - Return oFilteredProfiles - Catch ex As Exception - _Logger.Warn("Unexpected error in FilterProfilesByProcess...") - _Logger.Error(ex) - End Try - - End Function - Public Function FilterWindowsByWindowTitleRegex(Profiles As List(Of ProfileData), WindowTitle As String) As List(Of ProfileData) - Dim oProfiles As New List(Of ProfileData) - - For Each oProfile As ProfileData In Profiles - _Logger.Debug("Checking WindowDefinition for profile: {0}...", oProfile.Name) - If oProfile.IsMatched = False Then Continue For - Dim oWindows As New List(Of ProfileData.WindowData) - - For Each oWindowDef As ProfileData.WindowData In oProfile.Windows - If oWindowDef.WindowProcessID <> oProfile.MatchedProcessID Then Continue For - Try - If oWindowDef.Regex = String.Empty Then - oProfile.MatchedWindowID = oWindowDef.Guid - oWindowDef.IsMatched = True - oWindows.Add(oWindowDef) - Exit For - End If - - Dim oRegex As New Regex(oWindowDef.Regex) - Dim oMatch = oRegex.Match(WindowTitle) - - If oMatch.Success Then - _Logger.Debug("MATCH on WindowTitle: {0}", WindowTitle) - 'TODO: Add Debug Data - oProfile.MatchedWindowID = oWindowDef.Guid - oWindowDef.IsMatched = True - oWindows.Add(oWindowDef) - Dim olowestNode As TreeNode = Node_Get_Lowest_Node(oProfile.Name & "-REGEX") - If Not IsNothing(olowestNode) Then - Dim oNode As New TreeNode($"MATCH on WindowTitle: [{WindowTitle}]") - oNode.ImageIndex = 3 - oNode.Tag = oProfile.Name & "-WINDOW" - olowestNode.Nodes.Add(oNode) - End If - Exit For - End If - Catch ex As Exception - _Logger.Warn("Regex '{0}' could not be processed for input '{1}'", oWindowDef.Regex, WindowTitle) - _Logger.Error(ex) - End Try - Next - - If oWindows.Count > 0 Then - oProfile.Windows = oWindows - oProfile.IsMatched = True - oProfiles.Add(oProfile) - End If - Next - - Return oProfiles - End Function - - Public Function FilterWindowsByWindowClipboardRegex(Profiles As List(Of ProfileData), ClipboardContents As String) As List(Of ProfileData) - Dim oProfiles As New List(Of ProfileData) - - For Each oProfile As ProfileData In Profiles - _Logger.Debug("Current Profile: {0}", oProfile.Name) - - Dim oWindows As New List(Of ProfileData.WindowData) - - For Each w As ProfileData.WindowData In oProfile.Windows - Try - If w.Regex = String.Empty Then - oWindows.Add(w) - End If - - Dim oRegex As New Regex(w.Regex) - Dim oMatch = oRegex.Match(ClipboardContents) - - If oMatch.Success Then - _Logger.Debug("Window Clipboard Regex Matched: {0}", ClipboardContents) - Dim oResult As TreeNode - For Each oTreeNode In _TreeView.Nodes - If Not IsNothing(oResult) Then Exit For - If oTreeNode.Tag = oProfile.Name & "-REGEX" Then - oResult = oTreeNode - End If - - - Next - If Not IsNothing(oResult) Then - Dim oNode As New TreeNode($"MATCH on WINDOW Clipboard Regex: [{w.Regex}]") - oNode.ImageIndex = 2 - oNode.Tag = oProfile.Name & "-WINDOW_REGEX" - Dim olowestNode As TreeNode = GetLowestNode(oResult) - olowestNode.Nodes.Add(oNode) - End If - - oWindows.Add(w) - - - End If - Catch ex As Exception - _Logger.Warn("Regex '{0}' could not be processed for input '{1}'", w.Regex, ClipboardContents) - _Logger.Error(ex) - End Try - Next - - If oWindows.Count > 0 Then - oProfile.Windows = oWindows - oProfiles.Add(oProfile) - End If - Next - - Return oProfiles - End Function - - Public Function FilterProfilesByFocusedControl(Profiles As List(Of ProfileData), ClipboardContents As String, ControlFocusresult As String) As List(Of ProfileData) - Dim oWindow As Window.WindowInfo - Dim oFocusedControl As Window.WindowInfo - Dim oFocusedControlName As String = String.Empty - - Try - oWindow = _Window.GetWindowInfo() - oFocusedControl = _Window.GetFocusedControl(oWindow.hWnd) - - If oFocusedControl Is Nothing Then - _Logger.Info("Could not get FocusedControl in Window (Old method) {0}", oWindow.WindowTitle) - oFocusedControlName = String.Empty - Else - oFocusedControlName = oFocusedControl.ControlName - End If - Catch ex As Exception - _Logger.Warn("Error while getting Focused control (Old method)") - _Logger.Error(ex) - oFocusedControlName = String.Empty - End Try - - Dim oFilteredProfiles As New List(Of ProfileData) - - For Each oProfileMatchedSofar In Profiles - If oProfileMatchedSofar.IsMatched = False Then Continue For - - _Logger.Debug("Checking ControlDefiniotion on profile: {0}", oProfileMatchedSofar.Name) - If oProfileMatchedSofar.Controls.Count = 0 Then - oFilteredProfiles.Add(oProfileMatchedSofar) - - Dim oNode As New TreeNode($"No Controls configured!") - oNode.ImageIndex = 2 - oNode.ForeColor = Color.Blue - oNode.Tag = oProfileMatchedSofar.Name & "-NOCONTROLCONFIG" - Dim f = New Font("Tahoma", 10, FontStyle.Bold) - oNode.NodeFont = f - _TreeView.Nodes.Add(oNode) - Continue For - End If - - Dim oControls As New List(Of ProfileData.ControlData) - - For Each oControlDefinition In oProfileMatchedSofar.Controls - Try - If oControlDefinition.WindowId <> oProfileMatchedSofar.MatchedWindowID Then Continue For - _Logger.Debug($"Working on ControlDefinition: {oControlDefinition.Guid}-{oControlDefinition.ControlName}...") - If oControlDefinition.Regex = String.Empty Then - oProfileMatchedSofar.MatchedControlID = oControlDefinition.Guid - oControlDefinition.IsMatched = True - oControls.Add(oControlDefinition) - Exit For - End If - 'Dim oResult As TreeNode - 'For Each oTreeNode In CurrMatchTreeView.Nodes - ' oResult = NodeFind(oTreeNode, $"Global Clipboard Regex Matched [{oProfile.Regex}]") - 'Next - 'Dim oNode As TreeNode - Dim oNodeCaption As String - 'Dim oAddNode As Boolean = False - Dim oRegex As New Regex(oControlDefinition.Regex) - - Dim oFocusedControlResult As String = "" - - If oControlDefinition.AutomationId <> String.Empty And oControlDefinition.ControlName = String.Empty Then - _Logger.Debug($"AutomationID should be used...") - If Not IsNothing(ControlFocusresult) Then - If ControlFocusresult <> String.Empty Then - _Logger.Debug($"AutomationID will be used...") - oFocusedControlResult = ControlFocusresult - End If - End If - ElseIf oControlDefinition.AutomationId = String.Empty And oControlDefinition.ControlName <> String.Empty Then - _Logger.Debug($"ControlName should be used...") - If Not IsNothing(oFocusedControlName) Then - If oFocusedControlName <> String.Empty Then - _Logger.Debug($"ControlName will be used...") - oFocusedControlResult = oFocusedControlName - End If - End If - - End If - If oFocusedControlResult <> String.Empty Then - Dim oControlRegex As New Regex(oControlDefinition.Regex) - Dim oControlMatch = oRegex.Match(oFocusedControlResult) - - If oControlMatch.Success Then - _Logger.Debug($"MATCH on Focused Control [{oFocusedControlResult}] with Regex [{oControlDefinition.Regex}]") - oProfileMatchedSofar.IsMatched = True - oProfileMatchedSofar.MatchedControlID = oControlDefinition.Guid - oControlDefinition.IsMatched = True - oControls.Add(oControlDefinition) - Dim olowestNode As TreeNode = Node_Get_Lowest_Node(oProfileMatchedSofar.Name & "-REGEX") - If Not IsNothing(olowestNode) Then - Dim oNode As New TreeNode($"MATCH on Focused Control [{oFocusedControlResult}] with Regex [{oControlDefinition.Regex}]") - oNode.ImageIndex = 2 - oNode.Tag = oProfileMatchedSofar.Name & "-CONTROL" - olowestNode.Nodes.Add(oNode) - End If - Exit For - End If - End If - Catch ex As Exception - _Logger.Warn("Regex '{0}' could not be processed for input '{1}'", oControlDefinition.Regex, oFocusedControlName) - _Logger.Error(ex) - End Try - Next - - If oControls.Count > 0 Then - oProfileMatchedSofar.Controls = oControls - oFilteredProfiles.Add(oProfileMatchedSofar) - Else - Dim olowestNode As TreeNode = Node_Get_Lowest_Node(oProfileMatchedSofar.Name & "-REGEX") - If Not IsNothing(olowestNode) Then - Dim oNode As New TreeNode($"NO MATCHES on Focused Control, Please check the Config") - oNode.ImageIndex = 2 - oNode.Tag = oProfileMatchedSofar.Name & "-CONTROLNoMatch" - olowestNode.Nodes.Add(oNode) - End If - End If - Next - - Return oFilteredProfiles - End Function - Private Function Node_Get_Lowest_Node(NodeTag As String) As TreeNode - Dim oExit = False - Dim oParentNode As TreeNode - For Each oTreeNode As TreeNode In _TreeView.Nodes - For Each oNodes As TreeNode In oTreeNode.Nodes - If oExit = True Then Exit For - If oNodes.Tag = NodeTag Then - oParentNode = oNodes - oExit = True - Exit For - End If - Next - Next - Dim olowestNode As TreeNode = GetLowestNode(oParentNode) - - Return olowestNode - End Function - Public Function ClearNotMatchedProfiles(Profiles As List(Of ProfileData)) As List(Of ProfileData) - Dim oFilteredProfiles As New List(Of ProfileData) - For Each oProfile In Profiles - If oProfile.IsMatched Then - oFilteredProfiles.Add(oProfile) - End If - Next - Return oFilteredProfiles - End Function - Private Function TransformProfiles() As List(Of ProfileData) - Dim oList As New List(Of ProfileData) - - For Each oRow As DataRow In _ProfileTable.Rows - Dim oProfileId = oRow.Item("GUID") - Dim oProcessList As List(Of ProfileData.ProcessData) = TransformProcesses(oProfileId, _ProcessTable) - Dim oWindowList As List(Of ProfileData.WindowData) = TransformWindows(oProfileId, _WindowTable) - Dim oControlList As List(Of ProfileData.ControlData) = TransformControls(oProfileId, _ControlTable) - - oList.Add(New ProfileData() With { - .Guid = oRow.Item("GUID"), - .Regex = NotNull(oRow.Item("REGEX_EXPRESSION"), String.Empty), - .Name = NotNull(oRow.Item("NAME"), String.Empty), - .Comment = NotNull(oRow.Item("COMMENT"), String.Empty), - .ProfileType = NotNull(oRow.Item("PROFILE_TYPE"), String.Empty), - .Processes = oProcessList, - .Windows = oWindowList, - .Controls = oControlList - }) - Next - - Return oList - End Function - - Private Function TransformControls(ProfileId As Integer, ControlDatatable As DataTable) As List(Of ProfileData.ControlData) - Dim oControlList As New List(Of ProfileData.ControlData) - - For Each oRow As DataRow In ControlDatatable.Rows - If oRow.Item("PROFILE_ID") = ProfileId Then - oControlList.Add(New ProfileData.ControlData() With { - .Guid = oRow.Item("GUID"), - .Description = NotNull(oRow.Item("DESCRIPTION"), String.Empty), - .Regex = NotNull(oRow.Item("REGEX"), String.Empty), - .AutomationId = NotNull(oRow.Item("AUTOMATION_ID"), String.Empty), - .WindowId = oRow.Item("WINDOW_ID") - }) - End If - Next - - Return oControlList - End Function - Private Function TransformProcesses(ProfileId As Integer, ProcessDatatable As DataTable) As List(Of ProfileData.ProcessData) - Dim oProcessList As New List(Of ProfileData.ProcessData) - - For Each oRow As DataRow In ProcessDatatable.Rows - oProcessList.Add(New ProfileData.ProcessData() With { - .Guid = oRow.Item("GUID"), - .ProfileId = oRow.Item("PROFILE_ID"), - .ProcessName = NotNull(oRow.Item("PROC_NAME"), String.Empty) - }) - Next - - Return oProcessList - End Function - Private Function TransformWindows(ProfileId As Integer, WindowDatatable As DataTable) As List(Of ProfileData.WindowData) - Dim oWindowList As New List(Of ProfileData.WindowData) - - For Each oRow As DataRow In WindowDatatable.Rows - oWindowList.Add(New ProfileData.WindowData() With { - .Guid = oRow.Item("GUID"), - .WindowProcessID = oRow.Item("PROCESS_ID"), - .Title = NotNull(oRow.Item("DESCRIPTION"), String.Empty), - .Regex = NotNull(oRow.Item("REGEX"), String.Empty), - .Sequence = NotNull(oRow.Item("SEQUENCE"), 0) - }) - Next - - Return oWindowList - End Function -End Class diff --git a/Modules/ZooFlow/ZooFlow.vbproj b/Modules/ZooFlow/ZooFlow.vbproj index 53da6caa..6e22bcfa 100644 --- a/Modules/ZooFlow/ZooFlow.vbproj +++ b/Modules/ZooFlow/ZooFlow.vbproj @@ -74,7 +74,6 @@ - diff --git a/ZooFlow/ClassFlowForm.vb b/ZooFlow/ClassFlowForm.vb index d2da8887..c294eac0 100644 --- a/ZooFlow/ClassFlowForm.vb +++ b/ZooFlow/ClassFlowForm.vb @@ -51,6 +51,9 @@ Class Win32 Public Const AC_SRC_OVER As Byte = &H0 Public Const AC_SRC_ALPHA As Byte = &H1 + Public Const WM_NCLBUTTONDOWN As Integer = &HA1 + Public Const HTCAPTION As Integer = &H2 + Public Shared Function UpdateLayeredWindow(ByVal hwnd As IntPtr, ByVal hdcDst As IntPtr, ByRef pptDst As Point, ByRef psize As Size, ByVal hdcSrc As IntPtr, ByRef pprSrc As Point, ByVal crKey As Int32, ByRef pblend As BLENDFUNCTION, ByVal dwFlags As Int32) As Bool End Function @@ -72,6 +75,13 @@ Class Win32 Public Shared Function DeleteObject(ByVal hObject As IntPtr) As Bool End Function + + Public Shared Function ReleaseCapture() As Boolean + End Function + + Public Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer + End Function + End Class Public Class ClassFlowForm @@ -81,6 +91,23 @@ Public Class ClassFlowForm TopMost = True End Sub + + + Private Sub Form_Load(ByVal sender As Object, ByVal e As EventArgs) + AddHandler MouseDown, New MouseEventHandler(AddressOf Form_MouseDown) + End Sub + + Private Sub Form_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles MyBase.MouseDown + If e.Button = MouseButtons.Left Then + Win32.ReleaseCapture() + Win32.SendMessage(Handle, Win32.WM_NCLBUTTONDOWN, Win32.HTCAPTION, 0) + End If + End Sub + + Private Sub Form_click(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Click + MsgBox("LOL") + End Sub + Public Sub SetBitmap(ByVal bitmap As Bitmap) SetBitmap(bitmap, 255, bitmap.Width, bitmap.Height) End Sub diff --git a/ZooFlow/ClassPatterns.vb b/ZooFlow/ClassPatterns.vb new file mode 100644 index 00000000..be46d13b --- /dev/null +++ b/ZooFlow/ClassPatterns.vb @@ -0,0 +1,302 @@ +Imports System.Text.RegularExpressions +Imports DigitalData.Modules.Logging +Imports DigitalData.Modules.ZooFlow + +''' +''' Defines common Functions for Checking for and replacing placeholders. +''' This Class also includes a child class `Pattern` for passing around Patterns. +''' +''' The format of all placeholders is: +''' {#TYPE#VALUE} +''' +''' Some Examples: +''' {#INT#USERNAME} +''' {#CTRL#CMB_2} +''' {#WMI#String 39} +''' +Public Class ClassPatterns + ' Complex patterns that rely on a datasource like a Database or Windream + Public Const PATTERN_WMI = "WMI" + Public Const PATTERN_CTRL = "CTRL" + ' Simple patterns that only rely on .NET functions + Public Const PATTERN_INT = "INT" + ' Simple patterns that rely on Data from the TBDD_USER table + Public Const PATTERN_USER = "USER" + + Public Const USER_VALUE_PRENAME = "PRENAME" + Public Const USER_VALUE_SURNAME = "SURNAME" + Public Const USER_VALUE_EMAIL = "EMAIL" + Public Const USER_VALUE_SHORTNAME = "SHORTNAME" + Public Const USER_VALUE_USER_ID = "USER_ID" + Public Const USER_VALUE_PROFILE_ID = "PROFILE_ID" + + Public Const INT_VALUE_USERNAME = "USERNAME" + Public Const INT_VALUE_MACHINE = "MACHINE" + Public Const INT_VALUE_DOMAIN = "DOMAIN" + Public Const INT_VALUE_DATE = "DATE" + + Public Const CLIPBOARD_VALUE_DE = "@Zwischenablage" + Public Const CLIPBOARD_VALUE_EN = "@Clipboard" + + Public Const MAX_TRY_COUNT = 100 + + Private _Logger As Logger + Private _LogConfig As LogConfig + + Private _Regex As Regex = New Regex("{#(\w+)#([\w\s_-]+)}+") + Private _AllPatterns As New List(Of String) From {PATTERN_WMI, PATTERN_CTRL, PATTERN_USER, PATTERN_INT} + Private _ComplexPatterns As New List(Of String) From {PATTERN_WMI, PATTERN_CTRL} + Private _SimplePatterns As New List(Of String) From {PATTERN_USER, PATTERN_INT} + + ''' + ''' Wraps a pattern-type and -value in the common format: {#type#value} + ''' + Public Function WrapPatternValue(type As String, value As String) As String + Return New Pattern(type, value).ToString + End Function + + Public Sub New(LogConfig As LogConfig) + _LogConfig = LogConfig + _Logger = LogConfig.GetLogger + End Sub + + Public Function ReplaceAllValues(input As String, User As State.UserState) As String + Try + Dim result = input + + result = ReplaceInternalValues(result) + result = ReplaceUserValues(result, User) + + Return result + Catch ex As Exception + _Logger.Error(ex) + _Logger.Warn("Error in ReplaceAllValues:" & ex.Message) + Return input + End Try + End Function + + Public Function ReplaceClipboardContents(Input As String, ClipboardContents As String) As String + Dim oResult = Input + + oResult = oResult.Replace(CLIPBOARD_VALUE_DE.ToLower, ClipboardContents) + oResult = oResult.Replace(CLIPBOARD_VALUE_DE.ToUpper, ClipboardContents) + oResult = oResult.Replace(CLIPBOARD_VALUE_EN.ToLower, ClipboardContents) + oResult = oResult.Replace(CLIPBOARD_VALUE_EN.ToUpper, ClipboardContents) + + Return oResult + End Function + + Public Function ReplaceInternalValues(Input As String) As String + Try + Dim oResult = Input + + ' Replace Username(s) + While ContainsPatternAndValue(oResult, PATTERN_INT, INT_VALUE_USERNAME) + oResult = ReplacePattern(oResult, PATTERN_INT, System.Environment.UserName) + End While + + ' Replace Machinename(s) + While ContainsPatternAndValue(oResult, PATTERN_INT, INT_VALUE_MACHINE) + oResult = ReplacePattern(oResult, PATTERN_INT, System.Environment.MachineName) + End While + + ' Replace Domainname(s) + While ContainsPatternAndValue(oResult, PATTERN_INT, INT_VALUE_DOMAIN) + oResult = ReplacePattern(oResult, PATTERN_INT, System.Environment.UserDomainName) + End While + + ' Replace CurrentDate(s) + While ContainsPatternAndValue(oResult, PATTERN_INT, INT_VALUE_DATE) + oResult = ReplacePattern(oResult, PATTERN_INT, Now.ToShortDateString) + End While + + Return oResult + Catch ex As Exception + _Logger.Error(ex) + _Logger.Warn("Error in ReplaceInternalValues:" & ex.Message) + Return Input + End Try + End Function + + Public Function ReplaceUserValues(Input As String, User As State.UserState) As String + Try + Dim oResult = Input + + While ContainsPatternAndValue(oResult, PATTERN_USER, USER_VALUE_PRENAME) + oResult = ReplacePattern(Input, PATTERN_USER, User.GivenName) + End While + + While ContainsPatternAndValue(oResult, PATTERN_USER, USER_VALUE_USER_ID) + oResult = ReplacePattern(Input, PATTERN_USER, User.UserId.ToString) + End While + + While ContainsPatternAndValue(oResult, PATTERN_USER, USER_VALUE_SURNAME) + oResult = ReplacePattern(Input, PATTERN_USER, User.Surname) + End While + + While ContainsPatternAndValue(oResult, PATTERN_USER, USER_VALUE_SHORTNAME) + oResult = ReplacePattern(Input, PATTERN_USER, User.ShortName) + End While + + While ContainsPatternAndValue(oResult, PATTERN_USER, USER_VALUE_EMAIL) + oResult = ReplacePattern(Input, PATTERN_USER, User.Email) + End While + + Return oResult + Catch ex As Exception + _Logger.Error(ex) + _Logger.Warn("Error in ReplaceUserValues:" & ex.Message) + Return Input + End Try + End Function + + Public Function ReplaceControlValues(Input As String, Panel As Panel) As String + Try + Dim oResult = Input + Dim oTryCounter = 0 + + While ContainsPattern(oResult, PATTERN_CTRL) + If oTryCounter > MAX_TRY_COUNT Then + Throw New Exception("Max tries in ReplaceControlValues exceeded.") + End If + + Dim controlName As String = GetNextPattern(oResult, PATTERN_CTRL).Value + Dim control As Control = Panel.Controls.Find(controlName, False).FirstOrDefault() + + If control IsNot Nothing Then + Dim value As String = control.Text + oResult = ReplacePattern(oResult, PATTERN_CTRL, value) + End If + + oTryCounter += 1 + End While + + Return oResult + Catch ex As Exception + _Logger.Error(ex) + _Logger.Warn("Error in ReplaceControlValues:" & ex.Message) + Return Input + End Try + End Function + + Private Function ContainsPattern(input As String, type As String) As Boolean + Dim elements As MatchCollection = _Regex.Matches(input) + + For Each element As Match In elements + Dim t As String = element.Groups(1).Value + + If t = type Then + Return True + End If + Next + + Return False + End Function + + Public Function GetNextPattern(Input As String, Type As String) As Pattern + Dim oElements As MatchCollection = _Regex.Matches(Input) + + For Each oElement As Match In oElements + ' Pattern in input + Dim oType As String = oElement.Groups(1).Value + Dim oValue As String = oElement.Groups(2).Value + + If oType = Type Then + Return New Pattern(oType, oValue) + End If + Next + + Return Nothing + End Function + Public Function GetAllPatterns(Input As String) As List(Of Pattern) + Dim elements As MatchCollection = _Regex.Matches(Input) + Dim results As New List(Of Pattern) + + For Each element As Match In elements + ' Pattern in input + Dim t As String = element.Groups(1).Value + Dim v As String = element.Groups(2).Value + + results.Add(New Pattern(t, v)) + Next + + Return results + End Function + Public Function ReplacePattern(Input As String, Type As String, Replacement As String) As String + Dim oElements As MatchCollection = _Regex.Matches(Input) + + If IsNothing(Replacement) Or Replacement = String.Empty Then + Return Input + End If + + For Each element As Match In oElements + ' if group 1 contains the 'pattern' the replace whole group with 'replacement' + ' and return it + If element.Groups(1).Value = Type Then + Return Regex.Replace(Input, element.Groups(0).Value, Replacement) + End If + Next + + ' no replacement made + Return Input + End Function + Private Function ContainsPatternAndValue(Input As String, Type As String, Value As String) As Boolean + Dim oElements As MatchCollection = _Regex.Matches(Input) + + For Each oElement As Match In oElements + ' Pattern in input + Dim oType As String = oElement.Groups(1).Value + Dim oValue As String = oElement.Groups(2).Value + + If oType = Type And oValue = Value Then + Return True + End If + Next + + Return False + End Function + + Public Function HasAnyPatterns(Input As String) As Boolean + Return _AllPatterns.Any(Function(p) + Return HasPattern(Input, p) + End Function) + End Function + + Public Function HasOnlySimplePatterns(Input As String) As Boolean + Return Not HasComplexPatterns(Input) + End Function + + Public Function HasComplexPatterns(Input As String) As Boolean + Return _ComplexPatterns.Any(Function(oPattern) + Return HasPattern(Input, oPattern) + End Function) + End Function + + Public Function HasPattern(Input As String, Type As String) As Boolean + Dim oMatches = _Regex.Matches(Input) + + For Each oMatch As Match In oMatches + For Each oGroup As Group In oMatch.Groups + If oGroup.Value = Type Then + Return True + End If + Next + Next + + Return False + End Function + + Public Class Pattern + Public ReadOnly Property Type As String + Public ReadOnly Property Value As String + + Public Sub New(Type As String, Value As String) + Me.Type = Type + Me.Value = Value + End Sub + + Public Overrides Function ToString() As String + Return $"{{#{Type}#{Value}}}" + End Function + End Class +End Class \ No newline at end of file diff --git a/ZooFlow/ClassProfileFilter.vb b/ZooFlow/ClassProfileFilter.vb index 37d75905..22fc3e5a 100644 --- a/ZooFlow/ClassProfileFilter.vb +++ b/ZooFlow/ClassProfileFilter.vb @@ -217,7 +217,6 @@ Public Class ClassProfileFilter Return oProfiles End Function - Public Function FilterWindowsByWindowClipboardRegex(Profiles As List(Of ProfileData), ClipboardContents As String) As List(Of ProfileData) Dim oProfiles As New List(Of ProfileData) @@ -272,7 +271,6 @@ Public Class ClassProfileFilter Return oProfiles End Function - Public Function FilterProfilesByFocusedControl(Profiles As List(Of ProfileData), ClipboardContents As String, ControlFocusresult As String) As List(Of ProfileData) Dim oWindow As Window.WindowInfo Dim oFocusedControl As Window.WindowInfo @@ -396,6 +394,59 @@ Public Class ClassProfileFilter Return oFilteredProfiles End Function + Public Function FilterProfilesBySearchResults(Profiles As List(Of ProfileData)) As List(Of ProfileData) + Dim oProfiles As New List(Of ProfileData) + + For Each oProfile In Profiles + Dim oResultDocs As Integer = 0 + Dim oResultData As Integer = 0 + + Dim oPatterns As New ClassPatterns(My.LogConfig) + Dim oDataSearches As DataTable = My.Database.GetDatatable($"SELECT COUNT_COMMAND FROM TBCW_PROF_DATA_SEARCH WHERE ACTIVE = 1 AND PROFILE_ID = {oProfile.Guid}") + Dim oDocSearches As DataTable = My.Database.GetDatatable($"SELECT COUNT_COMMAND FROM TBCW_PROF_DOC_SEARCH WHERE ACTIVE = 1 AND PROFILE_ID = {oProfile.Guid}") + + For Each oRow As DataRow In oDataSearches.Rows + Dim oCountCommand = String.Empty + Try + oCountCommand = NotNull(oRow.Item("COUNT_COMMAND"), String.Empty) + + If oCountCommand = String.Empty Then + Continue For + End If + + oCountCommand = oPatterns.ReplaceAllValues(oCountCommand, My.Application.User) + oResultData += NotNull(Of Integer)(My.Database.GetScalarValue(oCountCommand), 0) + Catch ex As Exception + _Logger.Warn("Invalid SQL Query for Counting Data in Profile {0}: {1}", oProfile.Guid, oCountCommand) + End Try + Next + + For Each oRow As DataRow In oDocSearches.Rows + Dim oCountCommand = String.Empty + Try + oCountCommand = NotNull(oRow.Item("COUNT_COMMAND"), String.Empty) + + If oCountCommand = String.Empty Then + Continue For + End If + + oCountCommand = oPatterns.ReplaceAllValues(oCountCommand, My.Application.User) + oResultDocs += NotNull(Of Integer)(My.Database.GetScalarValue(oCountCommand), 0) + Catch ex As Exception + _Logger.Warn("Invalid SQL Query for Counting Data in Profile {0}: {1}", oProfile.Guid, oCountCommand) + End Try + Next + + If oResultData > 0 Or oResultDocs > 0 Then + oProfile.CountData = oResultData + oProfile.CountDocs = oResultDocs + oProfiles.Add(oProfile) + End If + Next + + Return oProfiles + End Function + Private Function Node_Get_Lowest_Node(NodeTag As String) As TreeNode Dim oExit = False Dim oParentNode As TreeNode @@ -445,7 +496,6 @@ Public Class ClassProfileFilter Return oList End Function - Private Function TransformControls(ProfileId As Integer, ControlDatatable As DataTable) As List(Of ProfileData.ControlData) Dim oControlList As New List(Of ProfileData.ControlData) @@ -492,4 +542,6 @@ Public Class ClassProfileFilter Return oWindowList End Function + + End Class diff --git a/ZooFlow/Events/OnFlowFormInteractionEvent.vb b/ZooFlow/Events/OnFlowFormInteractionEvent.vb new file mode 100644 index 00000000..ea200dee --- /dev/null +++ b/ZooFlow/Events/OnFlowFormInteractionEvent.vb @@ -0,0 +1,11 @@ +Public Class OnFlowFormInteractionEvent + Public Enum FlowFormInteraction + Click + End Enum + + Public ReadOnly Property Interaction As FlowFormInteraction + + Public Sub New(Interaction As FlowFormInteraction) + _Interaction = Interaction + End Sub +End Class diff --git a/ZooFlow/Events/OnFlowFormStateChangedEvent.vb b/ZooFlow/Events/OnFlowFormStateChangedEvent.vb new file mode 100644 index 00000000..86cfdf77 --- /dev/null +++ b/ZooFlow/Events/OnFlowFormStateChangedEvent.vb @@ -0,0 +1,12 @@ +Public Class OnFlowFormStateChangedEvent + Public Enum FlowFormState + [Default] + HasSearchResults + End Enum + + Public ReadOnly Property State As FlowFormState + + Public Sub New(State As FlowFormState) + _State = State + End Sub +End Class diff --git a/ZooFlow/My Project/Resources.Designer.vb b/ZooFlow/My Project/Resources.Designer.vb index f18a3286..a42ec63e 100644 --- a/ZooFlow/My Project/Resources.Designer.vb +++ b/ZooFlow/My Project/Resources.Designer.vb @@ -63,9 +63,9 @@ Namespace My.Resources ''' ''' Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. ''' - Friend ReadOnly Property CW_hatwas_klein() As System.Drawing.Bitmap + Friend ReadOnly Property CW_GEFUNDEN_klein() As System.Drawing.Bitmap Get - Dim obj As Object = ResourceManager.GetObject("CW_hatwas_klein", resourceCulture) + Dim obj As Object = ResourceManager.GetObject("CW_GEFUNDEN_klein", resourceCulture) Return CType(obj,System.Drawing.Bitmap) End Get End Property @@ -73,9 +73,39 @@ Namespace My.Resources ''' ''' Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. ''' - Friend ReadOnly Property CW_wartet_klein() As System.Drawing.Bitmap + Friend ReadOnly Property CW_klein() As System.Drawing.Bitmap Get - Dim obj As Object = ResourceManager.GetObject("CW_wartet_klein", resourceCulture) + Dim obj As Object = ResourceManager.GetObject("CW_klein", resourceCulture) + Return CType(obj,System.Drawing.Bitmap) + End Get + End Property + + ''' + ''' Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + ''' + Friend ReadOnly Property GLOBIX_GEFUNDEN_klein() As System.Drawing.Bitmap + Get + Dim obj As Object = ResourceManager.GetObject("GLOBIX_GEFUNDEN_klein", resourceCulture) + Return CType(obj,System.Drawing.Bitmap) + End Get + End Property + + ''' + ''' Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + ''' + Friend ReadOnly Property GLOBIX_klein() As System.Drawing.Bitmap + Get + Dim obj As Object = ResourceManager.GetObject("GLOBIX_klein", resourceCulture) + Return CType(obj,System.Drawing.Bitmap) + End Get + End Property + + ''' + ''' Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + ''' + Friend ReadOnly Property ZOOFLOW_Home_klein() As System.Drawing.Bitmap + Get + Dim obj As Object = ResourceManager.GetObject("ZOOFLOW_Home_klein", resourceCulture) Return CType(obj,System.Drawing.Bitmap) End Get End Property diff --git a/ZooFlow/My Project/Resources.resx b/ZooFlow/My Project/Resources.resx index 2ba959ad..7eb0f61a 100644 --- a/ZooFlow/My Project/Resources.resx +++ b/ZooFlow/My Project/Resources.resx @@ -118,10 +118,19 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - ..\Resources\CW_hatwas_klein.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\CW_GEFUNDEN_klein.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\CW_wartet_klein.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\CW_klein.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\GLOBIX_GEFUNDEN_klein.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\GLOBIX_klein.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\ZOOFLOW_Home_klein.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a \ No newline at end of file diff --git a/ZooFlow/Resources/CW_GEFUNDEN_klein.png b/ZooFlow/Resources/CW_GEFUNDEN_klein.png new file mode 100644 index 00000000..e544b92e Binary files /dev/null and b/ZooFlow/Resources/CW_GEFUNDEN_klein.png differ diff --git a/ZooFlow/Resources/CW_klein.png b/ZooFlow/Resources/CW_klein.png new file mode 100644 index 00000000..251710c6 Binary files /dev/null and b/ZooFlow/Resources/CW_klein.png differ diff --git a/ZooFlow/Resources/GLOBIX_GEFUNDEN_klein.png b/ZooFlow/Resources/GLOBIX_GEFUNDEN_klein.png new file mode 100644 index 00000000..fe73164b Binary files /dev/null and b/ZooFlow/Resources/GLOBIX_GEFUNDEN_klein.png differ diff --git a/ZooFlow/Resources/GLOBIX_klein.png b/ZooFlow/Resources/GLOBIX_klein.png new file mode 100644 index 00000000..1833fdef Binary files /dev/null and b/ZooFlow/Resources/GLOBIX_klein.png differ diff --git a/ZooFlow/Resources/ZOOFLOW_Home_klein.png b/ZooFlow/Resources/ZOOFLOW_Home_klein.png new file mode 100644 index 00000000..de0265d5 Binary files /dev/null and b/ZooFlow/Resources/ZOOFLOW_Home_klein.png differ diff --git a/ZooFlow/ZooFlow.vbproj b/ZooFlow/ZooFlow.vbproj index 6ef8582a..f8628b45 100644 --- a/ZooFlow/ZooFlow.vbproj +++ b/ZooFlow/ZooFlow.vbproj @@ -89,8 +89,11 @@ + + + @@ -183,16 +186,16 @@ - - - - {991d0231-4623-496d-8bd0-9ca906029cbc} Filesystem + + {af664d85-0a4b-4bab-a2f8-83110c06553a} + Messaging + {44982F9B-6116-44E2-85D0-F39650B1EF99} Config @@ -223,6 +226,21 @@ + + + + + + + + + + + + + + +