Strings verbinden geht nicht ??

  • VB.NET

Es gibt 25 Antworten in diesem Thema. Der letzte Beitrag () ist von Rikudo.

    Strings verbinden geht nicht ??

    Aaaalso,

    Ich nutze folgendes um die aktiven fesnter auszulesen, sowie das handle, titel und status (maxmimized, minimized, normal)

    Spoiler anzeigen

    VB.NET-Quellcode

    1. #Region "Windowmanaging"
    2. Public Delegate Function CallBack(ByVal hwnd As IntPtr, ByVal lParam As Integer) As Boolean
    3. Public Declare Function EnumWindows Lib "user32.dll" (ByVal Adress As CallBack, ByVal y As Integer) As Integer
    4. Public Declare Function IsWindowVisible Lib "user32.dll" (ByVal hwnd As IntPtr) As Boolean
    5. Private Declare Function GetWindowText Lib "user32.dll" Alias "GetWindowTextA" (ByVal hwnd As Integer, ByVal lpWindowText As String, ByVal cch As Integer) As Integer
    6. Private Shared ActiveWindows As New ObjectModel.Collection(Of IntPtr)
    7. Private Declare Function IsZoomed Lib "user32.dll" (ByVal hwnd As Long) As Long
    8. Private Declare Function IsIconic Lib "user32.dll" (ByVal hwnd As Long) As Long
    9. Private Declare Function ShowWindow Lib "user32.dll" (ByVal hwnd As Integer, ByVal nCmdShow As Integer) As Integer
    10. Private Const Windows = 11
    11. Public Function GetWindows() As List(Of String)
    12. On Error Resume Next
    13. Dim VisibleWindow As String = Nothing
    14. Dim inVisibleWindow As String = Nothing
    15. Dim hwndlist As New List(Of String)
    16. ActiveWindows.Clear()
    17. For Each i In GetActiveWindows()
    18. Dim windtitle As String = GetWindowtitle(i).Trim(Chr(0))
    19. If Not windtitle = Nothing Then
    20. If IsWindowVisible(i) Then
    21. hwndlist.Add(i.ToString & "|||" & GetWindowState(i) & "|||" & GetWindowtitle(i) & ";;;")
    22. End If
    23. End If
    24. Next
    25. Return hwndlist
    26. End Function
    27. Public Shared Function GetWindowtitle(ByVal hwnd As IntPtr) As String
    28. On Error Resume Next
    29. Dim Text As String = Space(Int16.MaxValue)
    30. GetWindowText(hwnd, Text, Int16.MaxValue)
    31. Return Text.Trim
    32. End Function
    33. Public Shared Function GetActiveWindows() As ObjectModel.Collection(Of IntPtr)
    34. On Error Resume Next
    35. EnumWindows(AddressOf Enumerator, 0)
    36. Return ActiveWindows
    37. End Function
    38. Private Shared Function Enumerator(ByVal Hwnd As IntPtr, ByVal lParam As Integer) As Boolean
    39. On Error Resume Next
    40. ActiveWindows.Add(Hwnd)
    41. Return True
    42. End Function
    43. Public Shared Function GetWindowState(hwnd As String) As String
    44. If IsZoomed(hwnd) = 1 Then 'maximized
    45. Return "Maxmimized"
    46. ElseIf IsIconic(hwnd) = 1 Then 'minimized
    47. Return "Minimized"
    48. End If
    49. Return "Normal"
    50. End Function
    51. #End Region


    Das seltsame ist, wenn ich die Funktion so anspreche:

    VB.NET-Quellcode

    1. For Each item As String In GetWindows()
    2. ListBox1.Items.Add(item)
    3. Next


    Dann geht es, alle einträge werden in der ListBox gelistet.
    Wenn ich jetzt allerdings alle Informationen der Fenster zusammenfügen möchte, etwas so:
    1234567|||Maximized|||TitelVonFenster1;;;76543|||Minimized|||TitelVonFenster2;;;9387234|||Maximized|||TitelVonFenster3 ...
    Und ich versuche die Strings so zu verbinden, dann geht es nicht:

    VB.NET-Quellcode

    1. Dim test as String = Nothing
    2. For Each item As String In GetWindows()
    3. test &= item
    4. Next
    5. MsgBox(test)


    Es wird mir lediglich ein Informationsset angezeigt, also nur von einem Fenster, anstatt alle informationen in einen String verknüpft?
    Wieso geht das nicht??
    C# Developer
    Learning C++

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

    Gonger96 schrieb:

    Sämtliche Deklarationen sind falsch, schau mal bei Pinvoke.net vorbei. On Error Resume Next ? ;(

    Aber das ansprechen der Funktionen geht ja, die Daten werden ja zurückgegeben, nur nicht zu einem einzelnen String verknüpft??
    C# Developer
    Learning C++

    Gonger96 schrieb:

    Trotzdem sind die falsch. Ändere erstmal diese Fehler, dann kümmern wir uns ums Problem

    Habe gerade mal die unnötigen rausgenommen, meinst du mit falsch das sie stattdessen mit DLLImport angesprochen werden sollten?
    C# Developer
    Learning C++
    Hi
    übrigens werden Strings im Normalfall an einem 0-Char abgeschnitten (also ein Char mit dem Wert 0). Dieses bleibt bei der Konkatenation von zwei Strings weiter vorhanden, wenn der String nicht die volle Länge ausnutzt, die für ihn reserviert wurde (hier verhält sich die String-Klasse anders, als C-Strings).

    Gruß
    ~blaze~

    Gonger96 schrieb:

    Auch das. Aber allg. sind die Typen falsch. Für Zeiger nimmt man IntPtr und am Rückgabetyp Long zweifel ich auch

    So bitte sehr, ich habe alles mal auf DLLImport geändert und die Rückgabewerte angepasst:

    VB.NET-Quellcode

    1. #Region "Windowmanaging"
    2. Public Delegate Function CallBack(ByVal hwnd As IntPtr, ByVal lParam As Integer) As Boolean
    3. Private Delegate Function EnumWindowsProc(ByVal hWnd As IntPtr, ByVal lParam As IntPtr) As Boolean
    4. Private Shared ActiveWindows As New ObjectModel.Collection(Of IntPtr)
    5. <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
    6. Private Shared Function EnumWindows(ByVal lpEnumFunc As EnumWindowsProc, ByVal lParam As IntPtr) As Boolean
    7. End Function
    8. <DllImport("user32.dll")> _
    9. Public Shared Function IsWindowVisible(hwnd As Integer) As Integer
    10. End Function
    11. <DllImport("user32.dll")> _
    12. Public Shared Function GetWindowText(hwnd As Integer, lpstring As String, cch As Integer) As Integer
    13. End Function
    14. <DllImport("user32.dll")> _
    15. Public Shared Function IsZoomed(hwnd As Integer) As Integer
    16. End Function
    17. <DllImport("user32.dll")> _
    18. Public Shared Function IsIconic(hwnd As Integer) As Integer
    19. End Function
    20. <DllImport("user32.dll")> _
    21. Public Shared Function ShowWindow(hwnd As Integer, nCmdShow As Integer) As Integer
    22. End Function
    23. Private Const Windows = 11
    24. Public Function GetWindows() As List(Of String)
    25. On Error Resume Next
    26. Dim VisibleWindow As String = Nothing
    27. Dim inVisibleWindow As String = Nothing
    28. Dim hwndlist As New List(Of String)
    29. ActiveWindows.Clear()
    30. For Each i In GetActiveWindows()
    31. Dim windtitle As String = GetWindowtitle(i).Trim(Chr(0))
    32. If Not windtitle = Nothing Then
    33. If IsWindowVisible(i) Then
    34. hwndlist.Add(i.ToString & "|||" & GetWindowState(i) & "|||" & GetWindowtitle(i) & ";;;")
    35. End If
    36. End If
    37. Next
    38. Return hwndlist
    39. End Function
    40. Public Shared Function GetWindowtitle(ByVal hwnd As IntPtr) As String
    41. On Error Resume Next
    42. Dim Text As String = Space(Int16.MaxValue)
    43. GetWindowText(hwnd, Text, Int16.MaxValue)
    44. Return Text.Trim
    45. End Function
    46. Public Shared Function GetActiveWindows() As ObjectModel.Collection(Of IntPtr)
    47. On Error Resume Next
    48. EnumWindows(AddressOf Enumerator, 0)
    49. Return ActiveWindows
    50. End Function
    51. Private Shared Function Enumerator(ByVal Hwnd As IntPtr, ByVal lParam As Integer) As Boolean
    52. On Error Resume Next
    53. ActiveWindows.Add(Hwnd)
    54. Return True
    55. End Function
    56. Public Shared Function GetWindowState(hwnd As String) As String
    57. If IsZoomed(hwnd) = 1 Then 'maximized
    58. Return "Maxmimized"
    59. ElseIf IsIconic(hwnd) = 1 Then 'minimized
    60. Return "Minimized"
    61. End If
    62. Return "Normal"
    63. End Function
    64. #End Region


    Allerdings kann ich die Funktion jetzt überhaupt nicht mehr ansprechen, im vgl zu vorher, bzw, jetzt passiert überhaupt nichts mehr :c
    Wo ist das Problem?
    Ich möchte lediglich die Information aller Fenster (Jedes Fenster hat ein Handle, Titel und Status), in einen String verpacken und zurückgeben.
    C# Developer
    Learning C++
    Da du mich wieder mal übergangen hast und ich das äußerst unhöflich finde, hatte ich eigentlich nicht vor, nochmal was zu sagen, aber On Error Resume Next ist ein nogo. Außerdem sind hwnd grundsätzlich IntPtr und lParam ist einmal IntPtr und einmal Integer. Schau' halt auf der MSDN nach...

    Gruß
    ~blaze~
    Tut mir leid war nicht böse gemeint, aber ich habe nicht darauf reagiert weil ich nicht verstanden habe was du damit meinst...
    Ich überprüfe jetzt nochmal die Deklarationen auf msdn...

    EDIT:

    Habe die DllImports nochmals bearbeitet:

    VB.NET-Quellcode

    1. Public Delegate Function CallBack(ByVal hwnd As IntPtr, ByVal lParam As Integer) As Boolean
    2. Private Shared ActiveWindows As New ObjectModel.Collection(Of IntPtr)
    3. Private Delegate Function EnumWindowsProc(hWnd As IntPtr, lParam As IntPtr) As Boolean
    4. Public Declare Auto Function GetWindowText Lib "user32.dll" (ByVal hwnd As IntPtr, ByVal lpString As String, ByVal cch As Integer) As Integer
    5. <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
    6. Private Shared Function EnumWindows(callback As EnumWindowsProc, extraData As IntPtr) As Boolean
    7. End Function
    8. <DllImport("user32.dll", CharSet:=CharSet.Auto)> _
    9. Public Shared Function IsWindowVisible(ByVal hWnd As IntPtr) As Boolean
    10. End Function
    11. <DllImport("user32.dll", CharSet:=CharSet.Auto, ExactSpelling:=True)> _
    12. Public Shared Function IsZoomed(ByVal hWnd As IntPtr) As Boolean
    13. End Function
    14. <DllImport("user32.dll")> _
    15. Public Shared Function IsIconic(hwnd As Integer) As Boolean
    16. End Function
    17. <DllImport("user32.dll")> _
    18. Public Shared Function ShowWindow(hwnd As Integer, nCmdShow As Integer) As Integer
    19. End Function
    20. Private Const Windows = 11

    Habe aber wieder das selbe Problem wie am Anfang, in der ListBox gibt er alle aus, beim concating aber verknüpft er sie nicht... :C
    C# Developer
    Learning C++

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

    Überleg mal ob ein HWND (ein Zeiger auf _HWND) ein int sein kann, obwohl er an anderer Stelle ein IntPtr ist und obwohl dir @~blaze~: bereits gesagt hat, dass Handles und Zeiger generell als IntPtr gemarashallt werden (bis auf Strings natürlich).

    Gonger96 schrieb:

    Überleg mal ob ein HWND (ein Zeiger auf _HWND) ein int sein kann, obwohl er an anderer Stelle ein IntPtr ist und obwohl dir @~blaze~: bereits gesagt hat, dass Handles und Zeiger generell als IntPtr gemarashallt werden (bis auf Strings natürlich).

    Okay, habs nochmals *schwitz* überarbeitet, jetzt werden die DatenTypen IntPtr verwendet.

    VB.NET-Quellcode

    1. Public Delegate Function CallBack(ByVal hwnd As IntPtr, ByVal lParam As IntPtr) As Boolean
    2. Private Shared ActiveWindows As New ObjectModel.Collection(Of IntPtr)
    3. Private Delegate Function EnumWindowsProc(hWnd As IntPtr, lParam As IntPtr) As Boolean
    4. Public Declare Auto Function GetWindowText Lib "user32.dll" (ByVal hwnd As IntPtr, ByVal lpString As String, ByVal cch As IntPtr) As IntPtr
    5. <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
    6. Private Shared Function EnumWindows(callback As EnumWindowsProc, extraData As IntPtr) As Boolean
    7. End Function
    8. <DllImport("user32.dll", CharSet:=CharSet.Auto)> _
    9. Public Shared Function IsWindowVisible(ByVal hWnd As IntPtr) As Boolean
    10. End Function
    11. <DllImport("user32.dll", CharSet:=CharSet.Auto, ExactSpelling:=True)> _
    12. Public Shared Function IsZoomed(ByVal hWnd As IntPtr) As Boolean
    13. End Function
    14. <DllImport("user32.dll")> _
    15. Public Shared Function IsIconic(hwnd As IntPtr) As Boolean
    16. End Function
    17. <DllImport("user32.dll")> _
    18. Public Shared Function ShowWindow(hwnd As IntPtr, nCmdShow As IntPtr) As IntPtr
    19. End Function
    20. Private Const Windows = 11


    Die Items werden wie gesagt in die ListBox eingetragen, aber das verknüpfen der Strings geht nach wie vor nicht...
    C# Developer
    Learning C++
    Ich glaube außerdem, dass es wirklich an der Nullterminierung liegt. Strings enden in C bei der Darstellung auf \0, d.h. ein "0-Int16". Es handelt sich dabei um einen Sonder-Buchstaben, der eben den Wert 0 hat und einen String beendet (terminiert). .Net verwendet für Strings ein anderes Konzept; es hält die Puffergröße bereit, usw. Wenn du also einen String erzeugst, der auf \0 endet - was er bei dir wohl tut - und diesen an einen weiteren hängst, hast du ein \0 im String selbst und die Anzeige bricht dort ab, weil sie nicht auf dem .Net-Konzept, sondern auf dem C-Konzept basiert.

    Gruß
    ~blaze~
    Okay, das heisst mein String wird terminiert bevor ich den nächsten Teil anknüpfe, habe ich das so richtig verstanden?
    Und was kann ich machen das dies nicht passiert?
    Wo genau wird den dieser 0-String bei mir erzeugt?
    C# Developer
    Learning C++
    Ich würde darauf tippen, dass das hier geschieht:

    VB.NET-Quellcode

    1. Public Shared Function GetWindowtitle(ByVal hwnd As IntPtr) As String
    2. On Error Resume Next
    3. Dim Text As String = Space(Int16.MaxValue)
    4. GetWindowText(hwnd, Text, Int16.MaxValue)
    5. Return Text.Trim
    6. End Function

    Die Space-Funktion ist btw. ein Relikt, da kannst du stattdessen den Konstruktor von String benutzen: [ic=vb]New String(Chr(0), Short.MaxValue)[/vb], wobei es glaub' ich auch eine GetWindowTextLength-Funktion gibt, die du dafür stattdessen verwenden könntest. Statt Trim würde man dann eben TrimEnd(Chr(0)) oder sowas benutzen, wenn du auf GetWindowTextLength verzichtest. Du hast dann aber im Normalfall eine große Menge Speicher im Vergleich zum effektiv benötigten Speicher verpulvert.

    Gruß
    ~blaze~
    Perfekt ~blaze~, das war tatsächlich der Grund ^^
    So geht es:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Delegate Function CallBack(ByVal hwnd As IntPtr, ByVal lParam As IntPtr) As Boolean
    2. Private Shared ActiveWindows As New ObjectModel.Collection(Of IntPtr)
    3. Private Delegate Function EnumWindowsProc(hWnd As IntPtr, lParam As IntPtr) As Boolean
    4. Public Declare Auto Function GetWindowText Lib "user32.dll" (ByVal hwnd As IntPtr, ByVal lpString As String, ByVal cch As IntPtr) As IntPtr
    5. <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
    6. Private Shared Function EnumWindows(callback As EnumWindowsProc, extraData As IntPtr) As Boolean
    7. End Function
    8. <DllImport("user32.dll", CharSet:=CharSet.Auto)> _
    9. Public Shared Function IsWindowVisible(ByVal hWnd As IntPtr) As Boolean
    10. End Function
    11. <DllImport("user32.dll", CharSet:=CharSet.Auto, ExactSpelling:=True)> _
    12. Public Shared Function IsZoomed(ByVal hWnd As IntPtr) As Boolean
    13. End Function
    14. <DllImport("user32.dll")> _
    15. Public Shared Function IsIconic(hwnd As IntPtr) As Boolean
    16. End Function
    17. <DllImport("user32.dll")> _
    18. Public Shared Function ShowWindow(hwnd As IntPtr, nCmdShow As IntPtr) As IntPtr
    19. End Function
    20. Private Const Windows = 11
    21. Public Function GetWindows() As List(Of String)
    22. Dim VisibleWindow As String = Nothing
    23. Dim inVisibleWindow As String = Nothing
    24. Dim hwndlist As New List(Of String)
    25. ActiveWindows.Clear()
    26. For Each i In GetActiveWindows()
    27. Dim windtitle As String = GetWindowtitle(i).Trim(Chr(0))
    28. If Not windtitle = Nothing Then
    29. If IsWindowVisible(i) Then
    30. hwndlist.Add(i.ToString & "|||" & GetWindowState(i) & "|||" & GetWindowtitle(i) & ";;;")
    31. End If
    32. End If
    33. Next
    34. Return hwndlist
    35. End Function
    36. Public Shared Function GetWindowtitle(ByVal hwnd As IntPtr) As String
    37. Dim Text As String = New String(Chr(0), Short.MaxValue)
    38. GetWindowText(hwnd, Text, Int16.MaxValue)
    39. Return Text.TrimEnd(Chr(0))
    40. End Function
    41. Public Shared Function GetActiveWindows() As ObjectModel.Collection(Of IntPtr)
    42. EnumWindows(AddressOf Enumerator, 0)
    43. Return ActiveWindows
    44. End Function
    45. Private Shared Function Enumerator(ByVal Hwnd As IntPtr, ByVal lParam As Integer) As Boolean
    46. ActiveWindows.Add(Hwnd)
    47. Return True
    48. End Function
    49. Public Shared Function GetWindowState(hwnd As String) As String
    50. If IsZoomed(hwnd) = 1 Then
    51. Return "Maxmimized"
    52. ElseIf IsIconic(hwnd) = 1 Then
    53. Return "Minimized"
    54. End If
    55. Return "Normal"
    56. End Function
    57. #End Region


    Und dann aufrufen mit:

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. Dim Test As String = Nothing
    3. For Each item As String In GetWindows()
    4. Test &= item
    5. Next
    6. MsgBox(test)
    7. End Sub
    C# Developer
    Learning C++
    msdn.microsoft.com/en-us/libra…op/ms633521(v=vs.85).aspx
    pinvoke.net/default.aspx/user32/GetWindowTextLength.html
    das sind btw. auch interessante Quellen für dich.
    Außerdem noch was: Durch die ActiveWindows-Funktion ist das ganze nicht wirklich sauber gelöst. Überleg' mal, was passiert, wenn du's mehrfach aufrufst und außerdem ist der Status der Liste nicht durchgehend gültig. ;)

    Gruß
    ~blaze~