Wie funktionieren bestimmte API's richtig?

  • VB.NET

Es gibt 57 Antworten in diesem Thema. Der letzte Beitrag () ist von Xiantrius.

    Mir gefällt auch nicht alles, aber schön das du dich gemeldet hast. :)
    Noch etwas hab ich vergessen zu erwähnen aber lieber später als nie.

    Der Converter den du hier verlinkt hast ist recht gut, schade das ich so einen nicht als Tool, ohne abhängigkeit von netz habe.


    So hab mal die Funktion selbst geschrieben im inneren.
    Variable CheckHWND schaut der hwnd höher als 0 ist.
    Falls ja wird es bestätigt mit return true bestätigt, amsonsten return false nicht bestätigt um möglichen crash zu vermeiden.

    VB.NET-Quellcode

    1. Public Function Enumerate(ByVal hwnd As IntPtr, ByVal lParam As IntPtr) As Boolean
    2. Dim CheckHWND As Integer = CInt(hwnd)
    3. If CheckHWND > 0 Then
    4. Return True
    5. Else
    6. Return False
    7. End If
    8. End Function


    Falls das immer noch falsch ist wäre einer so nett mir den richtigen Code zu nennen?

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Xiantrius“ ()

    BitBrösel schrieb:

    aus lParam(2. Parameter) wird mit "GCHandle.FromIntPtr(lParam).Target" eine List(of IntPtr) gemach


    BitBrösel schrieb:

    Hab vergessen zu sagen, wenn die Liste nach dem casten nicht Nothing ist, wird noch das Handle zur in der Sub Funktion erstellen Liste hinzugefügt, dadurch ist sie in der Liste, die bei EnumChildWindows reingeht.


    Ich sehe nicht dein Problem, so macht das keinen Spaß hier. Du hast alle Informationen, einen Converter, Code.(Andere Programme fernsteuern) Wenn die Liaste nach dem casten Nothing ist, entweder False ausgeben oder anders wie z.B. RodFromGermany im Code reagieren.
    Ich will ja keine Anwendung steuern, sondern nur auslesen mein Tool heist nicht umsonst Windowed-Scanner.
    Habe eine andere API drin die scannt mit eine Funktion ob ein Spiel in Fullscreen ist, oder nicht.
    Funktioniert aber nicht bei allen spielen. Darum versuche ich mit der API EnumChildWindows was zu erreichen.

    Hauptziel ist:
    1. Wird geprüft ob das Spiel in Vollbild gestartet wurde. Leider geht es nicht bei jeden Spiel daher versuche ich das mit EnumChildWindows irgendwie festzustellen bei Spielen wo der bisherige Code versagt hat.

    2. Der Desktop soll sich die Auflösung merken und den Auflösungswert Wert zwischen speichern in einen variable integer wo es gerade hat das ist kein problem kriege ich auch alles hin.

    3. Solange die selbe Auflösung und frequenz haben wie das Spiel das ich in Prozess ausgesucht habe wird sich solange der Prozess offen ist die Desktopauflösung in die selbe Auflösung setzen wie das Spiel, wenn es vorrausgesetzt eine niedrigere, oder höhere Auflösung hat als der Desktop. Vorteil ist switche ich mit ALT+TAB aus dem Spiel muss die Pixelauflösung nicht neu berechnet werden, eben so wenig wenn ich wieder zurück ins Spiel switche.

    4. Dannach soll er die ursprüngliche Auflösung von Desktop wiederherstellen sobald das Spiel beendet wurde.

    Xiantrius schrieb:

    Der Converter den du hier verlinkt hast ist recht gut, schade das ich so einen nicht als Tool, ohne abhängigkeit von netz habe.

    In meiner Signatur, habe ich mehrere Konverter verlinkt (online und offline), suche dir einen aus.
    Ich empfehle die VS-Extension.
    Hallo @FormFollowsFunction
    danke werde ich mir anschauen.
    Also dein Empfohlener Converter hab ich angetestet, sieht sehr vielversprechend aus.

    So muss jetzt los zur Arbeit melde mich gelegentlich zurück wenn jemand schreibt.

    Im Zuge der Moderation (siehe Modpost unten) habe ich hier etwas gekürzt. ~Thunderbolt

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „Thunderbolt“ ()

    Ui, hier ging es ja heiß her. Ich habe etwas aufgeräumt; das waren doch einige Nebengespräche, die sich jetzt (hoffentlich) geklärt haben.

    Halten wir fest: Xiantrius hat mehrfach bekräftigt, an einer Lernverzögerung zu leiden. Daher dauert ein tiefes Verständnis einfach länger. Ich sehe keinen Anlass, das zu bezweifeln. Die Diskussion darüber hat sich doch etwas aufgeschaukelt. Meine Bitte an euch alle: Einmal durchatmen, niemand möchte euch persönlich kränken oder ärgern — manchmal ist man jedoch selbst in einer Situation so involviert, dass man umgangssprachlich „angefressen“ wird. Zwischenmenschliche Kommunikation ist kompliziert. Lasst uns hier etwas abkühlen und noch einmal neu beginnen. Danke.
    Mit freundlichen Grüßen,
    Thunderbolt
    Guten morgen zusammen:

    Ich hab gestern abend verbracht um von @RodFromGermany den C# QuellCode zu convertieren.
    Wird eh noch nicht alles funktionieren. Poste aber mal trotzdem die Übersetzung.
    Vielleicht können wir ja gemeinsam die Puzzleteile irgendwie zusammen setzen.
    Das ist echt verdammt viel Code für das man nur ein kleines Ziel erreichen will, aber naja ich hab damit angefangen und hoffe das ich es mit eure Hilfe besser schaffe.

    Es geht normalerweise viel einfacher um auf eigene Buttons Textboxen in der Form zuzugreifen, aber der Code soll später auf andere Prozesse zugreifen die Form finden und alle Classnamen und Handles inhalb der fremden Form finden.

    1. Zuerst mal den Code irgendwie durch gehen vermute sehr stark das da noch Fehler sind.
    2. Damit ich das Grundprinzip verstehe habe ich es mir zunext zur Aufgabe gemacht mit den Code es irgendwie zu schaffen auf die 3 Buttons auszulesen.

    Spoiler anzeigen

    VB.NET-Quellcode

    1. 'Das Aller Wichtigste das nie fehlen darf.
    2. Option Strict On
    3. Public Class Form1
    4. 'Aus C# von RodFromGermany sein tutorial erst mal Konvertiert in VB.NET.
    5. 'Dank FormFollowsFunction seine Empfehlung zum Converter C# >>> VB.NET den man Offline betreiben kann.
    6. 'Das Sind Sendmessage Parameter
    7. Public Const WM_LBUTTONDOWN = &H201
    8. Public Const WM_LBUTTONUP = &H202
    9. Public Const WM_KEYDOWN = &H100
    10. Public Const WM_KEYUP = &H101
    11. Public Const WM_CHAR = &H102
    12. Public Const WM_SETTEXT = &HC
    13. Public Const BM_SETCHECK As Integer = &HF1
    14. 'Hier wird Prozess varialbe und MainWindowHandle variable gemacht.
    15. Private Prozess As Process
    16. Private MainWnd As IntPtr
    17. Private Sub ProzessDefinieren()
    18. Prozess = Process.Start("FernsteuerungTestGui.exe")
    19. Dim prAll As Process() = Process.GetProcessesByName("FernsteuerungTestGui")
    20. Prozess = prAll(0)
    21. MainWnd = Prozess.MainWindowHandle
    22. End Sub
    23. Private Delegate Function EnumWindowProc(hWnd As IntPtr, parameter As IntPtr) As Boolean
    24. <Runtime.InteropServices.DllImport("user32")>
    25. Private Shared Function EnumChildWindows(window As IntPtr, callback As EnumWindowProc, listHandle As IntPtr) As <Runtime.InteropServices.MarshalAs(Runtime.InteropServices.UnmanagedType.Bool)> Boolean
    26. End Function
    27. Public Shared Function GetChildWindows(parent As IntPtr) As List(Of IntPtr)
    28. Dim result As New List(Of IntPtr)()
    29. Dim listHandle As Runtime.InteropServices.GCHandle = Runtime.InteropServices.GCHandle.Alloc(result)
    30. Try
    31. Dim childProc As New EnumWindowProc(AddressOf EnumWindow)
    32. EnumChildWindows(parent, childProc, Runtime.InteropServices.GCHandle.ToIntPtr(listHandle))
    33. Finally
    34. ' ordentlich aufräumen, falls was passiert, denn das sind unmanaged Ressourcen
    35. If listHandle.IsAllocated Then
    36. listHandle.Free()
    37. End If
    38. End Try
    39. Return result
    40. End Function
    41. Private Shared Function EnumWindow(handle As IntPtr, pointer As IntPtr) As Boolean
    42. Dim gch As Runtime.InteropServices.GCHandle = Runtime.InteropServices.GCHandle.FromIntPtr(pointer)
    43. Dim list As List(Of IntPtr) = TryCast(gch.Target, List(Of IntPtr))
    44. If list Is Nothing Then
    45. Throw New InvalidCastException("GCHandle Target could not be cast as List<IntPtr>")
    46. End If
    47. list.Add(handle)
    48. ' You can modify this to check to see if you want to cancel the operation, then return a null here
    49. Return True
    50. End Function
    51. Dim childs As List(Of IntPtr) = GetChildWindows(MainWnd)
    52. <Runtime.InteropServices.DllImport("user32.dll", CharSet:=Runtime.InteropServices.CharSet.Unicode)>
    53. Public Shared Function SendMessage(hwnd As IntPtr, wMsg As Integer, wParam As IntPtr, lParam As String) As IntPtr
    54. End Function
    55. <Runtime.InteropServices.DllImport("user32.dll", CharSet:=Runtime.InteropServices.CharSet.Ansi)>
    56. Public Shared Function SendMessageInt(hwnd As IntPtr, uMsg As Integer, wParam As Integer, lParam As Integer) As Integer
    57. End Function
    58. <Runtime.InteropServices.DllImport("user32.dll", CharSet:=Runtime.InteropServices.CharSet.Auto)>
    59. Public Shared Function PostMessage(ByVal hhwnd As IntPtr, ByVal msg As UInt32, ByVal wparam As IntPtr, ByVal lparam As IntPtr) As Boolean
    60. End Function
    61. 'Private Sub btnStart_Click(sender As Object, e As EventArgs)
    62. ' Prozess = New Process()
    63. ' AddHandler Prozess.Exited, AddressOf TextBox1
    64. ' Prozess.StartInfo.FileName = "FernsteuerungTestGui.exe"
    65. ' Prozess.Start()
    66. ' Prozess.WaitForInputIdle()
    67. ' MainWnd = Prozess.MainWindowHandle
    68. 'End Sub
    69. Private Sub btnEnumWnd_Click(sender As Object, e As EventArgs)
    70. Dim childs As List(Of IntPtr) = GetChildWindows(MainWnd)
    71. Dim i As Integer = 0
    72. While i < childs.Count
    73. SendMessage(childs(i), WM_SETTEXT, IntPtr.Zero, i.ToString())
    74. i += 1
    75. End While
    76. End Sub
    77. <Runtime.InteropServices.DllImport("user32.dll", SetLastError:=True, CharSet:=Runtime.InteropServices.CharSet.Auto)>
    78. Public Shared Function FindWindow(ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
    79. End Function
    80. <Runtime.InteropServices.DllImport("user32.dll", CharSet:=Runtime.InteropServices.CharSet.Unicode)>
    81. Public Shared Function FindWindowEx(parentHandle As IntPtr, childAfter As IntPtr, className As String, windowTitle As String) As IntPtr
    82. End Function
    83. Private Sub BTN1()
    84. Dim btn As IntPtr = FindWindowEx(MainWnd, IntPtr.Zero, "Button", "Button1")
    85. SendMessage(btn, WM_SETTEXT, IntPtr.Zero, "Button2")
    86. Dim [next] As IntPtr = IntPtr.Zero
    87. Dim i As Integer = 0
    88. ' Endlosschleife über alle Controls gleicher Window-Klasse
    89. While True
    90. Dim btn2 As IntPtr = FindWindowEx(MainWnd, [next], "Button", Nothing)
    91. If btn2 = IntPtr.Zero Then
    92. ' Abbruchkriterium
    93. Exit While
    94. End If
    95. SendMessage(btn2, WM_SETTEXT, IntPtr.Zero, "bla")
    96. i += 1
    97. [next] = btn2
    98. End While
    99. End Sub
    100. Private Sub Nexter1()
    101. Dim Nexter As IntPtr = IntPtr.Zero
    102. Dim allWnd As New List(Of IntPtr)()
    103. Dim lbl1 As IntPtr = FindWindowEx(MainWnd, Nexter, "Static", "")
    104. Dim lbl2 As IntPtr = FindWindowEx(MainWnd, Nexter, "Static", Nothing)
    105. ' Endlosschleife über alle Controls gleicher Window-Klasse
    106. While True
    107. Dim wnd As IntPtr = FindWindowEx(MainWnd, Nexter, Nothing, Nothing)
    108. If wnd = IntPtr.Zero Then
    109. ' Abbruchkriterium
    110. Exit While
    111. End If
    112. allWnd.Add(wnd)
    113. Nexter = wnd
    114. End While
    115. End Sub
    116. Private Sub BTN2()
    117. Dim [next] As IntPtr = IntPtr.Zero
    118. Dim i As Integer = 0
    119. ' Endlosschleife über alle Controls gleicher Window-Klasse
    120. While True
    121. Dim btn2 As IntPtr = FindWindowEx(MainWnd, [next], "Button", Nothing)
    122. If btn2 = IntPtr.Zero Then
    123. ' Abbruchkriterium
    124. Exit While
    125. End If
    126. SendMessage(btn2, WM_SETTEXT, IntPtr.Zero, "bla")
    127. i += 1
    128. [next] = btn2
    129. End While
    130. End Sub
    131. Private Sub GleicheNamen()
    132. Dim Nexter As IntPtr = IntPtr.Zero
    133. Dim allWnd As New List(Of IntPtr)()
    134. ' Endlosschleife über alle Controls gleicher Window-Klasse
    135. While True
    136. Dim wnd As IntPtr = FindWindowEx(MainWnd, Nexter, Nothing, Nothing)
    137. If wnd = IntPtr.Zero Then
    138. ' Abbruchkriterium
    139. Exit While
    140. End If
    141. allWnd.Add(wnd)
    142. Nexter = wnd
    143. End While
    144. End Sub
    145. 'Dim ptr As IntPtr = FindWindowEx(MainWnd, IntPtr.Zero, className, wndText)
    146. Public Const BM_CLICK As Integer = &HF5
    147. Public Shared Sub ClickButtonMethode1(hwnd As IntPtr)
    148. SendMessage(hwnd, BM_CLICK, IntPtr.Zero, Nothing)
    149. End Sub
    150. Public Shared Sub ClickButtonMethode2(hwnd As IntPtr)
    151. PostMessage(hwnd, BM_CLICK, IntPtr.Zero, Nothing)
    152. End Sub
    153. Dim check As IntPtr = FindWindowEx(MainWnd, IntPtr.Zero, "Button", "Check1")
    154. '<Runtime.InteropServices.DllImport("user32.dll", EntryPoint:="GetClassNameW")>
    155. 'Public Shared Function GetClassNameW(ByVal hWnd As IntPtr, <Runtime.InteropServices.MarshalAs(Runtime.InteropServices.UnmanagedType.LPWStr)> ByVal lpClassName As System.Text.StringBuilder, ByVal nMaxCount As Integer) As Integer
    156. 'End Function
    157. <Runtime.InteropServices.DllImport("user32.dll", CharSet:=Runtime.InteropServices.CharSet.Auto)>
    158. Public Shared Function GetClassName(ByVal hWnd As System.IntPtr, ByVal lpClassName As System.Text.StringBuilder, ByVal nMaxCount As Integer) As Integer
    159. End Function
    160. Dim ClassID As IntPtr
    161. Private Sub cbCheck_CheckedChanged(sender As Object, e As EventArgs) Handles cbCheck.CheckedChanged
    162. Dim check As IntPtr = FindWindowEx(MainWnd, IntPtr.Zero, CStr(GetClassName(ClassID, Nothing, 0)), "Check1")
    163. Dim value As Integer = If(cbCheck.Checked, 0, 1)
    164. ' Achtung: Anders herum, BM_SETCHECK invertiert, löst aber nicht aus.
    165. SendMessageInt(check, BM_SETCHECK, value, 0)
    166. ClickButtonMethode1(check)
    167. End Sub
    168. <Runtime.InteropServices.DllImport("user32.dll")>
    169. Public Shared Function GetWindow(hwnd As IntPtr, nID As IntPtr) As IntPtr
    170. End Function
    171. <Runtime.InteropServices.DllImport("user32.dll")>
    172. Public Shared Function GetWindowText(hWnd As IntPtr, returnedString As System.Text.StringBuilder, nMaxCount As Integer) As Integer
    173. End Function
    174. <Runtime.InteropServices.DllImport("user32.dll")>
    175. Public Shared Function GetParent(hwnd As IntPtr) As IntPtr
    176. End Function
    177. Public Const GW_HWNDFIRST As Integer = 0
    178. Public Const GW_HWNDNEXT As Integer = 2
    179. Private Function GetDlgWindow(title As String) As IntPtr
    180. Dim hWndNext As IntPtr = GetWindow(FindWindow(CStr(IntPtr.Zero), CStr(IntPtr.Zero)), CType(GW_HWNDFIRST, IntPtr))
    181. Dim space As New System.Text.StringBuilder(&H200)
    182. While hWndNext <> IntPtr.Zero
    183. If (GetWindowText(hWndNext, space, space.Capacity) > 0) AndAlso space.ToString().StartsWith(title) AndAlso (GetParent(hWndNext) = MainWnd) Then
    184. Return hWndNext
    185. End If
    186. hWndNext = GetWindow(hWndNext, CType(GW_HWNDNEXT, IntPtr))
    187. End While
    188. Return IntPtr.Zero
    189. End Function
    190. Private Sub button_Click(sender As Object, e As EventArgs) Handles Button4.Click
    191. If ListView1.Items.Count > 0 Then
    192. If ListView1.SelectedIndices.Count >= 0 Then
    193. Dim index As Integer
    194. If sender.ToString = Button1.Name.ToString Then
    195. index = 0
    196. ElseIf sender.ToString = Button2.Name.ToString Then
    197. index = 1
    198. ElseIf sender.ToString = Button3.Name.ToString Then
    199. index = 2
    200. End If
    201. Dim box As IntPtr = GetDlgWindow("Andere_Programme_fernsteuern") 'ListView1.SelectedItems(0).SubItems(2).Text)
    202. If box = IntPtr.Zero Then
    203. MessageBox.Show("Fenster nicht gefunden")
    204. Return
    205. End If
    206. If RadioButton1.Checked Then
    207. ' Methode GetChildWindows
    208. Dim childs As List(Of IntPtr) = GetChildWindows(box)
    209. ' Button auslösen
    210. ClickButtonMethode1(childs(index))
    211. Else
    212. ' Methode FindWindowEx
    213. Dim Nexter As IntPtr = IntPtr.Zero
    214. Dim i As Integer = 0
    215. While i <= index
    216. Dim btn As IntPtr = FindWindowEx(box, Nexter, CStr(GetClassName(ClassID, Nothing, 0)), Nothing)
    217. Nexter = btn
    218. i += 1
    219. End While
    220. ' Button auslösen
    221. ClickButtonMethode1(Nexter)
    222. End If
    223. End If
    224. End If
    225. End Sub
    226. 'Das hab ich gemacht
    227. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    228. MsgBox("JA wurde per Fernsteuerung geklickt.")
    229. End Sub
    230. Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    231. MsgBox("NEIN wurde per Fernsteuerung geklickt")
    232. End Sub
    233. Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
    234. MsgBox("ABBRECHEN wurde per Fernsteuerung geklickt")
    235. End Sub
    236. 'Ab hier ist der Code von mir ist für andere Prozesse gedacht.
    237. Private Sub AutoSizeListViewColumns(oListView As ListView)
    238. SuspendLayout()
    239. For nCol = 0 To oListView.Columns.Count - 1
    240. oListView.Columns(nCol).Width = -1 'forces autosizing on column
    241. If oListView.Columns(nCol).Width < 100 Then
    242. oListView.Columns(nCol).Width = 100
    243. End If
    244. Next
    245. oListView.Refresh()
    246. ResumeLayout()
    247. End Sub
    248. Dim CheckColumn As Boolean
    249. Private Sub Prozessliste()
    250. If CheckColumn = False Then
    251. CheckColumn = True
    252. ListView1.FullRowSelect = True
    253. ListView1.Columns.Add("FensterHandle")
    254. ListView1.Columns.Add("Fensternamen")
    255. ListView1.Columns.Add("Prozesse")
    256. ListView1.Columns.Add("Prozess-ID")
    257. ElseIf CheckColumn = True Then
    258. End If
    259. ListView1.Items.Clear()
    260. For Each Alle_Prozesse In Process.GetProcesses()
    261. If Alle_Prozesse.MainWindowHandle.ToInt32 > 0 Then
    262. With ListView1.Items.Add(Hex(Alle_Prozesse.MainWindowHandle.ToString))
    263. .SubItems.Add(Alle_Prozesse.MainWindowTitle)
    264. .SubItems.Add(Alle_Prozesse.ProcessName)
    265. .SubItems.Add(Hex(Alle_Prozesse.Id.ToString))
    266. End With
    267. End If
    268. Next
    269. If ListView1.Items.Count > 0 Then
    270. AutoSizeListViewColumns(ListView1)
    271. End If
    272. End Sub
    273. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    274. Prozessliste()
    275. End Sub
    276. End Class

    Xiantrius schrieb:

    VB.NET-Quellcode

    1. <Runtime.InteropServices.DllImport("user32.dll", CharSet:=Runtime.InteropServices.CharSet.Ansi)>
    2. Public Shared Function SendMessageInt(hwnd As IntPtr, uMsg As Integer, wParam As Integer, lParam As Integer) As Integer
    3. End Function
    Sieh Dir die Vorlage aus diesem Post noch mal gaaaaaaaaaaaaaaaaaaaaaaaaaaaaaanz genau an.
    Du hast da einige Prozeduren, die nicht verwendet werden.
    Was passiert, was soll passieren?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Wie ich bereits sagte, das ist erst alles übersetzt und ist jetzt wie Puzzleteile die noch rum fliegen und nicht passend zusammen gesetzt sind.
    Ich weis ja nicht worauf du genau hinaus willst.

    Hat warscheinlich damit zu tun...

    VB.NET-Quellcode

    1. Dim ClassID As IntPtr
    2. Private Sub cbCheck_CheckedChanged(sender As Object, e As EventArgs) Handles cbCheck.CheckedChanged
    3. Dim check As IntPtr = FindWindowEx(MainWnd, IntPtr.Zero, CStr(GetClassName(ClassID, Nothing, 0)), "Button1")
    4. Dim value As Integer = If(cbCheck.Checked, 0, 1)
    5. ' Achtung: Anders herum, BM_SETCHECK invertiert, löst aber nicht aus.
    6. SendMessageInt(check, BM_SETCHECK, CType(value, IntPtr), 0)
    7. ClickButtonMethode1(check)
    8. End Sub


    Fehler:
    System.EntryPointNotFoundException: "Der Einstiegspunkt "SendMessageInt" wurde nicht in der DLL "user32.dll" gefunden."

    Ok sehe schon Sendmessage >>int<< muss weg.

    muss auch schon wieder bald los zum Arzttermin und muss dann zur Arbeit.


    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Xiantrius“ ()

    Xiantrius schrieb:

    If Alle_Prozesse.MainWindowHandle.ToInt32 > 0 Then

    Hier musst du das Handle nicht zu einem Integer machen, du kannst bei IntPtr so testen ob die ungleich 0 sind.

    VB.NET-Quellcode

    1. If Alle_Prozesse.MainWindowHandle <> IntPtr.Zero Then


    Diesen Test hatte ich als ich das Video aufnahm nicht drin, war ja zu sehen an der gefluteten Debug-Ausgabe. Wenn das Handle 0 ist, wird alles, wirklich alles gelistet, da das durchaus bei mehreren Prozessen der Fall sein kann weil nicht jeder Prozess ein Fenster hat, war das in der schleife bei mir Unsinn, das nicht zu tun.

    Der Name "Alle_Prozesse" passt nicht so ganz. Alle_Prozesse ist zwar je einmal jeder einzelne Prozess, aber nie alle Zeitgleich.

    Xiantrius schrieb:

    Dim childs As List(Of IntPtr) = GetChildWindows(MainWnd)


    Diese Liste würde ich so nicht erstellen, wenn diese Klasse erstellt wird, wird GetChildWindows ausgeführt, was zu diesem Zeitpunkt aber noch nicht nötig ist.

    VB.NET-Quellcode

    1. Dim childs As List(Of IntPtr) = New List(Of IntPtr)


    Bei btnEnumWnd_Click wird sie ja jedes mal zugewiesen(was ja richtig ist), so kannst du den ersten Durchlauf beim starten des Programms bevor du überhaupt auf den Button geklickt hast einsparen.

    Damit du nun was zu experimentieren hast, hier nun doch meine "Enumerate Funktion", ich hatte erst wie gesagt wenn die Liste Nothing nach dem casten ist False ausgeben, ich hab das nun verändert und werfe eine Exception, wie das auch RodFromGermany macht. Auch das prüfen ob das Handle ungleich 0 ist.

    Wenn du das Debug-Ausgabe Fenster nicht offen hast drücke STRG+ALT+O zeitgleich beim ausführen des Codes, dann siehst du was Debug.WriteLine schreibt, hast du bereits bei mir im Video gesehen. Teste das erstmal in einem anderen Projekt, dann hast du ein funktionierendes Demo-Projekt. Dann in dein Projekt einbauen. Ich wollte dir die FUnktion Enumerate zwar nicht verraten, aber ich denke du hast genug zu tun, das in dein Projekt zu bekommen.

    VB.NET-Quellcode

    1. Option Strict On
    2. Imports System.Runtime.InteropServices
    3. Imports System.Text
    4. Public Class Form1
    5. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    6. For Each p As Process In Process.GetProcesses()
    7. Dim windowHandle As IntPtr = p.MainWindowHandle
    8. If windowHandle <> IntPtr.Zero Then
    9. Dim childList As List(Of IntPtr) = New List(Of IntPtr)()
    10. Dim childListHandle As GCHandle = GCHandle.Alloc(childList)
    11. Dim enumChildWindows As New Win32.EnumWindowsProc(AddressOf Enumerate)
    12. If Not Win32.EnumChildWindows(windowHandle, enumChildWindows, GCHandle.ToIntPtr(childListHandle)) Then
    13. MessageBox.Show("ErrorCode: " & Marshal.GetLastWin32Error())
    14. End If
    15. If childListHandle.IsAllocated Then
    16. childListHandle.Free()
    17. End If
    18. For Each childHandle As IntPtr In childList
    19. Dim windowTextLength As Integer = Win32A.GetWindowTextLengthA(childHandle)
    20. Dim stringBuilder As StringBuilder
    21. If windowTextLength > 0 Then
    22. stringBuilder = New StringBuilder
    23. stringBuilder.Capacity = windowTextLength + 1
    24. Dim copiedCharsCount As Integer = Win32A.GetWindowTextA(childHandle, stringBuilder, windowTextLength + 1)
    25. If copiedCharsCount = windowTextLength Then
    26. Debug.WriteLine(stringBuilder.ToString())
    27. End If
    28. Else
    29. Debug.WriteLine("childHandle: " & childHandle.ToString() & " hat keinen Text")
    30. End If
    31. Next
    32. End If
    33. Next
    34. End Sub
    35. Private Function Enumerate(hWnd As IntPtr, lParam As IntPtr) As Boolean
    36. Dim childList As List(Of IntPtr) = TryCast(GCHandle.FromIntPtr(lParam).Target, List(Of IntPtr))
    37. If childList Is Nothing Then
    38. Throw New Exception("childList in Enumrate ist Nothing!")
    39. End If
    40. childList.Add(hWnd)
    41. Return True
    42. End Function
    43. End Class



    PS.
    Beachte das dies hier nur funktioniert, wenn SetLastError auf True gestellt ist, in der API Deklaration, siehe in dem Post von mir wo das Video war nach, das ist nun Code.

    VB.NET-Quellcode

    1. MessageBox.Show("ErrorCode: " & Marshal.GetLastWin32Error())


    PPS.
    @Panter
    Deinen Post dazwischen hatte ich nicht bemerkt, die Funktion ist nun hier zu sehen.

    Ich editiere den Post wo das Video war noch einmal, dann ist mein Samplecode dort komplett.

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „BitBrösel“ ()

    @BitBrösel

    Ich habe mein Code nun auch vollstänidg eingestellt.
    Bin ich auf dem richtigen weg?
    Die childList ist ein Referenztyp - der dann wieder in der Funktion Enumerate mit TryCast weiterverwendet wird. Dazu wird dieses GCHandle verwendet.
    In meinem Code hatte ich ja eine Datatable erstellt auf die ich immer zugreifen kann...


    VB.NET-Quellcode

    1. Dim childList As List(Of IntPtr) = New List(Of IntPtr)()
    2. Dim childListHandle As GCHandle = GCHandle.Alloc(childList)
    3. If Not Win32.EnumChildWindows(windowHandle, enumChildWindows, GCHandle.ToIntPtr(childListHandle)) Then
    4. Dim childList As List(Of IntPtr) = TryCast(GCHandle.FromIntPtr(lParam).Target, List(Of IntPtr))
    Das kann ich anhand dieser wenigen Codezeilen nicht beurteilen. Ich habe in deinem Post davor gesehen, das du in der Delegaten-Funktion zu viel Code hast, dort kommt nur rein, was ich oben gezeigt habe. In Zeile 21 kannst du sehen

    VB.NET-Quellcode

    1. For Each childHandle As IntPtr In childList

    dort gehe ich alle Handles durch. Alle gefundenen Handles sind nachdem EnumChildWindows erfolgreich in der List(Of IntPtr), die ich in Form_Load erstellt habe.

    @Panter
    Du hast auch nur eine Tabelle, ein Process hat viele Fenster, auch Steuerelemente sind Fenster, die werden auch mit den CreateWindow(Ex) APIs erstellt. Ein ParentChildView wäre richtig, Parent Tabelle Daten vom Prozess, die untergeordnete Tabelle, die Fensterdaten vom Prozess.

    Damit das leichter zu verstehen ist, habe ich eine weitere Funktion hinzugefügt, die Funktionen Enumerate und GetWindowHandlesFromProcess sind fertig, dort alles lassen wie es ist.

    VB.NET-Quellcode

    1. Option Strict On
    2. Imports System.Runtime.InteropServices
    3. Imports System.Text
    4. Public Class Form1
    5. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    6. For Each p As Process In Process.GetProcesses()
    7. Dim windowHandle As IntPtr = p.MainWindowHandle
    8. If windowHandle <> IntPtr.Zero Then
    9. Dim childList As List(Of IntPtr) = GetWindowHandlesFromProcess(p)
    10. For Each childHandle As IntPtr In childList
    11. Dim windowTextLength As Integer = Win32A.GetWindowTextLengthA(childHandle)
    12. Dim stringBuilder As StringBuilder
    13. If windowTextLength > 0 Then
    14. stringBuilder = New StringBuilder
    15. stringBuilder.Capacity = windowTextLength + 1
    16. Dim copiedCharsCount As Integer = Win32A.GetWindowTextA(childHandle, stringBuilder, windowTextLength + 1)
    17. If copiedCharsCount = windowTextLength Then
    18. Debug.WriteLine(stringBuilder.ToString())
    19. End If
    20. Else
    21. Debug.WriteLine("childHandle: " & childHandle.ToString() & " hat keinen Text")
    22. End If
    23. Next
    24. End If
    25. Next
    26. End Sub
    27. Private Function GetWindowHandlesFromProcess(process As Process) As List(Of IntPtr)
    28. Dim childList As List(Of IntPtr) = New List(Of IntPtr)()
    29. Dim childListHandle As GCHandle = GCHandle.Alloc(childList)
    30. Dim enumChildWindows As New Win32.EnumWindowsProc(AddressOf Enumerate)
    31. If Not Win32.EnumChildWindows(process.MainWindowHandle, enumChildWindows, GCHandle.ToIntPtr(childListHandle)) Then
    32. MessageBox.Show("ErrorCode: " & Marshal.GetLastWin32Error())
    33. End If
    34. If childListHandle.IsAllocated Then
    35. childListHandle.Free()
    36. End If
    37. Return childList
    38. End Function
    39. Private Function Enumerate(hWnd As IntPtr, lParam As IntPtr) As Boolean
    40. Dim childList As List(Of IntPtr) = TryCast(GCHandle.FromIntPtr(lParam).Target, List(Of IntPtr))
    41. If childList Is Nothing Then
    42. Throw New Exception("childList in Enumrate ist Nothing!")
    43. End If
    44. childList.Add(hWnd)
    45. Return True
    46. End Function
    47. End Class

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „BitBrösel“ ()

    Xiantrius schrieb:

    Ich weis ja nicht worauf du genau hinaus willst.
    Sieh Dir einfach beide Deklarationen an, wenn Du sie ins Notepad++ packst.
    Was passiert, wenn Du diese Funktion aufrufst?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ich habe eben einen Fehler in meinen Code gesehen, die Zeile mit der MessageBox kann nie erreicht werden, mögliche Korrekturen:
    >Anstatt die Exception zu werfen False returnen
    >Den Fehlercode gleich mit in den Text für die Exception einbauen.(MessageBox wird auch nicht gezeigt, aber dafür hat man den Fehlercode)
    >wie 2, aber den If Test weglassen und einen Try/Catch-Block benutzen



    Auch eine Verbesserung hab ich noch, die Fehlercodes sagen als Zahl nicht viel aus, es sei denn, man kennt diese bereits oder sieht bei Microsoft nach. Mit einer System.ComponentModel.Win32Exception lässt sich aus dem Fehlercode eine brauchbarere Meldung machen.

    VB.NET-Quellcode

    1. Dim ex As New System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error())
    2. MessageBox.Show("Error: " & ex.Message)

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „BitBrösel“ ()

    Ich schätze das Expeption ist bestimmt besser.
    Als alternative ginge auch.

    VB.NET-Quellcode

    1. 'geht eigentlich auch, aber bestimmt nicht überall.
    2. Msgbox(Error.tostring)
    3. 'oder
    4. MessageBox.Show(Error.tostring)

    Xiantrius schrieb:

    Als alternative ginge auch
    Eher nicht.
    Marshal.GetLastWin32Error() gibt den Fehlercode zurück.
    Mit System.ComponentModel.Win32Exception(...) bekommst Du eine mehr oder weniger sinnvolle Beschreibung zu dieser Fehlernummer.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hallo Xiantrius

    Was fehlt nun eigentlich noch? BitBrösel hat ja nun den Code angegeben.

    Mein Code ist nun auch fertig - meiner Ansicht nach funktioniert er gut, ist einfach eine Vereinfachung von BitBrösels Code - es wurden ein paar fortgeschrittene Elemente weggelassen. Anbei noch mein fertiger Code, gemäss deinen Wünschen, inkl. ClassName. Du benötigst nur eine Form mit einem DatagridView1 und sonst läuft es, wie Du es in der 1. Post gewünscht hast (einfach statt eine Listbox ein Datagridview).

    VB.NET-Quellcode

    1. Imports System.Diagnostics
    2. Imports Microsoft.VisualBasic
    3. Public Class Aktives_Fenster
    4. Dim dt As New DataTable
    5. Dim dv As New DataView(dt)
    6. Dim Parent_Handle As IntPtr
    7. Private Sub Aktives_Fenster_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    8. With dt.Columns
    9. .Add("Handle", Type.GetType("System.Int64"))
    10. .Add("Handle_child", Type.GetType("System.Int64"))
    11. .Add("ClassName", Type.GetType("System.String"))
    12. .Add("MainWindowTitle", Type.GetType("System.String"))
    13. End With
    14. DataGridView1.DataSource = dv
    15. ' alle Prozesse durchlaufen
    16. For Each oProcess As Process In Process.GetProcesses
    17. If oProcess.MainWindowHandle <> IntPtr.Zero Then
    18. Dim windowHandle As IntPtr = oProcess.MainWindowHandle
    19. Dim row As DataRow = dt.NewRow()
    20. row!Handle = windowHandle.ToString
    21. row!MainWindowTitle = GetActiveWindowText(windowHandle) 'oProcess.MainWindowTitle.ToString
    22. row!ClassName = ClassName(windowHandle)
    23. dt.Rows.Add(row)
    24. Parent_Handle = windowHandle
    25. GetChild(windowHandle)
    26. End If
    27. Next
    28. dv.Sort = "Handle ASC"
    29. End Sub
    30. Public Function Enumerate(hWnd As IntPtr, lParam As IntPtr) As Boolean
    31. Dim row As DataRow = dt.NewRow()
    32. row!Handle = Parent_Handle.ToInt64
    33. row!Handle_child = CInt(hWnd.ToString)
    34. row!Classname = ClassName(hWnd)
    35. row!MainWindowTitle = GetActiveWindowText(hWnd)
    36. dt.Rows.Add(row)
    37. Return True
    38. End Function
    39. Public Function GetChild(hwnd As IntPtr) As Boolean
    40. Dim x As Boolean
    41. x = EnumChildWindows(hwnd, AddressOf Enumerate, CType(0, IntPtr))
    42. Return True
    43. End Function
    44. End Class


    und das Modul:

    VB.NET-Quellcode

    1. Imports System.Runtime.InteropServices
    2. Imports System.Text
    3. Module Module1
    4. <DllImport("user32.dll", SetLastError:=True)>
    5. Private Function GetForegroundWindow() As IntPtr
    6. End Function
    7. <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
    8. Private Function GetWindowText(ByVal hwnd As IntPtr, ByVal lpString As StringBuilder, ByVal cch As Integer) As Integer
    9. End Function
    10. <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
    11. Private Function GetWindowTextLength(ByVal hwnd As IntPtr) As Integer
    12. End Function
    13. 'no specific Charset APIs
    14. <DllImport("user32.dll", SetLastError:=True)>
    15. Public Function EnumChildWindows(hWndParent As IntPtr, lpEnumFunc As EnumWindowsProc, lParam As IntPtr) As Boolean
    16. End Function
    17. Public Delegate Function EnumWindowsProc(hWnd As IntPtr, lParam As IntPtr) As Boolean
    18. ' int GetClassName(
    19. ' [in] HWND hWnd,
    20. ' [out] LPTSTR lpClassName,
    21. ' [in] int nMaxCount
    22. ');
    23. <Runtime.InteropServices.DllImport("user32.dll", CharSet:=Runtime.InteropServices.CharSet.Auto)>
    24. Public Function GetClassName(ByVal hWnd As System.IntPtr, ByVal lpClassName As System.Text.StringBuilder, ByVal nMaxCount As Integer) As Integer
    25. End Function
    26. Public Function GetActiveWindowText(hWnd As IntPtr) As String
    27. Dim length As Integer ', hWnd As IntPtr = GetForegroundWindow()
    28. If hWnd.ToInt32 = 0 Then
    29. Return Nothing
    30. End If
    31. length = GetWindowTextLength(hWnd)
    32. If length = 0 Then
    33. Return Nothing
    34. End If
    35. Dim sb As New System.Text.StringBuilder("", length)
    36. GetWindowText(hWnd, sb, sb.Capacity + 1)
    37. Return sb.ToString()
    38. End Function
    39. Public Function ClassName(hwnd As IntPtr) As String
    40. Dim sClassName As New StringBuilder("", 256)
    41. 'pass in the handle of the object for which to get
    42. 'the class name; for example, the form's handle
    43. Call GetClassName(hwnd, sClassName, 256)
    44. Return sClassName.ToString
    45. End Function
    46. End Module

    Da haste dich ja mächtig ins Zeug gelegt.
    Das guck ich mir heute Abend mal an.
    Bin grad auf der Arbeit. Schreibe über Smartphone.

    So bin seid ca. 16:20 zuhause und hab mir nach den Abendessen hab den Code angeschaut.
    Erst einmal herzlichen dank für die Hilfe.
    Hab das bisschen an den Code gefeilt.
    Folgende Verbesserung:
    Prozessname und Prozessid wird auch passenden aufgelistet.
    Man kann jetzt mit Buttonklick aktualisieren in dem sämtliche variable die dafür verantwortlich wurden auf 0 resettet wurden inklusiv Datagridview und Liste frisch laden, davor war das nicht möglich.
    Die Liste wird per Buttonklick nach bedarf gelöscht brauch man eigentlich nicht ist da es in Button aktualisieren bereits drin ist.

    API_MODUL
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Module API_Modul
    2. <Runtime.InteropServices.DllImport("user32.dll", SetLastError:=True)>
    3. Private Function GetForegroundWindow() As IntPtr
    4. End Function
    5. <Runtime.InteropServices.DllImport("user32.dll", SetLastError:=True, CharSet:=Runtime.InteropServices.CharSet.Auto)>
    6. Private Function GetWindowText(ByVal hwnd As IntPtr, ByVal lpString As Text.StringBuilder, ByVal cch As Integer) As Integer
    7. End Function
    8. <Runtime.InteropServices.DllImport("user32.dll", SetLastError:=True, CharSet:=Runtime.InteropServices.CharSet.Auto)>
    9. Private Function GetWindowTextLength(ByVal hwnd As IntPtr) As Integer
    10. End Function
    11. 'no specific Charset APIs
    12. <Runtime.InteropServices.DllImport("user32.dll", SetLastError:=True)>
    13. Public Function EnumChildWindows(hWndParent As IntPtr, lpEnumFunc As EnumWindowsProc, lParam As IntPtr) As Boolean
    14. End Function
    15. Public Delegate Function EnumWindowsProc(hWnd As IntPtr, lParam As IntPtr) As Boolean
    16. <Runtime.InteropServices.DllImport("user32.dll", CharSet:=Runtime.InteropServices.CharSet.Auto)>
    17. <Runtime.InteropServices.DllImport("user32.dll", CharSet:=Runtime.InteropServices.CharSet.Auto)>
    18. Public Function GetClassName(ByVal hWnd As System.IntPtr, ByVal lpClassName As System.Text.StringBuilder, ByVal nMaxCount As Integer) As Integer
    19. End Function
    20. Public Function GetActiveWindowText(hWnd As IntPtr) As String
    21. Dim length As Integer
    22. If hWnd.ToInt32 = 0 Then
    23. Return Nothing
    24. End If
    25. length = GetWindowTextLength(hWnd)
    26. If length = 0 Then
    27. Return Nothing
    28. End If
    29. Dim sb As New System.Text.StringBuilder("", length)
    30. GetWindowText(hWnd, sb, sb.Capacity + 1)
    31. Return sb.ToString()
    32. End Function
    33. Public Function ClassName(hwnd As IntPtr) As String
    34. Dim sClassName As New Text.StringBuilder("", 256)
    35. Call GetClassName(hwnd, sClassName, 256)
    36. Return sClassName.ToString
    37. End Function
    38. Public dt As New DataTable
    39. Public dv As New DataView(dt)
    40. Public Parent_Handle As IntPtr
    41. Public Function Enumerate(hWnd As IntPtr, lParam As IntPtr) As Boolean
    42. Dim row As DataRow = dt.NewRow()
    43. row!Handle = Parent_Handle.ToInt64
    44. row!Handle_child = CInt(hWnd.ToString)
    45. row!Classname = ClassName(hWnd)
    46. row!MainWindowTitle = GetActiveWindowText(hWnd)
    47. dt.Rows.Add(row)
    48. Return True
    49. End Function
    50. Public Function GetChild(hwnd As IntPtr) As Boolean
    51. Dim x As Boolean
    52. x = EnumChildWindows(hwnd, AddressOf Enumerate, CType(0, IntPtr))
    53. Return True
    54. End Function
    55. End Module



    WindowsForms
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Option Strict On
    2. Public Class Form1
    3. Dim CheckColumn As Boolean
    4. Dim FormName As String = "Windowed Scanner v2"
    5. Public Sub Handle_auflisten()
    6. If CheckColumn = False Then
    7. CheckColumn = True
    8. With dt.Columns
    9. .Add("Handle", Type.GetType("System.Int64"))
    10. .Add("Handle_child", Type.GetType("System.Int64"))
    11. .Add("ClassName", Type.GetType("System.String"))
    12. .Add("MainWindowTitle", Type.GetType("System.String"))
    13. .Add("Prozesse", Type.GetType("System.String"))
    14. .Add("Prozess_IDs", Type.GetType("System.String"))
    15. End With
    16. End If
    17. DataGridView1.DataSource = dv
    18. Dim Zähler As Integer
    19. For Each oProcess As Process In Process.GetProcesses
    20. If oProcess.MainWindowHandle <> IntPtr.Zero Then
    21. Dim Prozesse As String = oProcess.ProcessName
    22. Dim ProzessIDs As Int32 = oProcess.Id
    23. Dim windowHandle As IntPtr = oProcess.MainWindowHandle
    24. Dim row As DataRow = dt.NewRow()
    25. row!Handle = windowHandle.ToString
    26. row!MainWindowTitle = GetActiveWindowText(windowHandle) 'oProcess.MainWindowTitle.ToString
    27. row!ClassName = ClassName(windowHandle)
    28. row!Prozesse = Prozesse 'oProcess.ProcessName
    29. row!Prozess_IDs = ProzessIDs 'oProcess.Id
    30. dt.Rows.Add(row)
    31. Parent_Handle = windowHandle
    32. GetChild(windowHandle)
    33. End If
    34. Next
    35. dv.Sort = "Handle ASC"
    36. Zähler = DataGridView1.Rows.Count
    37. Me.Text = Me.Text & " Gefundene Handles: " & Zähler.ToString
    38. End Sub
    39. Private Sub ReadAllProzesse()
    40. DataGridView1.DataSource = Nothing
    41. DataGridView1.Rows.Clear()
    42. dt.Rows.Clear()
    43. Parent_Handle = IntPtr.Zero
    44. Me.Text = FormName
    45. Handle_auflisten()
    46. End Sub
    47. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    48. ReadAllProzesse()
    49. End Sub
    50. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    51. ReadAllProzesse()
    52. End Sub
    53. Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    54. DataGridView1.DataSource = Nothing
    55. DataGridView1.Rows.Clear()
    56. End Sub
    57. End Class



    Was fehlt nun eigentlich noch?

    Mein Ursprünglicher Code war ja so das er ein Spiel scannt ob es in Vollbild ist es ging zum Teil bei einigen Spiele.
    Manche Spiele sind widerspenstig und mein Tool kann nicht bestätigen das diese in Vollbild laufen obwohl sie wirklich in den Modus laufen.

    Mein Vorgänger bevor es mit Enumchild richtig anfing.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Option Explicit On
    2. Option Strict On
    3. Imports System.Runtime.InteropServices
    4. Imports System.Text
    5. Public Class Form1
    6. <Runtime.InteropServices.DllImport("user32.dll")>
    7. Shared Function GetAsyncKeyState(ByVal vKey As System.Windows.Forms.Keys) As Short
    8. End Function
    9. Private Function DoesProcessExists(ByVal PName As String) As Boolean
    10. Return System.Diagnostics.Process.GetProcessesByName(PName).Length >= 1
    11. End Function
    12. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    13. Prozessliste()
    14. End Sub
    15. Private Sub AutoSizeListViewColumns(oListView As ListView)
    16. SuspendLayout()
    17. For nCol = 0 To oListView.Columns.Count - 1
    18. oListView.Columns(nCol).Width = -1 'forces autosizing on column
    19. If oListView.Columns(nCol).Width < 100 Then
    20. oListView.Columns(nCol).Width = 100
    21. End If
    22. Next
    23. oListView.Refresh()
    24. ResumeLayout()
    25. End Sub
    26. Dim CheckColumn As Boolean
    27. Private Sub Prozessliste()
    28. If CheckColumn = False Then
    29. CheckColumn = True
    30. ListView1.FullRowSelect = True
    31. ListView1.Columns.Add("FensterHandle")
    32. ListView1.Columns.Add("Fensternamen")
    33. ListView1.Columns.Add("Prozesse")
    34. ListView1.Columns.Add("Prozess-ID")
    35. ElseIf CheckColumn = True Then
    36. End If
    37. ListView1.Items.Clear()
    38. For Each Alle_Prozesse In Process.GetProcesses()
    39. If Alle_Prozesse.MainWindowHandle.ToInt32 > 0 Then
    40. With ListView1.Items.Add(Hex(Alle_Prozesse.MainWindowHandle.ToString))
    41. .SubItems.Add(Alle_Prozesse.MainWindowTitle)
    42. .SubItems.Add(Alle_Prozesse.ProcessName)
    43. .SubItems.Add(Hex(Alle_Prozesse.Id.ToString))
    44. End With
    45. End If
    46. Next
    47. If ListView1.Items.Count > 0 Then
    48. AutoSizeListViewColumns(ListView1)
    49. End If
    50. End Sub
    51. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    52. Prozessliste()
    53. TextBox1.ReadOnly = True
    54. TextBox2.ReadOnly = True
    55. RichTextBox1.ReadOnly = True
    56. RichTextBox2.ReadOnly = True
    57. TextBox1.BorderStyle = BorderStyle.None
    58. TextBox2.BorderStyle = BorderStyle.None
    59. RichTextBox1.BorderStyle = BorderStyle.None
    60. RichTextBox2.BorderStyle = BorderStyle.None
    61. TextBox1.Cursor = Cursors.Default
    62. TextBox2.Cursor = Cursors.Default
    63. RichTextBox1.Cursor = Cursors.Default
    64. RichTextBox2.Cursor = Cursors.Default
    65. End Sub
    66. <Runtime.InteropServices.DllImport("user32.dll", SetLastError:=False)>
    67. Private Shared Function GetDesktopWindow() As IntPtr
    68. End Function
    69. <Runtime.InteropServices.DllImport("user32.dll", SetLastError:=True)>
    70. Private Shared Function GetForegroundWindow() As IntPtr
    71. End Function
    72. <Runtime.InteropServices.DllImport("user32.dll")>
    73. Private Shared Function GetWindowPlacement(ByVal hWnd As IntPtr, ByRef lpwndpl As WINDOWPLACEMENT) As Int32
    74. End Function
    75. <Runtime.InteropServices.DllImport("user32.dll")>
    76. Private Shared Function GetWindowRect(ByVal hWnd As IntPtr, ByRef lpRect As RECT) As Boolean
    77. End Function
    78. <Runtime.InteropServices.StructLayout(Runtime.InteropServices.LayoutKind.Sequential)>
    79. Public Structure RECT
    80. Public Left As Integer
    81. Public Top As Integer
    82. Public Right As Integer
    83. Public Bottom As Integer
    84. Public Overrides Function ToString() As String
    85. Return String.Format("Left: {0}, Top: {1}, Right: {2}, Bottom: {3}", Left, Top, Right, Bottom)
    86. End Function
    87. End Structure
    88. Dim XYRect As RECT
    89. Public Structure POINTAPI
    90. Public X As Int32
    91. Public Y As Int32
    92. End Structure
    93. Public Structure WINDOWPLACEMENT
    94. Public Length As Int32
    95. Public flags As Int32
    96. Public showCmd As Int32
    97. Public ptMinPosition As POINTAPI
    98. Public ptMaxPosition As POINTAPI
    99. Public rcNormalPosition As RECT
    100. Public rcDevice As RECT
    101. End Structure
    102. Dim intRet As Integer
    103. Dim wpTemp As WINDOWPLACEMENT
    104. Dim HWND As IntPtr
    105. Dim WindowMode_Information(3) As String
    106. Dim XYCheck As RECT
    107. Public Function GetWindowRectangle(ByVal hwnd As IntPtr) As Rectangle
    108. Dim XYRect As RECT
    109. GetWindowRect(hwnd, XYRect)
    110. Dim rr As New Rectangle(XYRect.Left, XYRect.Top, XYRect.Right - XYRect.Left, XYRect.Bottom - XYRect.Top)
    111. WindowMode_Information(0) = GetWindowRect(hwnd, XYRect) & vbNewLine & rr.ToString
    112. Return rr
    113. End Function
    114. Private Sub PrüfeWindowedModus()
    115. If ListView1.SelectedItems.Count > 0 Then
    116. For Each Prozess As Process In Process.GetProcessesByName(ListView1.SelectedItems.Item(0).SubItems(2).Text)
    117. TextBox1.Text = Prozess.ProcessName
    118. wpTemp.Length = System.Runtime.InteropServices.Marshal.SizeOf(wpTemp)
    119. intRet = GetWindowPlacement(Prozess.MainWindowHandle, wpTemp)
    120. HWND = Prozess.MainWindowHandle
    121. If Not Prozess.MainWindowHandle = IntPtr.Zero Then
    122. TextBox2.Text = Hex(Prozess.MainWindowHandle.ToString)
    123. CheckWindowMode()
    124. End If
    125. Next
    126. End If
    127. End Sub
    128. Private Sub ListView1_Click(sender As Object, e As EventArgs) Handles ListView1.Click
    129. If ListView1.Items.Count > 0 Then
    130. PrüfeWindowedModus()
    131. End If
    132. End Sub
    133. Private Sub ListView1_KeyUp(sender As Object, e As KeyEventArgs) Handles ListView1.KeyUp
    134. If e.KeyCode = Keys.Down Or e.KeyCode = Keys.Up Then
    135. If ListView1.Items.Count > 0 Then
    136. If ListView1.SelectedIndices.Count > 0 Then
    137. PrüfeWindowedModus()
    138. End If
    139. End If
    140. End If
    141. End Sub
    142. Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    143. If GetAsyncKeyState(Keys.LControlKey) <> 0 Or GetAsyncKeyState(Keys.RControlKey) <> 0 Then
    144. End If
    145. 'Da ich nur 1 Monitor habe benutze ich den Trick damit ich wenn ich Fullscreen minimiere sehe welcher modus zuletzt angezeigt wurde.
    146. 'Einfach Tastaturkürzel während den Vollbild anwenden. Um den Modus des Handles auszulesen.
    147. Select Case True
    148. Case GetAsyncKeyState(Keys.LShiftKey) <> 0
    149. 'Linke Shift Taste
    150. Case GetAsyncKeyState(Keys.RShiftKey) <> 0
    151. 'Rechte Shift Taste
    152. Case GetAsyncKeyState(Keys.LMenu) <> 0
    153. 'Linke Alt Taste
    154. Case GetAsyncKeyState(Keys.ControlKey) <> 0 AndAlso
    155. GetAsyncKeyState(Keys.RMenu) <> 0
    156. 'Rechte AltGr Taste ( Muss immer als erster stelle stehen!!! )
    157. Case GetAsyncKeyState(Keys.LControlKey) <> 0 AndAlso GetAsyncKeyState(Keys.Right) <> 0
    158. 'Linke STRG Taste und Rechte Pfeil Taste
    159. Case GetAsyncKeyState(Keys.LControlKey) <> 0 AndAlso GetAsyncKeyState(Keys.Left) <> 0
    160. 'Linke STRG Taste und Linke Pfeil Taste
    161. Case GetAsyncKeyState(Keys.RControlKey) <> 0 AndAlso GetAsyncKeyState(Keys.Right) <> 0
    162. 'TextBox3.Text = FullscreenCheck(ListView1.SelectedItems(0).SubItems(2).Text)
    163. 'Rechte STRG Taste und Rechte Pfeil Taste
    164. Case GetAsyncKeyState(Keys.RControlKey) <> 0 AndAlso GetAsyncKeyState(Keys.Left) <> 0
    165. 'Rechte STRG Taste und Linke Pfeil Taste
    166. CheckWindowMode()
    167. Case GetAsyncKeyState(Keys.RControlKey) <> 0 AndAlso GetAsyncKeyState(Keys.Down) <> 0 Or GetAsyncKeyState(Keys.LControlKey) <> 0 AndAlso GetAsyncKeyState(Keys.Down) <> 0
    168. 'Rechte STRG, oder Linke STRG Taste und Untere Pfeil Taste
    169. Case GetAsyncKeyState(Keys.RControlKey) <> 0 AndAlso GetAsyncKeyState(Keys.Up) <> 0 Or GetAsyncKeyState(Keys.LControlKey) <> 0 AndAlso GetAsyncKeyState(Keys.Up) <> 0
    170. 'Rechte STRG, oder Linke STRG Taste und Oberer Pfeil Taste
    171. Case GetAsyncKeyState(Keys.RControlKey) <> 0 AndAlso GetAsyncKeyState(Keys.Right) <> 0 OrElse GetAsyncKeyState(Keys.LControlKey) <> 0 AndAlso GetAsyncKeyState(Keys.Right) <> 0
    172. 'Rechte STRG, oder Linke STRG Taste und Rechter Pfeil Taste
    173. Case GetAsyncKeyState(Keys.RControlKey) <> 0 AndAlso GetAsyncKeyState(Keys.Left) <> 0 OrElse GetAsyncKeyState(Keys.LControlKey) <> 0 AndAlso GetAsyncKeyState(Keys.Left) <> 0
    174. 'Rechte STRG, oder Linke STRG Taste und Linker Pfeil Taste
    175. End Select
    176. End Sub
    177. Private Sub CheckWindowMode()
    178. RichTextBox2.Text = IsFullscreen(HWND) & vbNewLine & GetWindowState(HWND).ToString
    179. RichTextBox1.Text = WindowMode_Information(3)
    180. 'TextBox4.Text = IsFullscreen(HWND) & vbNewLine & WindowMode_Information(0) & vbNewLine & vbNewLine & WindowMode_Information(1) & vbNewLine & vbNewLine & WindowMode_Information(3)
    181. 'RichTextBox1.Text = IsFullscreen(HWND) & vbNewLine & WindowMode_Information(0) & vbNewLine & vbNewLine & WindowMode_Information(1) & vbNewLine & vbNewLine & WindowMode_Information(3)
    182. End Sub
    183. Dim CheckMonitorScreens As String
    184. Public Enum MyWindowStates
    185. Minimized
    186. Normal
    187. Maximized
    188. FullScreen
    189. UNKNOWN
    190. End Enum
    191. Public Enum MyWindowStates_Test
    192. Minimiert
    193. Normal
    194. Maximiert
    195. Vollbild
    196. Unbekannt
    197. End Enum
    198. 'Takafusa sein Code mit von mir kleine modifikationen so das es Infos ausspuckt.
    199. Public Function GetWindowState(ByVal hwnd As IntPtr) As MyWindowStates_Test
    200. Dim R As Rectangle = GetWindowRectangle(hwnd)
    201. Dim screens() As Screen = Screen.AllScreens
    202. Dim result As MyWindowStates_Test = MyWindowStates_Test.Unbekannt
    203. Dim intRet As Integer
    204. Dim wpTemp As WINDOWPLACEMENT
    205. wpTemp.Length = System.Runtime.InteropServices.Marshal.SizeOf(wpTemp)
    206. intRet = GetWindowPlacement(hwnd, wpTemp)
    207. If wpTemp.showCmd = 1 Then
    208. result = MyWindowStates_Test.Normal
    209. ElseIf wpTemp.showCmd = 2 Then
    210. result = MyWindowStates_Test.Minimiert
    211. ElseIf wpTemp.showCmd = 3 Then
    212. result = MyWindowStates_Test.Maximiert
    213. End If
    214. For i As Integer = 0 To screens.Length - 1
    215. If R.X < 0 Then
    216. R.Width += R.X
    217. R.Y += R.Y
    218. End If
    219. If R.Y < 0 Then
    220. R.Height += R.Y
    221. R.Y += R.Y
    222. End If
    223. If R.X = screens(i).Bounds.X AndAlso R.Y = screens(i).Bounds.Y AndAlso R.Width = screens(i).Bounds.Width AndAlso R.Height = screens(i).Bounds.Height Then
    224. result = MyWindowStates_Test.Vollbild
    225. End If
    226. WindowMode_Information(3) = "FensterModus=" & result.ToString & vbNewLine &
    227. "X Position: " & R.X & vbNewLine &
    228. "Y Position: " & R.Y & vbNewLine & vbNewLine &
    229. "Monitor:=" & i & ", " & R.Width & "x" & R.Height
    230. Next
    231. Return result
    232. End Function
    233. 'Mein Code
    234. Public Function IsFullscreen(ByVal hwnd As IntPtr) As String
    235. Dim R As Rectangle = GetWindowRectangle(hwnd)
    236. Dim screens() As Screen = Screen.AllScreens
    237. For i As Integer = 0 To screens.Length - 1
    238. 'Ursprünglicher Code mit My.Computer
    239. 'If R.Width >= My.Computer.Screen.Bounds.Width AndAlso R.Height >= My.Computer.Screen.Bounds.Height Then
    240. ' Return "Fullscreen"
    241. 'End If
    242. 'Verbesserter Code ohne My.Conputer
    243. If R.Width >= screens(i).Bounds.Width AndAlso R.Height >= screens(i).Bounds.Height Then
    244. Return "Monitor=" & i & ", FensterModus=Fullscreen"
    245. End If
    246. WindowMode_Information(1) = "Breite wenn minimiert " & R.Width & vbNewLine &
    247. "Höhe wenn minimiert " & R.Height & vbNewLine & vbNewLine &
    248. "Von Bildschirm Breite: " & screens(i).Bounds.Width & vbNewLine & 'My.Computer.Screen.Bounds.Width & vbNewLine &
    249. "Von Bildschirm Höhe: " & screens(i).Bounds.Height 'My.Computer.Screen.Bounds.Height
    250. Dim intRet As Integer
    251. Dim wpTemp As WINDOWPLACEMENT
    252. wpTemp.Length = System.Runtime.InteropServices.Marshal.SizeOf(wpTemp)
    253. intRet = GetWindowPlacement(hwnd, wpTemp)
    254. If wpTemp.showCmd = 1 Then
    255. Return "Monitor:=" & i & ", FensterModus=Normal"
    256. ElseIf wpTemp.showCmd = 2 Then
    257. Return "Monitor=" & i & ", FensterModus=Minimized"
    258. ElseIf wpTemp.showCmd = 3 Then
    259. Return "Monitor=" & i & ", FensterModus=Maximized"
    260. End If
    261. Next
    262. Return "Error"
    263. End Function
    264. Private Sub RichTextBox_TextBox_Click(sender As Object, e As EventArgs) Handles TextBox1.Click, TextBox2.Click, RichTextBox1.Click, RichTextBox2.Click
    265. Button1.Focus()
    266. End Sub
    267. Private Sub RichTextBox_TextBox_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TextBox1.KeyPress, TextBox2.KeyPress, RichTextBox1.KeyPress, RichTextBox2.KeyPress
    268. e.Handled = True
    269. End Sub
    270. <DllImport("user32.dll", SetLastError:=True)>
    271. Private Shared Function EnumChildWindows(HWNDParent As IntPtr, lpEnumFunc As EnumWindowsProc, lParam As IntPtr) As Boolean
    272. End Function
    273. Public Delegate Function EnumWindowsProc(HWND As IntPtr, lParam As IntPtr) As Boolean
    274. <DllImport("user32.dll", CharSet:=CharSet.Ansi)>
    275. Public Shared Function GetWindowTextA(hwnd As IntPtr, <MarshalAs(UnmanagedType.LPStr)> lpString As StringBuilder, nMaxCount As Integer) As Integer
    276. End Function
    277. <DllImport("user32.dll")>
    278. Public Shared Function GetWindowTextLengthA(hwnd As IntPtr) As Integer
    279. End Function
    280. <DllImport("user32.dll", CharSet:=CharSet.Unicode)>
    281. Public Shared Function GetWindowTextW(hwnd As IntPtr, <MarshalAs(UnmanagedType.LPStr)> lpString As StringBuilder, nMaxCount As Integer) As Integer
    282. End Function
    283. <DllImport("user32.dll")>
    284. Public Shared Function GetWindowTextLengthW(hwnd As IntPtr) As Integer
    285. End Function
    286. End Class


    Dieser Beitrag wurde bereits 10 mal editiert, zuletzt von „Xiantrius“ ()

    Hallo Xiantrius

    Bei der Funktion Enumerate solltest Du auch noch die Neuerungen einfügen, d.H. Prozessname und ProzessID. Mich erstaunt, dass diese auch funktioniert, wenn Sie im Modul ist. Bei mir geht das so nicht.

    Die Table müsstest Du auch eigentlich nur 1 x definierten, Zeilen 8 - 17 - könntest du daher im FormLoad stehen lassen.
    Es reicht auch, wenn du die Datatable löscht, einfach:

    VB.NET-Quellcode

    1. dt.Clear()


    nicht so:

    VB.NET-Quellcode

    1. DataGridView1.DataSource = Nothing
    2. DataGridView1.Rows.Clear()
    3. dt.Rows.Clear()


    Noch schöner wäre es, wenn du ein Dataset im Desinger anlegen würdest, dann könntest Du auch die Spalten im Desinger bearbeiten. ErfinderDesRades hat da schöne Videos erstellt, die 4 Views.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Panter“ ()