Wie funktionieren bestimmte API's richtig?

  • VB.NET

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

    Wie funktionieren bestimmte API's richtig?

    Hallo

    Problem das ich derzeit habe:
    1. EnumWindows und EnumChildWindows

    VB.NET-Quellcode

    1. <Runtime.InteropServices.DllImport("user32.dll", SetLastError:=True, CharSet:=Runtime.InteropServices.CharSet.Auto)>
    2. Public Shared Function EnumWindows(ByVal lpEnumFunc As EnumWindowsProc, ByVal lParam As IntPtr) As Boolean
    3. End Function
    4. Public Delegate Function EnumWindowsProc(ByVal hwnd As IntPtr, ByVal lParam As IntPtr) As Boolean
    5. <Runtime.InteropServices.DllImport("user32")>
    6. Public Shared Function EnumChildWindows(ByVal hWndParent As IntPtr,
    7. ByVal lpEnumProc As EnumChildProc, ByVal lParam As Integer) As Boolean
    8. End Function
    9. Public Delegate Function EnumChildProc(ByVal hwnd As IntPtr, ByVal lParam As IntPtr) As Boolean
    10. Private Sub EnumChildWindows(ByVal parentWindow As IntPtr)
    11. EnumChildWindows(parentWindow, AddressOf ProcessChildWindow, 0)
    12. End Sub
    13. Private Function ProcessChildWindow(ByVal hwnd As IntPtr, ByVal lParam As IntPtr) As Boolean
    14. Return True
    15. End Function


    Beispiel:
    Ich möchte eine Liste mit MainWindowtitel und MainWindowHandle über die API passenden nebeneinander als reihe in einer ListBox auflisten.
    Wie müsste ich da vor gehen?
    Ich muss ehrlich zugeben ich komme damit nicht klar.

    VB.NET-Quellcode

    1. <Runtime.InteropServices.DllImport("user32.dll", SetLastError:=True, CharSet:=Runtime.InteropServices.CharSet.Auto)>
    2. Private Shared Function GetWindowTextLength(ByVal hwnd As IntPtr) As Int32
    3. End Function
    4. <Runtime.InteropServices.DllImport("user32.dll", EntryPoint:="GetWindowText")>
    5. Public Shared Function GetWindowText(ByVal hwnd As Integer, ByVal lpString As System.Text.StringBuilder, ByVal cch As Integer) As Integer
    6. End Function
    7. <Runtime.InteropServices.DllImport("user32.dll", CharSet:=Runtime.InteropServices.CharSet.Auto)>
    8. Public Shared Function GetClassName(ByVal hWnd As System.IntPtr, ByVal lpClassName As System.Text.StringBuilder, ByVal nMaxCount As Integer) As Integer
    9. End Function
    10. Public Function EnumProc(ByVal hwnd As IntPtr, ByVal lParam As IntPtr) As Boolean
    11. 'Dim Retval As String
    12. Dim CheckStrB As New Text.StringBuilder
    13. Dim WindowText As String
    14. Dim WindowClass As String
    15. On Error GoTo ErrHandler
    16. 'Möchte Fenstertitel mit richtige Fensterhandle in die Listbox zb. haben.
    17. With ListBox1.Items
    18. CheckStrB.Append(GetWindowTextLength(hwnd) + 1)
    19. WindowText = GetWindowText(CInt(hwnd), CheckStrB, CheckStrB.Length).ToString
    20. WindowClass = GetClassName(hwnd, CheckStrB, CheckStrB.Length).ToString
    21. .Add(CStr(hwnd) & " # " & WindowClass & " # " & WindowText)
    22. End With
    23. ' nächstes Child-Window ermitteln
    24. EnumProc = True
    25. Exit Function
    26. ErrHandler:
    27. WindowText = ""
    28. Resume Next
    29. End Function


    Ich bitte um gute Code Beispiele, damit ich es verstehen kann.

    mfg.
    Xiantrius

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

    Hi

    Nur mal fix über Deinen Code drüber geschaut und nur zwei APIs rausgepickt. Die APIs GetWindowText und GetClassName sind nicht korrekt. Insbesondere der zweite Parameter. Hier wird ein Pointer auf einen StringBuffer erwartet. Da Du die Variante ohne A/W verwendest, müsste hier wohl ByRef hin. Bei der A und W Varinte mit ByVal (bzw ByVal muss man nirgends angeben) mit entsprechenden Marshalling auf LPStr oder LPWStr. StringBuilder ist ok aber Du gibst dem StringBuilder keine Capacity (<- GetWindowTextLength) mit. Dein Buffer hat daher die Capacity 0. Bei GetWindowText stimmt der erste Parameter auch nicht. hwnd ist ein IntPtr. Die Rückgabe dieser beiden APIs ist ein Integer der die Anzahl der Kopierten Zeichen wiedergibt die sich dann im Buffer befinden den Du einen String übergibst? Der von der API zurück gelieferte String steht dann im zweiten Parameter. Option Explicit On? On Error Goto ...? Wir sind hier doch bei .Net und nicht bei VB6. Wo kopierst Du Dir eigentlich immer diese verkorksten API und Code her ohne diese gegen zu checken?

    Schau in die MS Doku zu den APIs. Da wird alles genau beschrieben was welcher Parameter erwartet und wie diese gegebenenfalls zu marshallen sind falls nötig und was die APIs zurück geben. Auch wenn Du kein C++ lesen kannst, kann ich Dir nur empfehlen Dich ein wenig mit C++ zu beschäftigen. Zumindest soweit das Du APIs usw nicht irgendwo her kopieren musst und diese so, wie sie in der MS Doku stehen, direkt übersetzen kannst.
    Mfg -Franky-
    Hallo @-Franky-
    hmm verstehe nicht genau worauf du hinaus willst?
    Aber Wenn du denkst ich hab das irgendwo raus kopiert dann nicht aus irgend ein Forum.

    Von hier habe ich die GetWindowText API:
    pinvoke.net/default.aspx/user32/GetWindowTextLength.html

    Von hier habe ich die GetClassName API:
    pinvoke.net/default.aspx/user32/GetClassName.html

    Habe alle API's die du siehst aus der pinvoke.net Seite.
    Man muss nicht unbedingt c++ lernen nur damit man API's nutzen kann.
    Dann hätte ich es schon längst gemusst da ich auch mit anderen API's zurecht kam die ich bereits bei mir drin habe.
    Da gab es auch wirklich auch aufschlussreiche Hilfe aus dem Netz das mich das hat lernen lassen.
    Ok vielleicht ein bisschen C++, aber ich muss es nicht so gut können gerade soviel das es ausreicht um etwas raus zu lesen. Viel mehr kann ich eh nicht, ist mir zu kompliziert. Wenn du mir sagst schreib mal draus ein C++ programm, kann ich dir sagen ich kann es nicht. Vor allem mag ich reine Consolen Anwendungen nicht. Habe mich Seit April 2012 - bis Heute mit VB.NET spezialisiert.
    Mit VB 2008/2010 fing ich an. Viele tutorials in Youtube geschaut und auch in Forum wie hier geschaut, deswegen hab ich mich auch registriert damit man mir hilft etwas neues über VB.NET Code zu lernen. Aber ich merke schon die ganzen Jahre seit ich hier registriert bin, dass ich das Gefühl immer weiter verstärkt das ich manchmal meine Zeit hier verschwende. Dann ist mir doch vielleicht einer bereit zu helfen und schon ist das Gefühl wieder weg, weil ich dann sagen kann das hat sich gelohnt.
    Sicher ist nicht die beste Lösung, aber immer noch besser als von einer Seite wie VB6 API's zu holen wo nur LONG drin steht.
    Ich hätte lieber ein gutes Beispiel Tutorial angeschaut als die VB6 variante vorzufinden.
    Ich suche oft im Netz lerne und wenn ich ein Code selber schreiben kann dann tue ich es auch. Kommt auch vor das ich wenn ich absolut nicht weiter komme im Netz suche, bin sicher bin nicht der einzige.
    Ausserdem kopiere ich Codes nicht einfach und klatsch die ins Projekt, nein ich passe sie auch an wenn nötig. Es kommt auch vor das ich dann was eigenes schreibe wenn ich den Code verstanden habe und ersetze den Code von Netz auch mit meinen.
    Andere passende Codes können einen inspirien und auf die Sprünge helfen bei problemen die man hat.
    So entstanden Zahlreiche Projekte auch wenn es zwecks manchmal zur Übung diente. @-Franky-.
    Noch etwas es fällt mir echt schwer das zu sagen, aber damit nicht schon wieder Leute wie Takafusa am ende so über mich denken muss ich folgendes wichtiges schreiben damit ihr versteht:
    Ich war als Kind Sonderschüler und habe eine Lernverzögerung als Behinderung, es gibt bestimmt Leute die lachen über mich und glauben mir nicht, oder lachen weil ich die Behinderung habe. Ihr wundert euch warum ich das Anspreche. Damit ihr die Zusammenhänge versteht warum.
    Ich brauche viel länger ein Projekt zu schreiben. Würde einer das gleiche Programm schreiben wie ich und ist in Kopf fitter wie ich. Der würde das in je nach dem 10 - 20 Minuten fertig haben, während ich 1 Stunde oder länger brauch je nach komplexität.


    So weiter gehts:
    Ich hab einfach bisher keine richtige Antwort auf diese API's.
    Wenn die API nicht korrekt ist, wie muss das über den Code aussehen?
    Ich schrieb auch bitte per Code damit ich es besser verstehen kann.
    Wo muss das ByRef rein?

    VB.NET-Quellcode

    1. Public Function EnumProc(ByVal hwnd As IntPtr, ByVal lParam As IntPtr) As Boolean' war übrigends zwangsläufig aus ein VB6 Beispiel bekomme es halt nicht richtig übersetzt. Hab es doch versucht die Function sah ein wenig anders aus, bevor ich es versuchte zu übersetzen. Mir ist klar das es schönere Funktionen gibt.
    2. 'Wo muss hier was ausgebessert werden?
    3. <Runtime.InteropServices.DllImport("user32.dll", CharSet:=Runtime.InteropServices.CharSet.Auto)>
    4. Public Shared Function GetClassName(ByVal hWnd As System.IntPtr, ByVal lpClassName As System.Text.StringBuilder, ByVal nMaxCount As Integer) As Integer
    5. End Function
    6. 'Wo muss hier was ausgebessert werden?
    7. <Runtime.InteropServices.DllImport("user32.dll", EntryPoint:="GetWindowText")>
    8. Public Shared Function GetWindowText(ByVal hwnd As Integer, ByVal lpString As System.Text.StringBuilder, ByVal cch As Integer) As Integer
    9. End Function


    Ich möchte alle drauf hinweisen das es kein Spass euch damit zu belästigen, denn ich brauche da wirklich eure Hilfe.
    Ausserdem profitieren auch andere davon ganz automatisch.
    Ich wäre euch sehr dankbar darüber.

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

    Moin moin

    Naja, Du kopierst die APIs von Pinvoke.net und die sind dort oft falsch. Deswegen schlage ich Dir vor, schau Dir lieber die API Signaturen, die Beschreibung der Parameter und Rückgabe in der MS Doku an. Für die Parameter und Rückgabe muss man aber nur ein wenig C++ lesen können oder zumindest wissen, welcher C++ Datentyp entspricht welchem .NET Datentyp. Mehr muss es gar nicht sein um das von der MS Doku korrekt nach .Net zu übersetzen.

    Versteh mich bitte nicht falsch. Ich will Dich nicht ärgern oder provozieren. Ich hab vllt nur eine andere Art Dir zu sagen, wenn Du von Pinvoke.net kopierst, dann checke die Signaturen mit der, wie sie in der MS Doku stehen. Dann müssten Dir die Fehler auffallen.
    Mfg -Franky-
    So sollte es eigentlich funktionieren man könnte auch normalen String nehmen.

    VB.NET-Quellcode

    1. 'Für API GetWindowText
    2. lpString As String
    3. 'Für GetClassName
    4. lpClassName As String


    VB.NET-Quellcode

    1. ' int GetWindowTextA(
    2. ' [in] HWND hWnd,
    3. ' [out] LPSTR lpString,
    4. ' [in] int nMaxCount
    5. ');
    6. <Runtime.InteropServices.DllImport("user32.dll", EntryPoint:="GetWindowTextA")>
    7. Public Shared Function GetWindowText(ByVal hwnd As IntPtr, ByVal lpString As String, ByVal nMaxCount As Integer) As Integer
    8. End Function
    9. ' int GetClassNameA(
    10. ' [in] HWND hWnd,
    11. ' [out] LPSTR lpClassName,
    12. ' [in] int nMaxCount
    13. ');
    14. <Runtime.InteropServices.DllImport("user32.dll", EntryPoint:="GetClassNameA")>
    15. Public Shared Function GetClassName(ByVal hWnd As IntPtr, ByVal lpClassName As String, ByVal nMaxCount As Integer) As Integer
    16. End Function


    würde gerne wissen wie man das in einer funktion mit den API's oben in einer Function macht so das man die übergabe in einer listbox zb.: so sehen kann wie ich es gedacht habe.
    Wie funktioniert das?
    Wäre mal gut, wenn du schon interesse zeigst mir zu helfen, dass du auch mal bisschen was zeigst per Code.
    Ich gebe dir immer hin auch Details zumindest bemühe ich mich damit.

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

    hi @Panter

    Die Methode kenne ich schon mit der For Each schleife alle Prozesse mit Mainwindowhandle usw.. anzeigen zu lassen.
    Trotzdem danke.

    Mich würde es aber interessieren wie die API's das machen und ausserdem kann die Methode auch andere Controls auslesen aus externen Prozesse auslesen.
    Ich glaube das kann die API EnumChildProc wenn man das irgendwie als funktion hinbekommt.
    Der VB6 code funktionierte zwar nicht richtig aber der hatte in der liste weit mehr als 200 handle angezeigt. Das Dumme war ich weis aber nicht welches was war. Daher brauch ich noch die Prozesse und die Windowhandle, oder Classname passend zu den Handles in der liste.
    @Xiantrius Schau auch mal hier rein:
    Andere Programme fernsteuern
    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!
    Guck dir das an, ich habe aber < 10 Zeilen Code weggelassen, weil du nach guten Code gefragt hast, habe ich ein Video gemacht, sonst hätte ich hier Code gepostet, also abschreiben. Die Fehlenden Codezeilen betrifft die Sub Funktion für den Delegaten. Sieh dir andere Codes an, dann kannst du das hinbekommen, es ist ja immer gleich wie das geht.

    Habe das Video hier entfernt und den Code eingefügt, hat sich jemand drüber aufgeregt. Aber wie ihm Video auch fehlt die Delegaten Funktion, der Rumpf davon ist nun drin, aber nicht mehr.

    Spoiler anzeigen

    VB.NET-Quellcode

    1. 'Win32.vb
    2. Imports System.Runtime.InteropServices
    3. Public Class Win32
    4. 'no specific Charset APIs
    5. <DllImport("user32.dll", SetLastError:=True)>
    6. Public Shared Function EnumChildWindows(hWndParent As IntPtr, lpEnumFunc As EnumWindowsProc, lParam As IntPtr) As Boolean
    7. End Function
    8. Public Delegate Function EnumWindowsProc(hWnd As IntPtr, lParam As IntPtr) As Boolean
    9. End Class


    VB.NET-Quellcode

    1. 'Win32A.vb
    2. Imports System.Text
    3. Imports System.Runtime.InteropServices
    4. Public Class Win32A
    5. 'Ansi APIs
    6. <DllImport("user32.dll", CharSet:=CharSet.Ansi)>
    7. Public Shared Function GetWindowTextA(hwnd As IntPtr, <MarshalAs(UnmanagedType.LPStr)> lpString As StringBuilder, nMaxCount As Integer) As Integer
    8. End Function
    9. <DllImport("user32.dll")>
    10. Public Shared Function GetWindowTextLengthA(hwnd As IntPtr) As Integer
    11. End Function
    12. End Class


    VB.NET-Quellcode

    1. 'Win32W.vb
    2. Imports System.Text
    3. Imports System.Runtime.InteropServices
    4. Public Class Win32W
    5. 'Unicode APIs
    6. <DllImport("user32.dll", CharSet:=CharSet.Unicode)>
    7. Public Shared Function GetWindowTextW(hwnd As IntPtr, <MarshalAs(UnmanagedType.LPWStr)> lpString As StringBuilder, nMaxCount As Integer) As Integer
    8. End Function
    9. <DllImport("user32.dll")>
    10. Public Shared Function GetWindowTextLengthW(hwnd As IntPtr) As Integer
    11. End Function
    12. End Class


    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[/spoiler][spoiler]

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

    hi @BitBrösel Willkommen im vb-paradise. sehe du bist neu registriert.
    Also ich habe dein Code auf ähnlicher weise zusammen gebastelt.
    Da stellen sich allerdings 3 Fragen
    1. Muss das <UnmanagedType.Boolean> in die API EnumChildWindow, wenn ja wie? Ohne wäre der fehler weg, weis aber dann nicht ob was anderes an problemen dann auftritt.

    2. Die EnumWindowsProc Function fehlt, wie sieht die den aus, oder könnte sie in etwa aussehen?

    3. Für was ist der Variable Enumrate gedacht und wie muss ich die deklarieren? String, Int, oder IntPtr geht nicht.

    Trotz allem recht hilfreich danke.

    VB.NET-Quellcode

    1. <DllImport("user32")>
    2. <UnmanagedType.Boolean>
    3. Private Shared Function EnumChildWindows(ByVal window As IntPtr, ByVal callback As EnumWindowProc, ByVal listHandle As IntPtr) As Boolean
    4. End Function
    5. Private Sub TestListe()
    6. For Each Prozess As Process In Process.GetProcesses
    7. Dim WindowHandle As IntPtr = Prozess.MainWindowHandle
    8. Dim ChildList As List(Of IntPtr) = New List(Of IntPtr)()
    9. Dim ChildListHandle As GCHandle = GCHandle.Alloc(ChildList)
    10. 'Erforderliche EnumWindowsProc fehlt
    11. Dim EnumChildWindows As New EnumWindowsProc(AddressOf Enumrate)
    12. '2x Enumrate wurde nicht deklariert. Stellt sich doch gleich die Frage als was muss sie deklariert werden?
    13. If Not EnumChildWindows(WindowHandle, (AddressOf Enumrate), GCHandle.ToIntPtr(ChildListHandle)) Then
    14. MsgBox("ErrorCode: " & Marshal.GetLastWin32Error())
    15. End If
    16. If ChildListHandle.IsAllocated Then
    17. ChildListHandle.Free()
    18. End If
    19. For Each ChildHandle As IntPtr In ChildList
    20. Dim WindowTextLength As Integer = GetWindowTextLength(ChildHandle)
    21. Dim StringBuild As New StringBuilder
    22. If WindowTextLength > 0 Then
    23. StringBuild.Capacity = WindowTextLength + 1
    24. Dim copiedCharsCount As Integer = GetWindowText(ChildHandle, StringBuild, WindowTextLength + 1)
    25. If copiedCharsCount = WindowTextLength Then
    26. ListBox1.Items.Add(StringBuild.ToString())
    27. End If
    28. End If
    29. Next
    30. Next
    31. End Sub


    @RodFromGermany
    Hmm müsste ich mal in ruhe anschauen ist alles in C# und auch nicht unbedingt leicht zu entziffern für mich zumindest in VB.NET zu konvertieren.

    Mache für heute mal feierabend, vor lauter gecode und rum experimentiererei sehe ich die Hand vor Augen nicht mehr xDDD. na dann schönen abend euch und gute nacht.

    mfg.
    Xiantrius
    Die Frage nach dem Boolean Marshal'n erübrigt sich wenn du in meinem Video die Deklarationen ansiehst, ob du nun die Funktionen aus der Win32A oder Win32B nimmst ist schnuppe, mische nur nicht aus Win32A und Win32B, die aus der Win32 kannste mit den anderen ohne Agnst kombinieren. Bei Strukturen oder Zeichenketten ist es besser zu Marshal'n, ohne solche Typen zu Marshal'n gibt es flott mal eine AccessViolation- oder StackImbalance- Exception. Ich habe gesehen das -Franky- schrieb, den StringBuilder via ByRef zu übergeben, das würde eine AccesViolationException werfen.

    Die Delegaten- Sub Funktion ist bei mir nur 8 Zeilen lang, aus lParam(2. Parameter) wird mit "GCHandle.FromIntPtr(lParam).Target" eine List(of IntPtr) gemacht, das ist die Liste die bei EnumChildWindows als 3. Parameter mitgegeben wird, besser gesagt wie ein Zeiger, die ist dann im Speicher und wird befüllt. Wenn nach dem casten aber diese Liste in der Sub Funktion Nothing ist, wird False ausgeben und fertig, sonst immer True.

    PS.
    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.

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

    konnte noch nicht schlafen hab nochmal 1 Stunde rum probiert wegen der variable Enumrate, oder Enumerate ka war sehr schwer aus dem Video zu lesen.
    Naja wie auch immer ich habe keine deklaration dieses Namens gefunden. Wie wird die gemacht und was bewirkt die?

    Xiantrius schrieb:

    Wie wird die gemacht und was bewirkt die?


    Wie die gemacht wird? Ganz einfach geschrieben wird sie.
    Was da genau passiert, habe ich in meinem letzten Post genau beschrieben. Wenn ich dir diese 8 Zeilen auch noch "Serviere" hast du nichts gelernt. Wenn du das im Video schlecht sehen konntest, sieh dir das Video in 4K an, da ist das schärfer. In dieser Zeile mache ich eine Instanz vom Delegaten

    VB.NET-Quellcode

    1. Dim enumChildWindows As New Win32.EnumWindowsProc(AddressOf Enumerate)


    Enumerate heißt bei mir diese Sub Funktion , die baucht die gleichen Parameter wie der Delegate, mit AddressOf wird auf diese Sub Funktion gezeigt. Du kannst weiterfragen, aber ich werde dir nicht diese 8 Zeilen hier geben, die must du dir erarbeiten, auch wenn du dazu 20 andere Codes studieren musst. RodFromGermany verwendet genau den gleichen Delegaten(Andere Programme fernsteuern) die Sub Funktion heißt nur anders bei ihm, verstehe den Code, wenn du das nicht hinbekommst, must du nochmal Grundlagen pauken. Du bist seit 2012 hier, also knappe 10 Jahre, da solltest du diese Kleinigkeit hinbekommen.

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

    Du denkst also man lernt nichts wenn man den code gesagt bekommt? Warum glauben alle den Irrtum? gerade wenn man ihn bekommt, oder selbst raus kriegt kann man es lernen und man kommt drauf warum er so geschrieben wird. ich Analyisiere Codes und versuch es im Kopf mir auszumalen
    Sicher es gibt Leute die wollen einfach nur kopieren und fertig. Ich gehöre aber nicht zu so einer Sorte. Hast du eigentlich das ganze Thread gelesen?

    Kann nicht mal dein Code Testen weil noch 3 fehler drin sind.

    Schweregrad Code Beschreibung Projekt Datei Zeile Unterdrückungszustand
    Fehler BC30577 'Der AddressOf-Operand muss dem Namen einer Methode entsprechen (ohne Klammern). Windowed-Scanner D:\Programme\Visual Studio\VS Projekte\Visual Studio 2019 Enterprise\Save Debug\Windowed-Scanner\Form1.vb 621 Aktiv

    Schweregrad Code Beschreibung Projekt Datei Zeile Unterdrückungszustand
    Fehler BC30577 'Der AddressOf-Operand muss dem Namen einer Methode entsprechen (ohne Klammern). Windowed-Scanner D:\Programme\Visual Studio\VS Projekte\Visual Studio 2019 Enterprise\Save Debug\Windowed-Scanner\Form1.vb 627 Aktiv

    Schweregrad Code Beschreibung Projekt Datei Zeile Unterdrückungszustand
    Fehler BC30057 Zu viele Argumente für "Form1.EnumWindowsProc". Windowed-Scanner D:\Programme\Visual Studio\VS Projekte\Visual Studio 2019 Enterprise\Save Debug\Windowed-Scanner\Form1.vb 627 Aktiv
    Keine Ahnung wie du das gemacht hast...

    VB.NET-Quellcode

    1. If Not EnumChildWindows(WindowHandle, AddressOf Enumerate, GCHandle.ToIntPtr(ChildListHandle)) Then


    VB.NET-Quellcode

    1. 'Könnte möglicherweise so lauten die deklaration
    2. Dim Enumerate As Boolean

    Xiantrius schrieb:

    Warum glauben alle den Irrtum?

    Man lernt nicht durch kopieren, so wirst du immer nur kopieren, RodFromGermany hat ja bereits den Code den du brauchst verlinkt, da heißt diese eine Sub Funktion nur anders, der Code ist in C#, gut die Schreibweise ist ein wenig anders, aber du kannst Übersetzer nutzen.

    Das ist ein schlagkräftiges Argument was dafür spricht, das man durch Code kopieren nicht lernt.

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

    Kannst du mir bitte den letzten Post von Enumerate bestätigen ob das ein Boolean ist? Weil das andere bekomme ich noch nicht hin um das zu testen.
    Also ich bin auch in der lage kopierte und eigene codes anzuschauen glaube es mir, oder lass es....
    bin etwas genervt sorry, weil ich an den Projekt schon gefüllte 1 Wochen sitze dabei ist das nicht mal was grosses, sondern ein Teil von VB.NET das ich noch nie gemacht habe und man lässt mich jetzt mit den rest auflaufen...

    gehe jetzt schlafen ist bald 0 Uhr. gute nacht.
    Sieh in die Win32 Klasse in meinem Video, da ist ein delegate, die Parameter für die Sub Funktion sind identisch das habe ich ja schon gesagt(müssen sogar identisch sein), ich füge nun hinzu, der Typ der ausgegeben wird ist auch identisch und muss das auch sein. Das war mein letzter Tipp.

    PS.
    Es muss eine Funktion sein, nicht Sub, tut mir leid wenn ich damit Verwirrung gestiftet haben sollte. Ich habe das in meinen Posts gerade eben schnell korrigiert.

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

    guten morgen, erst mal danke das du trotzdem ein Weg gezeigt hast.
    Doch ich weis nicht wie die Funktion aussehen soll.

    Sicher kann oberflächig mit der Function beginnen, weis aber nicht wie der inhalt aussehen muss da ich die ich mich mit diese art API's zu wenig kenne.
    Denkst ich kopiere einfach nur und willst mir das vorwerfen das ich nichts lerne, sorry auch wenn du geholfen hast mir den Weg zu zeigen nehme ich dir das langsam übel weil das wie ein Vorwurf bzw. Behauptung klingt...

    Die funktion wird so eh nicht stimmen vor allem hilft mir das keiner zu Bestätigen vor allem dich habe ich gefragt BitBrösel.
    Wenn du dir den Thread von anfang an durch gelesen hättest, wüsstest du was für ein problem ich habe.
    Falls du es tatsächlich getan hast glaubst du mir nicht was in Post 3 steht.
    Du kannst auch gerne mein Behinderten Ausweis sehen der wäre Aussagekräfiger.
    Zeige ich aber nur Privat nicht hier offen wer mir nicht glauben will.

    VB.NET-Quellcode

    1. Public Function Enumerate(ByVal hwnd As IntPtr, ByVal lParam As IntPtr) As Boolean
    2. Return True
    3. End Function

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

    @BitBrösel Ich schrieb: .Da Du die Variante ohne A/W verwendest, müsste hier wohl ByRef hin. Müsste, eine Vermutung. Da ich aber gern die Kontrolle behalte, welche API nun wirklich verwendet wird, verwende ich nach Möglichkeit immer immer die A- oder W-Variante einer API. Vorzugsweise die W-Variante. Und dazu schrieb ich: Bei der A und W Variante mit ByVal mit entsprechenden Marshalling auf LPStr oder LPWStr.
    Mfg -Franky-
    Ich hatte das bisher nicht gelesen, wenn du die 5 fehlenden Zeilen noch schaffst darfst du aber doppelt stolz sein. :thumbsup: Wenn du den Code aus dem Video abgeschrieben hast, bist du fast am Ziel, den Rumpf der Funktion hast du ja jetzt. Sieh dir noch mal RodFromGermanys Anleitung an, dort ist das fehlende Stück. Er verwendet auch das EnumWindowProc, die Funktion auf die gezeigt wird heißt bei ihm nur anders,(aber das ist Egal, ob du einen Tee aus einem Glas oder einer Tasse trinkst, du trinkst ihn) nimm einen Online C# VB Übersetzer. Das traue ich dir trotz Defizit zu, du musst nur diese eine Parallele finden. Aus deiner Sicht ist das möglicherweise nicht so einfach zu verstehen, aber so lernst du mehr als wie wenn ich oder jemand anders es dir vorzeigt, du musst denn Ablauf bei RodFromGermanys Code mit dem aus meinem Video vergleichen, dann findest du in RodFromGermanys Code die Funktion. Es ist ja jetzt nicht so, das du ein Buch mit über 1000 Seiten durcharbeiten müsstest, übersetze die kleinen Codes, vergleiche das mit meinen, dann wirst du ganz sicher(auch wenn es dauert) die Lösung finden.

    Ich bringe meinem 12 Jährigen Neffen VB bei, der will auch immer die Lösung als Code haben, aber ich sehe das er besser wird weil ich es ihm nicht verrate.

    Xiantrius schrieb:

    man lässt mich jetzt mit den rest auflaufen...


    Das finde ich unfair, hier wurden dir alle Informationen geliefert die du brauchst um das zu vollenden.

    -Franky- schrieb:

    @BitBrösel Ich schrieb: .Da Du die Variante ohne A/W verwendest, müsste hier wohl ByRef hin. Müsste, eine Vermutung. Da ich aber gern die Kontrolle behalte, welche API nun wirklich verwendet wird, verwende ich nach Möglichkeit immer immer die A- oder W-Variante einer API. Vorzugsweise die W-Variante. Und dazu schrieb ich: Bei der A und W Variante mit ByVal mit entsprechenden Marshalling auf LPStr oder LPWStr.


    Mit den Ansi/Unicode Varianten sehe ich das ähnlich, darum habe ich im Video eine Klasse mit A, eine mit W und eine ohne beides, so hat der TE korrekte Deklarationen, egal für welche er sich nun entscheidet. Denn bei EnumChildWindows kann einem ein falsches CharSet nicht zum stolpern bringen.

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