diff --git a/GUIs.ClipboardWatcher/ProfileSearches.vb b/GUIs.ClipboardWatcher/ProfileSearches.vb index e25200c5..f7effafd 100644 --- a/GUIs.ClipboardWatcher/ProfileSearches.vb +++ b/GUIs.ClipboardWatcher/ProfileSearches.vb @@ -43,10 +43,11 @@ Public Class ProfileSearches End If Catch ex As Exception _Logger.Warn($"Could not initialize the AppServer: {ex.Message}") + _Logger.Error(ex) End Try End If Catch ex As Exception - + _Logger.Error(ex) End Try End Sub @@ -94,13 +95,13 @@ Public Class ProfileSearches End If oDocSearches.Add(New Search() With { - .Guid = oGuid, - .DataTable = oDatatable, - .ProfileId = oProfileId, - .TabCaption = oTabTitle, - .TabIndex = oCounter, - .SQLCommand = oSQL - }) + .Guid = oGuid, + .DataTable = oDatatable, + .ProfileId = oProfileId, + .TabCaption = oTabTitle, + .TabIndex = oCounter, + .SQLCommand = oSQL + }) oCounter += 1 Next diff --git a/GUIs.Common/GridBuilder.vb b/GUIs.Common/GridBuilder.vb index e754d051..0ea7dd2c 100644 --- a/GUIs.Common/GridBuilder.vb +++ b/GUIs.Common/GridBuilder.vb @@ -1,4 +1,5 @@ Imports System.Drawing +Imports System.Windows.Forms Imports DevExpress.XtraGrid.Views.Grid Imports DevExpress.XtraTreeList @@ -80,4 +81,28 @@ Public Class GridBuilder Return Me End Function + + Public Function WithClipboardHandler() As GridBuilder + For Each oGridView In Views + WithClipboardHandler(oGridView) + Next + + Return Me + End Function + + Public Function WithClipboardHandler(View As GridView) As GridBuilder + AddHandler View.KeyDown, AddressOf GridView_ClipboardHandler + + Return Me + End Function + + Private Sub GridView_ClipboardHandler(sender As Object, e As KeyEventArgs) + Dim view As GridView = CType(sender, GridView) + If e.Control AndAlso e.KeyCode = Keys.C Then + If view.GetRowCellValue(view.FocusedRowHandle, view.FocusedColumn) IsNot Nothing AndAlso view.GetRowCellValue(view.FocusedRowHandle, view.FocusedColumn).ToString() <> [String].Empty Then + Clipboard.SetText(view.GetRowCellValue(view.FocusedRowHandle, view.FocusedColumn).ToString()) + End If + e.Handled = True + End If + End Sub End Class diff --git a/GUIs.Common/My Project/AssemblyInfo.vb b/GUIs.Common/My Project/AssemblyInfo.vb index 3b4bfe01..b177f0cb 100644 --- a/GUIs.Common/My Project/AssemblyInfo.vb +++ b/GUIs.Common/My Project/AssemblyInfo.vb @@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices ' übernehmen, indem Sie "*" eingeben: ' - - + + diff --git a/GUIs.Test.GraphQLTest/frmMain.Designer.vb b/GUIs.Test.GraphQLTest/frmMain.Designer.vb index 4f54de16..87ddef7b 100644 --- a/GUIs.Test.GraphQLTest/frmMain.Designer.vb +++ b/GUIs.Test.GraphQLTest/frmMain.Designer.vb @@ -251,6 +251,7 @@ Partial Class frmMain Me.txtOperation.Name = "txtOperation" Me.txtOperation.Size = New System.Drawing.Size(458, 20) Me.txtOperation.TabIndex = 1 + Me.txtOperation.Text = "Auftraege" ' 'btnLogin ' diff --git a/GUIs.Test.GraphQLTest/frmMain.vb b/GUIs.Test.GraphQLTest/frmMain.vb index dfb0d3f7..170aff8c 100644 --- a/GUIs.Test.GraphQLTest/frmMain.vb +++ b/GUIs.Test.GraphQLTest/frmMain.vb @@ -153,7 +153,9 @@ Public Class frmMain End Using End Using - Dim oObj As JObject = JsonConvert.DeserializeObject(oResult) + 'Dim oObj As JObject = JsonConvert.DeserializeObject(oResult) + Dim oObj As JObject = JObject.Parse(oResult) + Dim oData As SAPData = ConvertResponse(oResult) _Logger.Debug("Inserting [{0}] items for datapool [{1}]", oData.sapdaten.Count, oDatapool) @@ -203,7 +205,13 @@ Public Class frmMain End Using End Using - Dim oObj As JObject = JsonConvert.DeserializeObject(oResult) + Dim oPath = "data.auftraege.auftraege" + Dim oObj As JObject = JObject.Parse(oResult) + If _Interface.ReadJSONPathFragmented(oObj, oPath) = False Then + MsgBox($"JSONPath [{oPath}] was not successfully read", MsgBoxStyle.Critical, Text) + End If + 'Dim oObj As JObject = JsonConvert.DeserializeObject(oResult) + Dim oIndentedJson As String = JsonConvert.SerializeObject(oObj, Formatting.Indented) txtResult.Text = oIndentedJson @@ -217,6 +225,7 @@ Public Class frmMain MsgBox(ex.Message, MsgBoxStyle.Critical) End Try End Sub + Sub SaveConfig() _Config.Config.ConnectionString = txtConnectionString.Text _Config.Config.BaseUrl = txtBaseUrl.Text diff --git a/Modules.EDMIAPI/Client.vb b/Modules.EDMIAPI/Client.vb index 5bee249f..06d1b313 100644 --- a/Modules.EDMIAPI/Client.vb +++ b/Modules.EDMIAPI/Client.vb @@ -44,13 +44,22 @@ Public Class Client ''' Creates a new EDMI Client object ''' ''' LogConfig object - ''' The full service url to connect to, for example: net.tcp://1.1.1.1:1111/some/path + ''' The IP address/hostname and port, separated by semicolon or colon, ex localhost:9000 Public Sub New(LogConfig As LogConfig, ServiceAdress As String) _logger = LogConfig.GetLogger() + Dim oServiceAddress As String = ServiceAdress + Dim oAddressArray() As String + + If oServiceAddress.Contains(";") Then + oAddressArray = oServiceAddress.Split(";") + Else + oAddressArray = oServiceAddress.Split(":") + End If + Try Dim oBinding = Channel.GetBinding() - Dim oAddress = New EndpointAddress(ServiceAdress) + Dim oAddress = New EndpointAddress($"net.tcp://{oAddressArray(0)}:{oAddressArray(1)}/DigitalData/Services/Main") Dim oFactory = New ChannelFactory(Of IEDMIServiceChannel)(oBinding, oAddress) _channelFactory = oFactory diff --git a/Modules.EDMIAPI/My Project/AssemblyInfo.vb b/Modules.EDMIAPI/My Project/AssemblyInfo.vb index d369d531..1ea84e11 100644 --- a/Modules.EDMIAPI/My Project/AssemblyInfo.vb +++ b/Modules.EDMIAPI/My Project/AssemblyInfo.vb @@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices ' übernehmen, indem Sie "*" eingeben: ' - - + + diff --git a/Modules.Interfaces/GraphQLInterface.vb b/Modules.Interfaces/GraphQLInterface.vb index ecbc59ab..fe19ea41 100644 --- a/Modules.Interfaces/GraphQLInterface.vb +++ b/Modules.Interfaces/GraphQLInterface.vb @@ -118,6 +118,30 @@ Public Class GraphQLInterface End Try End Function + Public Function ReadJSONPathFragmented(pObject As Linq.JObject, pJsonPath As String) + Dim oSplitPath As List(Of String) = pJsonPath.Split(".").ToList() + Dim oCurrentPath As String = String.Empty + + For Each oPart In oSplitPath + If oCurrentPath = String.Empty Then + oCurrentPath = oPart + Else + oCurrentPath &= "." & oPart + End If + + _logger.Debug("Selecting Path Fragment [{0}]", oCurrentPath) + + Try + pObject.SelectToken(oCurrentPath, errorWhenNoMatch:=True) + Catch ex As Exception + _logger.Warn("Path Fragment [{0}] did not return a valid token", oCurrentPath) + Return False + End Try + Next + + Return True + End Function + Private Function GetRequest(Url As String, PostData As Byte()) As HttpWebRequest Try Dim oRequest As HttpWebRequest = WebRequest.Create($"{_baseUrl}{Url}") diff --git a/Modules.Interfaces/My Project/AssemblyInfo.vb b/Modules.Interfaces/My Project/AssemblyInfo.vb index 13c23910..1f13e7f4 100644 --- a/Modules.Interfaces/My Project/AssemblyInfo.vb +++ b/Modules.Interfaces/My Project/AssemblyInfo.vb @@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices ' übernehmen, indem Sie "*" eingeben: ' - - + + diff --git a/Modules.Jobs/EDMI/GraphQL/GraphQLJob.vb b/Modules.Jobs/EDMI/GraphQL/GraphQLJob.vb index 01ebedde..1151b1c3 100644 --- a/Modules.Jobs/EDMI/GraphQL/GraphQLJob.vb +++ b/Modules.Jobs/EDMI/GraphQL/GraphQLJob.vb @@ -16,6 +16,8 @@ Public Class GraphQLJob Inherits JobBase Implements IJob(Of GraphQLArgs) + Private _GraphQL As GraphQLInterface = Nothing + Private Const PLACEHOLDER_STATIC = "STATIC:" Public Sub New(LogConfig As LogConfig, MSSQL As MSSQLServer) @@ -27,18 +29,16 @@ Public Class GraphQLJob Dim oConfigPath As String = Args.QueryConfigPath Dim oConfigManager As New ConfigManager(Of GraphQLConfig)(_LogConfig, oConfigPath) - Dim oInterface As GraphQLInterface - With oConfigManager.Config - oInterface = New GraphQLInterface(_LogConfig, .BaseUrl, .Email, .Password, .CertificateFingerprint) + _GraphQL = New GraphQLInterface(_LogConfig, .BaseUrl, .Email, .Password, .CertificateFingerprint) End With ' Login to get cookie _Logger.Debug("Logging in") - Dim oLoginResponse = oInterface.Login() + Dim oLoginResponse = _GraphQL.Login() ' save cookie for future requests - oInterface.SaveCookies(oLoginResponse.Cookies.Item(0)) + _GraphQL.SaveCookies(oLoginResponse.Cookies.Item(0)) _Logger.Debug("Loading Queries") @@ -85,7 +85,7 @@ Public Class GraphQLJob _Logger.Info("Getting data..", oQuery.Name) ' get the data from GraphQL - Dim oDataResponse = oInterface.GetData(oQuery.QueryString, oQuery.OperationName) + Dim oDataResponse = _GraphQL.GetData(oQuery.QueryString, oQuery.OperationName) Dim oResult As String ' write data to string @@ -144,7 +144,7 @@ Public Class GraphQLJob ' logout _Logger.Debug("Logging out") - Dim oLogoutResponse = oInterface.Logout() + Dim oLogoutResponse = _GraphQL.Logout() Catch ex As Exception _Logger.Error(ex) Throw ex @@ -153,24 +153,26 @@ Public Class GraphQLJob Private Function HandleResponse(JsonString As String, QueryData As GraphQL.Query, DB As Database.MSSQLServer) As GraphQL.Query Dim oObj As JObject = JObject.Parse(JsonString) - Dim oResultList As JToken = oObj.SelectToken(QueryData.MappingBasePath) + Dim oResultList As JToken + + If _GraphQL.ReadJSONPathFragmented(oObj, QueryData.MappingBasePath) = False Then + _Logger.Warn("There is an error in the MappingBasePath [{1}] configuration of query [{0}]", QueryData.Name, QueryData.MappingBasePath) + End If + + Try + oResultList = oObj.SelectToken(QueryData.MappingBasePath, errorWhenNoMatch:=True) + Catch ex As Exception + _Logger.Warn("HandleResponse: Could not find BasePath: [{0}] for query [{1}]", QueryData.MappingBasePath, QueryData.Name) + _Logger.Error(ex) + Return Nothing + End Try If oResultList Is Nothing Then _Logger.Warn("HandleResponse: Could not find BasePath: [{0}] for query [{1}]", QueryData.MappingBasePath, QueryData.Name) Return Nothing End If - _Logger.Info("Processing Queue [{0}] with [{1}] Items", QueryData.Name, oResultList.Count) - - 'If QueryData.ClearBeforeFill Then - ' _Logger.Info("Clearing Table {0} before insert", QueryData.DestinationTable) - ' _Logger.Info("Clear Command: [{0}]", QueryData.ClearCommand) - ' Try - ' DB.ExecuteNonQuery(QueryData.ClearCommand) - ' Catch ex As Exception - ' _Logger.Error(ex) - ' End Try - 'End If + _Logger.Info("HandleResponse: Processing Queue [{0}] with [{1}] Items", QueryData.Name, oResultList.Count) For Each oResultItem As JToken In oResultList Try diff --git a/Modules.Jobs/My Project/AssemblyInfo.vb b/Modules.Jobs/My Project/AssemblyInfo.vb index e92ef05e..a179eea5 100644 --- a/Modules.Jobs/My Project/AssemblyInfo.vb +++ b/Modules.Jobs/My Project/AssemblyInfo.vb @@ -30,5 +30,5 @@ Imports System.Runtime.InteropServices ' Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern ' übernehmen, indem Sie "*" eingeben: - - + + diff --git a/Modules.Logging/LogConfig.vb b/Modules.Logging/LogConfig.vb index ac14280f..ef1ac8ef 100644 --- a/Modules.Logging/LogConfig.vb +++ b/Modules.Logging/LogConfig.vb @@ -88,7 +88,6 @@ Public Class LogConfig Private Const LOG_FORMAT_DEFAULT As String = LOG_FORMAT_BASE & " >> ${message}" Private Const LOG_FORMAT_ERROR As String = LOG_FORMAT_BASE & " >> " & LOG_FORMAT_EXCEPTION Private Const LOG_FORMAT_DEBUG As String = LOG_FORMAT_BASE & " >> " & LOG_FORMAT_CALLSITE & " -> " & "${message}" - Private Const LOG_FORMAT_MEMORY As String = LOG_FORMAT_BASE & " >> " & LOG_FORMAT_EXCEPTION Private Const FILE_NAME_ACCESS_TEST = "accessTest.txt" Private Const FOLDER_NAME_LOG = "Log" @@ -251,6 +250,9 @@ Public Class LogConfig LogDirectory = _basePath LogFile = GetCurrentLogFilePath() + Dim oLogger = GetLogger() + oLogger.Info("Logging started for [{0}{1}] in [{2}]", oProductName, logFileSuffix, LogFile) + ' Clear old Logfiles as defined in `FileKeepInterval` ClearOldLogfiles(FileKeepRangeInDays) End Sub @@ -442,6 +444,7 @@ Public Class LogConfig config.AddRuleForOneLevel(LogLevel.Fatal, TARGET_ERROR_EX) config.AddRuleForOneLevel(LogLevel.Warn, TARGET_DEFAULT) config.AddRuleForOneLevel(LogLevel.Info, TARGET_DEFAULT) + config.AddRuleForAllLevels(TARGET_MEMORY) End Sub ''' @@ -534,7 +537,7 @@ Public Class LogConfig Private Function GetMemoryDebugTarget() As MemoryTarget Dim memoryLog As New MemoryTarget() With { - .Layout = LOG_FORMAT_MEMORY, + .Layout = LOG_FORMAT_DEBUG, .Name = TARGET_MEMORY, .OptimizeBufferReuse = True } diff --git a/Modules.Logging/My Project/AssemblyInfo.vb b/Modules.Logging/My Project/AssemblyInfo.vb index 9df0cb66..2a2924ae 100644 --- a/Modules.Logging/My Project/AssemblyInfo.vb +++ b/Modules.Logging/My Project/AssemblyInfo.vb @@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices ' übernehmen, indem Sie "*" eingeben: ' - - + + diff --git a/Windows/My Project/AssemblyInfo.vb b/Windows/My Project/AssemblyInfo.vb index 7f8740f7..374458eb 100644 --- a/Windows/My Project/AssemblyInfo.vb +++ b/Windows/My Project/AssemblyInfo.vb @@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices ' übernehmen, indem Sie "*" eingeben: ' - - + + diff --git a/Windows/Utils.vb b/Windows/Utils.vb deleted file mode 100644 index c6c197c1..00000000 --- a/Windows/Utils.vb +++ /dev/null @@ -1,96 +0,0 @@ -Imports System.Text -Imports System.ComponentModel - -Public Class Utils - Private Shared GetControlNameMessage As Integer = 0 - - Public Shared Function GetWinFormsId(ByVal hWnd As IntPtr) As String - GetControlNameMessage = NativeMethods.RegisterWindowMessage("WM_GETCONTROLNAME") - Return XProcGetControlName(hWnd, GetControlNameMessage) - End Function - - Protected Shared Function XProcGetControlName(ByVal hwnd As IntPtr, ByVal msg As Integer) As String - Dim bytearray As Byte() = New Byte(65535) {} - Dim bufferMem As IntPtr = IntPtr.Zero - Dim written As IntPtr = IntPtr.Zero - Dim retHandle As IntPtr = IntPtr.Zero - Dim retVal As Boolean - Dim processHandle As IntPtr = IntPtr.Zero - Dim fileHandle As IntPtr = IntPtr.Zero - - If Not (Environment.OSVersion.Platform = PlatformID.Win32Windows) Then - - Try - Dim size As UInteger - size = 65536 - processHandle = NativeMethods.OpenProcess(NativeMethods.PROCESS_VM_OPERATION Or NativeMethods.PROCESS_VM_READ Or NativeMethods.PROCESS_VM_WRITE, False, GetProcessIdFromHWnd(hwnd)) - - If processHandle.ToInt64() = 0 Then - Throw New Win32Exception() - End If - - bufferMem = NativeMethods.VirtualAllocEx(processHandle, IntPtr.Zero, New UIntPtr(size), NativeMethods.MEM_RESERVE Or NativeMethods.MEM_COMMIT, NativeMethods.PageProtection.ReadWrite) - - If bufferMem.ToInt64() = 0 Then - Throw New Win32Exception() - End If - - retHandle = NativeMethods.SendMessage(hwnd, msg, New IntPtr(size), bufferMem) - retVal = NativeMethods.ReadProcessMemory(processHandle, bufferMem, bytearray, New UIntPtr(size), written) - - If Not retVal Then - Throw New Win32Exception() - End If - - Finally - retVal = NativeMethods.VirtualFreeEx(processHandle, bufferMem, New UIntPtr(0), NativeMethods.MEM_RELEASE) - - If Not retVal Then - Throw New Win32Exception() - End If - - NativeMethods.CloseHandle(processHandle) - End Try - Else - - Try - Dim size2 As Integer - size2 = 65536 - fileHandle = NativeMethods.CreateFileMapping(New IntPtr(NativeMethods.INVALID_HANDLE_VALUE), IntPtr.Zero, NativeMethods.PageProtection.ReadWrite, 0, size2, Nothing) - - If fileHandle.ToInt64() = 0 Then - Throw New Win32Exception() - End If - - bufferMem = NativeMethods.MapViewOfFile(fileHandle, NativeMethods.FILE_MAP_ALL_ACCESS, 0, 0, New UIntPtr(0)) - - If bufferMem.ToInt64() = 0 Then - Throw New Win32Exception() - End If - - NativeMethods.MoveMemoryFromByte(bufferMem, bytearray(0), size2) - retHandle = NativeMethods.SendMessage(hwnd, msg, New IntPtr(size2), bufferMem) - NativeMethods.MoveMemoryToByte(bytearray(0), bufferMem, 1024) - Finally - NativeMethods.UnmapViewOfFile(bufferMem) - NativeMethods.CloseHandle(fileHandle) - End Try - End If - - Return ByteArrayToString(bytearray) - End Function - - Private Shared Function GetProcessIdFromHWnd(ByVal hwnd As IntPtr) As UInteger - Dim pid As UInteger - NativeMethods.GetWindowThreadProcessId(hwnd, pid) - Return pid - End Function - - Private Shared Function ByteArrayToString(ByVal bytes As Byte()) As String - If Environment.OSVersion.Platform = PlatformID.Win32Windows Then - Return Encoding.[Default].GetString(bytes).TrimEnd(vbNullChar) - Else - Return Encoding.Unicode.GetString(bytes).TrimEnd(vbNullChar) - End If - End Function -End Class diff --git a/Windows/Window.vb b/Windows/Window.vb index 08932317..7898fa24 100644 --- a/Windows/Window.vb +++ b/Windows/Window.vb @@ -1,4 +1,5 @@ -Imports System.Drawing +Imports System.ComponentModel +Imports System.Drawing Imports System.Runtime.InteropServices Imports System.Text Imports System.Windows.Forms @@ -7,6 +8,8 @@ Imports DigitalData.Modules.Logging Public Class Window Private _Logger As Logger + Private Const WINDOW_SNAP_OFFSET = 35 + Public Enum Anchor TopLeft BottomLeft @@ -387,4 +390,183 @@ Public Class Window Throw ex End Try End Function + + + Public Structure WINDOWPOS + Public hwnd As IntPtr + Public hwndInsertAfter As IntPtr + Public x As Integer + Public y As Integer + Public cx As Integer + Public cy As Integer + Public flags As Integer + End Structure + + Public Shared Sub SnapToDesktopBorder(pForm As Form, pLParam As IntPtr, Optional pWidthAdjustment As Integer = 0) + If pForm Is Nothing Then + ' Satisfies rule: Validate parameters + Throw New ArgumentNullException("pForm") + End If + + ' Snap client to the top, left, bottom or right desktop border + ' as the form is moved near that border + Try + ' Marshal the LPARAM value which is a WINDOWPOS struct + Dim oNewPosition As New WINDOWPOS + oNewPosition = CType(Marshal.PtrToStructure(pLParam, GetType(WINDOWPOS)), WINDOWPOS) + + If oNewPosition.y = 0 OrElse oNewPosition.x = 0 Then + Return ' Nothing to do! + End If + + ' Adjust the client size for borders and caption bar + Dim oClientRect As Rectangle = pForm.RectangleToScreen(pForm.ClientRectangle) + oClientRect.Width += SystemInformation.FrameBorderSize.Width - pWidthAdjustment + oClientRect.Height += (SystemInformation.FrameBorderSize.Height + SystemInformation.CaptionHeight) + + ' Now get the screen working area (without taskbar) + Dim oWorkingRect As Rectangle = System.Windows.Forms.Screen.GetWorkingArea(pForm.ClientRectangle) + + ' Left border + If oNewPosition.x >= oWorkingRect.X - WINDOW_SNAP_OFFSET AndAlso + oNewPosition.x <= oWorkingRect.X + WINDOW_SNAP_OFFSET Then + oNewPosition.x = oWorkingRect.X + End If + + ' Get screen bounds and taskbar height + ' (when taskbar is horizontal) + Dim oScreenRect As Rectangle = System.Windows.Forms.Screen.GetBounds(System.Windows.Forms.Screen.PrimaryScreen.Bounds) + Dim oTaskbarHeight As Integer = oScreenRect.Height - oWorkingRect.Height + + ' Top border (check if taskbar is on top + ' or bottom via WorkingRect.Y) + If oNewPosition.y >= -WINDOW_SNAP_OFFSET AndAlso + (oWorkingRect.Y > 0 AndAlso oNewPosition.y <= + (oTaskbarHeight + WINDOW_SNAP_OFFSET)) OrElse + (oWorkingRect.Y <= 0 AndAlso oNewPosition.y <= + (WINDOW_SNAP_OFFSET)) Then + If oTaskbarHeight > 0 Then + oNewPosition.y = oWorkingRect.Y ' Horizontal Taskbar + Else + oNewPosition.y = 0 ' Vertical Taskbar + End If + End If + + ' Right border + If oNewPosition.x + oClientRect.Width <= + oWorkingRect.Right + WINDOW_SNAP_OFFSET AndAlso + oNewPosition.x + oClientRect.Width >= + oWorkingRect.Right - WINDOW_SNAP_OFFSET Then + oNewPosition.x = oWorkingRect.Right - (oClientRect.Width + + SystemInformation.FrameBorderSize.Width) + End If + + ' Bottom border + If oNewPosition.y + oClientRect.Height <= + oWorkingRect.Bottom + WINDOW_SNAP_OFFSET AndAlso + oNewPosition.y + oClientRect.Height >= + oWorkingRect.Bottom - WINDOW_SNAP_OFFSET Then + oNewPosition.y = oWorkingRect.Bottom - (oClientRect.Height + + SystemInformation.FrameBorderSize.Height) + End If + + ' Marshal it back + Marshal.StructureToPtr(oNewPosition, pLParam, True) + Catch ex As ArgumentException + End Try + End Sub + + Public Class Utils + Private Shared GetControlNameMessage As Integer = 0 + + Public Shared Function GetWinFormsId(ByVal hWnd As IntPtr) As String + GetControlNameMessage = NativeMethods.RegisterWindowMessage("WM_GETCONTROLNAME") + Return XProcGetControlName(hWnd, GetControlNameMessage) + End Function + + Protected Shared Function XProcGetControlName(ByVal hwnd As IntPtr, ByVal msg As Integer) As String + Dim bytearray As Byte() = New Byte(65535) {} + Dim bufferMem As IntPtr = IntPtr.Zero + Dim written As IntPtr = IntPtr.Zero + Dim retHandle As IntPtr = IntPtr.Zero + Dim retVal As Boolean + Dim processHandle As IntPtr = IntPtr.Zero + Dim fileHandle As IntPtr = IntPtr.Zero + + If Not (Environment.OSVersion.Platform = PlatformID.Win32Windows) Then + + Try + Dim size As UInteger + size = 65536 + processHandle = NativeMethods.OpenProcess(NativeMethods.PROCESS_VM_OPERATION Or NativeMethods.PROCESS_VM_READ Or NativeMethods.PROCESS_VM_WRITE, False, GetProcessIdFromHWnd(hwnd)) + + If processHandle.ToInt64() = 0 Then + Throw New Win32Exception() + End If + + bufferMem = NativeMethods.VirtualAllocEx(processHandle, IntPtr.Zero, New UIntPtr(size), NativeMethods.MEM_RESERVE Or NativeMethods.MEM_COMMIT, NativeMethods.PageProtection.ReadWrite) + + If bufferMem.ToInt64() = 0 Then + Throw New Win32Exception() + End If + + retHandle = NativeMethods.SendMessage(hwnd, msg, New IntPtr(size), bufferMem) + retVal = NativeMethods.ReadProcessMemory(processHandle, bufferMem, bytearray, New UIntPtr(size), written) + + If Not retVal Then + Throw New Win32Exception() + End If + + Finally + retVal = NativeMethods.VirtualFreeEx(processHandle, bufferMem, New UIntPtr(0), NativeMethods.MEM_RELEASE) + + If Not retVal Then + Throw New Win32Exception() + End If + + NativeMethods.CloseHandle(processHandle) + End Try + Else + + Try + Dim size2 As Integer + size2 = 65536 + fileHandle = NativeMethods.CreateFileMapping(New IntPtr(NativeMethods.INVALID_HANDLE_VALUE), IntPtr.Zero, NativeMethods.PageProtection.ReadWrite, 0, size2, Nothing) + + If fileHandle.ToInt64() = 0 Then + Throw New Win32Exception() + End If + + bufferMem = NativeMethods.MapViewOfFile(fileHandle, NativeMethods.FILE_MAP_ALL_ACCESS, 0, 0, New UIntPtr(0)) + + If bufferMem.ToInt64() = 0 Then + Throw New Win32Exception() + End If + + NativeMethods.MoveMemoryFromByte(bufferMem, bytearray(0), size2) + retHandle = NativeMethods.SendMessage(hwnd, msg, New IntPtr(size2), bufferMem) + NativeMethods.MoveMemoryToByte(bytearray(0), bufferMem, 1024) + Finally + NativeMethods.UnmapViewOfFile(bufferMem) + NativeMethods.CloseHandle(fileHandle) + End Try + End If + + Return ByteArrayToString(bytearray) + End Function + + Private Shared Function GetProcessIdFromHWnd(ByVal hwnd As IntPtr) As UInteger + Dim pid As UInteger + NativeMethods.GetWindowThreadProcessId(hwnd, pid) + Return pid + End Function + + Private Shared Function ByteArrayToString(ByVal bytes As Byte()) As String + If Environment.OSVersion.Platform = PlatformID.Win32Windows Then + Return Encoding.[Default].GetString(bytes).TrimEnd(vbNullChar) + Else + Return Encoding.Unicode.GetString(bytes).TrimEnd(vbNullChar) + End If + End Function + End Class End Class diff --git a/Windows/Windows.vbproj b/Windows/Windows.vbproj index 9a4b1ab0..92b0b6dd 100644 --- a/Windows/Windows.vbproj +++ b/Windows/Windows.vbproj @@ -88,7 +88,6 @@ -