Wie zwei Listviews zusammenfügen?

  • VB.NET
  • .NET (FX) 1.0–2.0

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von Cheffboss.

    Wie zwei Listviews zusammenfügen?

    Moin! :)
    Ich habe folgendes Problem, ich lese mit zwei verschiedene Techniken alle Prozesse und Fenster auf.
    Da manche Programme wie „TheBat“ kein MainWindowTitle haben, müsste ich dies ohne die Process-Class auslesen.
    Jetzt möchte ich aber, beide Listviews zusammenfügen.
    Leider komme ich genau da nicht weiter!
    Man müsste prüfen 1. Ist der Prozess „TheBat“, in Listview2?
    Ziel ist es das leere Listview3(Siehe Pfeil) zu füllen.
    Aber keine doppelten Einträge!
    Ich hoffe ich könnte das Problem gut beschreiben.
    Freue mich auf eure Hilfe!
    BIG THX


    Visual Basic.NET 8o
    MS-SQL
    8o

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

    Da ein ListView ja nur Texte enthält, sollte doch eine einfache Textprüfung zum passenden Zusammenführungs-Ergebnis führen.
    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.
    @VaporiZed
    Danke, für deine Antwort. Aber ich weiß nicht wie ich das Umsetzen kann.

    @an alle
    Ich versuche es gerade so zu lösen, ich packe alle Fenstertitel und Prozesse in eine Listbox.
    Diese ich später wieder in ein passendes Listview einfügen möchte.
    Deshalb packe ich alle Einträge in die Listboxen, und entferne alle doppelten Einträge.
    Leider geht das Entfernen oft nicht, weil beide Fenster irgendein Umlaut oder Sonderzeichen hat, und dann mehrmals aufgelistet wird!
    Deswegen suche ich nun eine Lösung, wie man es richtig auslesen kann.
    (Siehe Bilder)
    Eine andere Möglichkeit habe ich bis jetzt noch nicht gefunden!

    VB.NET-Quellcode

    1. Private Declare Function GetWindowTextA Lib "user32" (ByVal hWnd As Integer, ByVal lpString As String, ByVal nMaxCount As Integer) As Integer


    Visual Basic.NET 8o
    MS-SQL
    8o
    Dann belass es bei den Textvergleichen bei den ersten 10 Zeichen. Oder probier es beim Vergleich mit dem LIKE-Operator. Da wird mit Ähnlichkeiten hantiert - AFAIK.
    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.
    Entferne alles was keine Zahlen oder Buchstaben sind aus dem Text. Dann hast du saubere Strings die du miteinander vergleichen kannst.
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen

    Cheffboss schrieb:

    @VaporiZed
    Danke, für deine Antwort. Aber ich weiß nicht wie ich das Umsetzen kann.

    @an alle

    Deshalb packe ich alle Einträge in die Listboxen, und entferne alle doppelten Einträge.
    Leider geht das Entfernen oft nicht, weil beide Fenster irgendein Umlaut oder Sonderzeichen hat, und dann mehrmals aufgelistet wird!
    Deswegen suche ich nun eine Lösung, wie man es richtig auslesen kann.


    schaumal ob das hilft

    VB.NET-Quellcode

    1. Option Strict On
    2. Public Class Form2
    3. Private Enum SelectionCriteria
    4. IsInBoth
    5. IsInFirstOnly
    6. IsInSecondOnly
    7. End Enum
    8. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    9. Dim l1 As New ListBox
    10. l1.Items.Add("dies ist ein Test")
    11. l1.Items.Add("um zu ermitteln")
    12. l1.Items.Add("ob in Listbox1")
    13. l1.Items.Add("ändere was")
    14. l1.Items.Add("Gratisporben & Freebies ? Kostenlos")
    15. Dim l2 As New ListBox
    16. l2.Items.Add("dies ist ein Test um")
    17. l2.Items.Add("um zu ermitteln ob")
    18. l2.Items.Add("ob in Listbox1")
    19. l2.Items.Add("mach was")
    20. l2.Items.Add("Ändere was")
    21. l2.Items.Add("Gratisporben & Freebies ? Kostenlos")
    22. l2.Items.Add("7, 8, 9, 22, 45")
    23. 'Listbox 1 to 3
    24. Dim a() As Object = CType(CompareListboxes(l1, l2, SelectionCriteria.IsInBoth), Object())
    25. ListBox1.DataSource = a
    26. Dim b() As Object = CType(CompareListboxes(l1, l2, SelectionCriteria.IsInFirstOnly), Object())
    27. ListBox2.DataSource = b
    28. Dim c() As Object = CType(CompareListboxes(l1, l2, SelectionCriteria.IsInSecondOnly), Object())
    29. ListBox3.DataSource = c
    30. End Sub
    31. Private Function CompareListboxes(ByVal l1 As ListBox, ByVal l2 As ListBox, ByVal sel As SelectionCriteria) As Array
    32. Select Case sel
    33. Case SelectionCriteria.IsInBoth
    34. Return (From l In l1.Items Join m In l2.Items On l Equals m Select l).ToArray
    35. Case SelectionCriteria.IsInFirstOnly
    36. Return (From l In l1.Items Where Not (From m In l2.Items Select m).Contains(l) Select l).ToArray
    37. Case SelectionCriteria.IsInSecondOnly
    38. Return (From l In l2.Items Where Not (From m In l1.Items Select m).Contains(l) Select l).ToArray
    39. Case Else
    40. Return Nothing
    41. End Select
    42. End Function
    43. End Class
    @mrMo
    Danke, ich versuche es gerade so zu lösen.
    Aber leider hat der ausgelesene String ein unbekanntes Zeichen.
    Ich sehe es nur im notepad++ Codierung ANSI.
    Da ist ein komisches Fragezeichen, aber ich kann dieses nicht raus Replace.
    Weiß jemand, wie man das Zeichen raus bekommt?




    @Kasi
    Danke, für den Code. Aber leider hilft er mir auch nicht viel weiter.

    @an alle
    Ich habe eine Idee, bin mir aber nicht sicher wie ich dies umsetzen kann.
    Ich habe eine Listbox1 mit den Fenstertiteln, und diese in eine ListOfString zusammengebunden.
    Deshalb habe ich die Idee, ob man das Problem so lösen kann:
    -- Alle Einträge vergleichen…
    -- Und nur ein Eintrag hinzufügen…



    Danke, für eure Hilfe! :thumbup:



    edit2:
    Leider habe ich mit dem Sonderzeichen ? noch Probleme, und könnte diese noch nicht lösen!
    Deshalb erstelle ich einen neuen Beitrag, zum neuen Problem-Thema.
    Visual Basic.NET 8o
    MS-SQL
    8o

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

    Nun ja, kannst ja alle Zeichen rausfiltern, die unerwünscht sind und dann eben den Rest zum Vergleich hernehmen. Da gab's vor nicht allzu langer Zeit einen Thread darüber.
    Aber woher kommen denn nun die "bereinigten" Schriftzüge? Hast Du jetzt 3 Sorten?
    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.
    @VaporiZed
    Ich muss leider mit zwei verschiedene Wege arbeiten um alle Fenster aufzulisten.
    Da nur mit der .NET ProccesClass nicht alle Fenster ausgelesen bekommt, z.B TheBat.
    Ich habe die zwei Schritte von meinen Code eingefügt.
    Wie gesagt es gibt zwei verschiedene Schritte die Infos vom System auszulesen.
    Wenn du willst kann ich dir noch das Modul1 posten.

    VB.NET-Quellcode

    1. Declare Function GetDesktopWindow Lib "user32" () As Integer
    2. Private Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal uCmd As Long) As Long
    3. Private Declare Function GetWindowTextA Lib "user32" (ByVal hwnd As Long, ByVal lpString As String, ByVal nMaxCount As Long) As Long
    4. Private Declare Function GetWindowInfo Lib "user32" (ByVal hwnd As Long, ByRef pwi As PWINDOWINFO) As Boolean
    5. Private Declare Function GetWindow Lib "user32" (ByVal hWnd As Integer, ByVal uCmd As Integer) As Integer
    6. Private Declare Function GetWindowTextA Lib "user32" (ByVal hWnd As Integer, ByVal lpString As String, ByVal nMaxCount As Integer) As Integer
    7. Private Declare Function GetWindowInfo Lib "user32" (ByVal hWnd As Integer, ByRef pwi As PWINDOWINFO) As Boolean
    8. ' Typen für GetWindowInfo
    9. Private Structure RECT
    10. Dim Left_Renamed As Integer
    11. Dim Top As Integer
    12. Dim Bottom As Integer
    13. End Structure
    14. Private Structure PWINDOWINFO
    15. Dim cbSize As Integer ' Strukturgröße
    16. Dim rcWindow As RECT ' Fensterkoordinaten
    17. Dim rcClient As RECT ' Clientkoordinaten
    18. Dim dwStyle As Integer ' Gibt WINDOWS_STYLES zurück
    19. Dim dwExStyle As Integer ' Gibt EXTENDED_WINDOWS_STYLES zurück
    20. Dim dwWindowStatus As Integer ' 1=Fenster ist aktives Fenster, 0=Fenster nicht aktiv
    21. Dim cxWindowBorders As Integer ' Rahmenbreite in px
    22. Dim cyWindowBorders As Integer ' Rahmenhöhe in px
    23. Dim atomWindowType As Short
    24. Dim wCreatorVersion As Short
    25. End Structure
    26. Private Const GW_CHILD As Short = 5 ' GetWindow: Erstes Kindfenster
    27. Private Const GW_HWNDNEXT As Short = 2 ' GetWindow: Nächstes Fenster gleicher Ebene
    28. Public Sub JetztAuslesen()
    29. Dim strTitel As String
    30. Dim wi As PWINDOWINFO
    31. Dim lngHwnd As Integer
    32. wi.cbSize = Len(wi)
    33. lngHwnd = GetWindow(GetDesktopWindow(), GW_CHILD) ' Erstes Kindfenster des Desktops
    34. Do Until lngHwnd = 0
    35. ' Zeige das Fenster, wenn es einen Titel hat und sichtbar ist
    36. GetWindowInfo(lngHwnd, wi)
    37. If (wi.dwStyle And &H10CF0000) = &H10CF0000 Then
    38. ' Titel des Fensters ermitteln
    39. strTitel = New String(CChar(vbNullChar), 255)
    40. GetWindowTextA(lngHwnd, strTitel, 255)
    41. strTitel = Replace(strTitel, vbNullChar, "")
    42. ' 1. Schritt!
    43. If strTitel <> "" AndAlso Module1.GetHwndEXE(lngHwnd) <> "" Then
    44. Me.ListBox1.Items.Add((strTitel))
    45. Me.ListBox2.Items.Add(Module1.GetHwndEXE(lngHwnd))
    46. End If
    47. End If
    48. lngHwnd = GetWindow(lngHwnd, GW_HWNDNEXT)
    49. Loop
    50. ' 2. Schritt!
    51. For Each prozlist As Process In Process.GetProcesses
    52. If prozlist.MainWindowTitle <> "" Then
    53. Me.ListBox1.Items.Add(prozlist.MainWindowTitle))
    54. Me.ListBox2.Items.Add(prozlist.MainModule.FileName)
    55. End If
    56. Next
    57. End Sub
    Visual Basic.NET 8o
    MS-SQL
    8o
    Ok, das ist die LowLevel-Variante. Aber da bekommst Du doch schon die ersten Prozesstitel. Wenn Du die sammelst, kannst Du doch mit der .NET-Variante noch die dazupacken, die Du noch nicht kennst, wo unterscheiden sich denn die Ergebnisse? In den Sonderzeichen? Wenn ja, vergleiche eben nur die von Sonderzeichen bereinigten Titel, bevor Du weitere Titel der finalen Liste hinzufügst.
    Beispiel:
    Die von Dir genannte LowLevel-Variante spuckt aus:
    • TheBat!
    • Foo » Bar
    • Test
    Die .NET-Variante spuckt aus:
    • Foo - Bar
    • Test
    Dann entfernst Du zum Vergleichen der Strings die Sonderzeichen aus den Titeln, sodass Du dann eben in der Hinzufügeschleife hast:

    Quellcode

    1. BereinigterTitel = TitelOhneSonderzeichen(RohtitelDesProzesses)
    2. BereitsBekannteTitelOhneSonderzeichen = BereitsBekannteTitel.Select(Function(x) TitelOhneSonderzeichen(x))
    3. Wenn bei "BereitsBekannteTitelOhneSonderzeichen" noch nicht "BereinigterTitel" drin ist, dann nimm RohtitelDesProzesses in die Liste "BereitsBekannteTitel" auf

    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.
    @VaporiZed
    Ich habe nun eine Funktion gefunden, die mir das unbekannte Zeichen im String als Fragezeichen anzeigt, diese ich dann ersetzten kann.
    Nun Versuche ich deinen Vorschlag umzusetzen.

    edit2:
    Danke, für deine Antwort. :)
    Der Code geht nun.
    Aber leider kommt nun ein neues Problem.
    Ich möchte die Werte von den zwei Listboxen in ein sauberes ListView kopieren.
    Den Fenstertitel und der passende Prozess.

    @an alle
    Hat jemand von euch ein Denkanstoß für mich?
    (Siehe Bild)




    VB.NET-Quellcode

    1. Private Function DelSpecCharInDotNet(strSource As String, Optional strPattern As String = "/W") As String
    2. Return System.Text.RegularExpressions.Regex.Replace(strSource, strPattern, "").Replace("?", " ")
    3. End Function
    4. Private Sub Button6_Click(sender As Object, e As EventArgs) Handles Button6.Click
    5. Dim BereinigterTitel As String = String.Empty
    6. Dim BereitsBekannteTitel As New List(Of String)
    7. For Each wert As String In Me.ListBox1.Items
    8. BereinigterTitel = DelSpecCharInDotNet(wert)
    9. If BereitsBekannteTitel.Contains(BereinigterTitel) Then Exit For
    10. BereitsBekannteTitel.Add(BereinigterTitel)
    11. Next
    12. Me.ListBox1.DataSource = Nothing
    13. Me.ListBox1.DataSource = (BereitsBekannteTitel)
    14. End Sub


    edit3:
    Ich glaube mir ist was eingefallen, ich werde morgen folgendes versuchen-
    In eine Listbox1 "Fenstertitel#Anwendung.exe"
    Und dies auf bereits bekannte Einträge prüfen.
    Und später mit Split(#) das Listview1 zu füllen.
    Ich hoffe das ich das morgen so hinbekomme.
    Werde mein Ergebnis morgen bekannt geben! 8-)
    Visual Basic.NET 8o
    MS-SQL
    8o

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

    @an alle
    Vielen Dank, ich habe es nun so lösen können. Einfach alle Titel und Prozesse in ein Listbox1 einfügen und diese dann mit Hilfe von Split in ein Listview1 kopieren.
    Und nochmals prüfen das kein doppelter Wert vorhanden ist.
    Visual Basic.NET 8o
    MS-SQL
    8o