API Deklarationen

  • VB.NET

Es gibt 12 Antworten in diesem Thema. Der letzte Beitrag () ist von exc-jdbi.

    API Deklarationen

    Ich programmiere (gelegentlich) in vb-express 2010. Und ich brauche dabei auch gelegentlich API-Funktionen. Dabei stoße ich immer wieder auf den Runtime-Fehler "pinvoke stackimbalance was detected". Als Grund dafür wird angegeben, dass das meistens auf einer falschen Deklaration der Betreffenden API-Funktion beruht. Ich habe dann im Internet nach der richtigen Deklaration gesucht und manchmal hat das auch geholfen.

    Ich suche aber nach einer Dokumentation der API-Funktionen und Deklaration, die unter vb-express 2010 auf einem Rechner mit Windows 10 (64bit) maßgeblich ist, damit ich nicht immer wieder auf diese ärgerlichen Fehler stoße. Wer kann da helfen?
    @artnat Die korrekten .NET-Deklarationen findest Du hier:
    pinvoke.net/
    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!

    artnat schrieb:

    immer wieder
    Poste 3 (drei) Beispiele. ;)
    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!
    Machen wir es mal anders. VB-express 2010 unter windows 10 (64):
    Ich habe pinvoke.net die folgende Deklaration entnommen:

    Public Declare Function GetWindowText Lib "user32.dll" Alias "GetWindowTextA" _
    (ByVal hWnd As Long, _
    ByVal prmstrString As String, _
    ByVal nMaxCount As Long) As Long
    ...

    Diese Funktion wird mit einem vorher per GetWindow ermittelten Handle mit dem Wert lngHwnd so aufgerufen:

    Dim strTitel As String
    ...
    strTitel = CStr(255)
    GetWindowText(lngHwnd, strTitel, 255)

    Dabei wird ein PinvokeStackImbalance fehler gefunden. Was ist falsch daran?

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

    Schuss ins Grüne: Mach mal aus den beiden Long je Integer
    Aber Moment. das stünde ja schon auf pinvoke … - wenn man bei VB.NET Signature schaut.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    -Franky- schrieb:

    pinvoke ist zwar ganz nett, wäre aber der letzte Ort wo ich suchen würde. Meine erste Anlaufstelle ist die MS Dokumentation.
    Für mich ist pinvoke die erste Anlaufstelle.
    In der MS-Doku findest du vielleicht gute Beispiele für C++. Die kannst du zwar mit genügend Erfahrung auch in VB.Net adaptieren,
    aber bei pinvoke findest du die Signaturen für alle Sprachen. Und das ist für C# und VB.Net wesentlich hilfreicher.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

    artnat schrieb:

    Ich habe pinvoke.net die folgende Deklaration entnommen:
    Leider die falsche. Du hast die VB Signature: genommen, brauchst aber die VB.NET Signature:. Kleiner aber sehr feiner Unterschied, auf den du achten solltest.

    Laut pinvoke.net folgendermaßen:
    <DllImport("user32.dll", EntryPoint:="GetWindowText")>
    Public Function GetWindowText(ByVal hwnd As Integer, ByVal lpString As System.Text.StringBuilder, ByVal cch As Integer) As Integer
    End Function


    Wobei das hier ein Beispiel für einen Fehler ist? Das Window-Handle ist IntPtr und nicht Interger.

    VaporiZed schrieb:

    Schuss ins Grüne:
    hWnd ist immer ein IntPtr.

    VB.NET-Quellcode

    1. Public Declare Function GetWindowText Lib "user32.dll" Alias "GetWindowTextA" _
    2. (ByVal hWnd As IntPtr, _
    3. ByVal prmstrString As String, _
    4. ByVal nMaxCount As Integer) As Integer
    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!
    Hi

    @petaod
    Für mich ist pinvoke die erste Anlaufstelle.In der MS-Doku findest du vielleicht gute Beispiele für C++. Die kannst du zwar mit genügend Erfahrung auch in VB.Net adaptieren

    Die Erfahrung C++ lesen zu können ist aus der Not heraus gebohren weil es viele Bsp, auch in der MS Doku, in C++ gibt. Ich bin seit VB1 dabei, davor mit QBasic und GW-Basic und ein wenig VB1 für DOS, und in .NET bin ich seit der VS2003 dabei. Ich programmiere viel mit COM Interfaces und da findet man kaum Infos auf pinvoke. Da bleiben einem nur die MS Doku und die C++ Headerfiles als Quelle. Mir fehlen auf pinvoke einfach gewisse wichtige Infos. Mal als Bsp SHBrowseForFolder. Wo steht auf pinvoke das diese API eigentlich ab Windows Vista nicht mehr benutzt und stattdessen das Interface IFileDialog verwendet werden sollte? Und wie festgestellt wurde, das für GetWindowText(A/W) -> hWnd ein IntPtr ist und nicht Interger wie es auf pinvoke steht. Mir fehlt auch das korrekte Marshalling bei den Parametern. Alles zusammen genommen ist pinvoke deswegen für mich nicht die erste Anlaufstelle.
    Mfg -Franky-

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

    Ich habe in einem alten Vb.Net 2010 Projekt hingeschrieben, dass diese hier funktionieren.

    VB.NET-Quellcode

    1. <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
    2. Public Shared Function GetWindowText(hwnd As IntPtr) As Int32
    3. End Function
    4. <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
    5. Public Shared Function GetWindowText(hWnd As IntPtr,
    6. <Out> lpstring As StringBuilder, nmaxcount As Int32) As Int32
    7. End Function
    8. <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
    9. Public Shared Function GetWindowTextLength( hWnd As IntPtr) As Int32
    10. End Function


    EDIT: Hab hier noch einen KonsolenTest
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Option Strict On
    2. Option Explicit On
    3. Imports System.Text
    4. Imports System.Runtime.InteropServices
    5. Public Module Module1
    6. Public Sub Main()
    7. Dim activewins As New Dictionary(Of String, IntPtr)(ToActiveWindows)
    8. Dim awitem As KeyValuePair(Of String, IntPtr)
    9. For i As Int32 = 0 To activewins.Keys.Count - 1
    10. awitem = activewins.ElementAt(i)
    11. Console.WriteLine(String.Format("Windows{2}: {0}[{1}]", awitem.Key, awitem.Value.ToString, i))
    12. Next
    13. Console.ReadLine()
    14. End Sub
    15. End Module
    16. Public Module WindowsNatives
    17. Private ActiveWindows As New Dictionary(Of String, IntPtr)
    18. Public Delegate Function DCallBack(hwnd As IntPtr, lparam As Int32) As Boolean
    19. <DllImport("user32.dll", SetLastError:=True)>
    20. Public Function IsWindowVisible(hwnd As IntPtr) As Boolean
    21. End Function
    22. <DllImport("user32.dll", SetLastError:=True)>
    23. Public Function EnumWindows(lpenumfunc As DCallBack, lparam As Int32) As Int32
    24. End Function
    25. <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
    26. Public Function GetWindowText(hWnd As IntPtr,
    27. <Out> lpstring As StringBuilder, nmaxcount As Int32) As Int32
    28. End Function
    29. Public Function ToActiveWindows() As Dictionary(Of String, IntPtr)
    30. ActiveWindows.Clear()
    31. EnumWindows(AddressOf Enumerator, 0)
    32. Return ActiveWindows
    33. End Function
    34. Private Function Enumerator(hwnd As IntPtr, lParam As Int32) As Boolean
    35. Dim wintext = New StringBuilder (Int16.MaxValue)
    36. 'Enumerable.Range(0, Int16.MaxValue).ToList.ForEach(Sub(x) wintext.Append(" "c)) 'Funkst auch ohne
    37. If IsWindowVisible(hwnd) Then
    38. GetWindowText(hwnd, wintext, Int16.MaxValue)
    39. If Not ActiveWindows.ContainsKey(wintext.ToString.Trim) Then
    40. ActiveWindows.Add(wintext.ToString.Trim, hwnd)
    41. End If
    42. End If
    43. Return True
    44. End Function
    45. End Module


    Freundliche Grüsse

    exc-jdbi

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „exc-jdbi“ ()