ListBox permanent aktualisieren und GUI aktiv halten



  • Hallo leute,

    ich habe ein kleinen BluetoothScanner Methode geschrieben, welches die gefundenen Devices in die ListBox schreibt. Das klappt für die einmalige Anwendung prima.
    Was ich nun will:
    -ListBox soll sich permanent aktualisieren: devices werden automatisch entfernt und hinzugefügt.

    Wenn ich das nun mit einer unendlichen while-Schleife mache, stürtzt meine UI ab. Kann mir jemand da unter die Arme greifen?

    Hier die Funktion für die ListBox Elemente:

    void BluetoothFunction(){
    			m_bt = BluetoothFindFirstRadio(&m_bt_find_radio, &m_radio);
    
    				int m_device_id=0;
    				int m_radio_id = 0;
    				m_radio_id=0;
    				BluetoothGetRadioInfo(m_radio, &m_bt_info);
    
    				m_search_params.hRadio = m_radio;
                    ::ZeroMemory(&m_device_info, sizeof(BLUETOOTH_DEVICE_INFO));
    				m_device_info.dwSize = sizeof(BLUETOOTH_DEVICE_INFO);
    				m_bt_dev = BluetoothFindFirstDevice(&m_search_params, &m_device_info);
    
    				do{
    					wostringstream tmp;
    					++m_device_id;						   			    
    					//Konvertiere Byte in String
    					for (int i = 0; i < 6; i++) {
    					  tmp << hex << m_device_info.Address.rgBytes [i];
    			    	  if (i < 5)
    						tmp << L':';
    					} 						
    					listBox1->Items->Add(System::Runtime::InteropServices::Marshal::PtrToStringUni(IntPtr((void*) tmp.str().c_str())));
    				}while(BluetoothFindNextDevice(m_bt_dev, &m_device_info));
    				BluetoothFindDeviceClose(m_bt_dev);	
    
    	}
    

    Über eine baldige Rückmeldung wäre ich sehr Dankbar.

    Schöne Grüße



  • Des Weiteren habe ich es mit einen Backroundworker probiet. Da ist leider das Problem, dass beim Adden in die ListBox eine Threadübergreifende Funktion ausfüht und mir eine Fehlermeldung beim listbox1->Items-> ... anzeigt!



  • Du kannst die Logik in einer Klasse kapseln, und wenn Geräte hinzukommen oder entfernt werden, ein Event auslösen und dann entsprechend die GUI aktualisieren. Das Polling könntest du in einem anderen Thread machen. Und das brauchst du wohl sicher nicht ununterbrochen machen, kannst mindestens 1 Sekunde Pausen einlegen.
    In deinem Code seh ich erstmal keine Endlosschleife (kenn die Bluetooth API aber nicht, vielleicht hast du da einen Fehler), also sollte sich die GUI erstmal nicht aufhängen.



  • Sorry - hatte die endlosschleife rausgenommen mit diesen Code hängt es nicht. 🙂 Somit könnte ich alle verfügbaren Geräte in Umgebung einmalig scannen. Dachte es gibt eine ganz simpele Methode.

    Kannst du mir dein Vorgehen nochmal Schritt für Schritt erläutern. Programmiere das gerade in VS 2012, wo ich die GUI auch per Drag and Drop "zusammengeklickt" habe. Mein Header hat zum einen die includeDateien und das Namespace der GUI wo alles von statten geht. Kann ich das irgendwie nicht bei der Hauptklasse neben der Main-Methode realisieren?



  • CLINoob schrieb:

    Kann ich das irgendwie nicht bei der Hauptklasse neben der Main-Methode realisieren?

    Ist nicht sinnvoll. Man sollte gleich lernen, seine Programme sinnvoll zu strukturieren. Dazu gehört auch, dass man Darstellung und Logik trennt. Die Logik ist bei dir das scannen nach Bluetooth Geräten, die sollte nichts über die Darstellung wissen (du fügst da direkt irgendwelche Elemente in die Listbox ein, wenn du was gefunden hast, damit ist es überhaupt nicht wiederverwendbar).
    Mach eine eigene Klasse, BluetoothEnumerator oder so. Die kann paar Events haben, z.B. OnDeviceAdded und OnDeviceRemoved oder vielleicht einfach OnDeviceListChanged. Die Devices haben eindeutige Kennungen, wenn du sie speicherst, kannst du beim nächsten Durchlauf erkennen, ob sich die Liste geändert hat.

    Sicher, dass du C++/CLI programmieren möchtest? Das ist weder richtiges C++ noch richtiges .NET, das ist eigentlich nur eine Sprache, um Bridges zwischen nativen und .NET Programmen zu schreiben, aber nicht um richtige Programme damit zu schreiben.



  • Das macht sinn es zu trennen.

    Schreibe also eine Klasse, welches die Logik enthält mit ganz vielen Methoden für verschiedene Events die eintreffen. Melde mich in einer halben Stunde wieder mit den Ergebnissen 🙂

    Eine Frage vorab. Wie kann ich mit CLI meine Klasse in der GUI-Ebene aufrufen?

    Wollte zunächst in QT Programmieren, aber die haben die Bluetooth API rausgeschmissen und ist komerziell. Danach wollte ich es in MFC machen, aber das ist auch viel zu Aufwändig für meine kleine Anwendung.

    Kennst du ein guten Add in für VS 2012 womit ich meine GUI in C++ einfach zusammenklicken kann?

    Schöne Grüße



  • CLINoob schrieb:

    Wollte zunächst in QT Programmieren, aber die haben die Bluetooth API rausgeschmissen und ist komerziell.

    Nee, ist nicht kommerziell. Es gibt auch eine LGPL Lizenz, benutzen wir auch in der Arbeit. Die Bluetooth API gehört ja zu Windows, es spielt keine Rolle, ob du noch Qt oder sonst was verwendest. Von MFC würde ich die Finger lassen, die API ist 20 Jahre alt und ziemlich hässlich und kann nichts.

    CLINoob schrieb:

    Eine Frage vorab. Wie kann ich mit CLI meine Klasse in der GUI-Ebene aufrufen?

    Was meinst du damit?



  • Meinst du ich kann mit QT die BluetoothAPI von Windows verwenden? Ich glaube nicht - hatte es schonmal provisorisch probiert gehabt.

    MFC hat mir mal ein User von Stackoverflow empfohlen - das ist unmöglich damit.

    Angenommen ich programmiere weiter mit CLI und habe die Logik in einer seperaten klasse mit verschiedenen Methoden. Wie kann ich diese spezifische Klasse aufrufen mit den entsprechenden Methoden?



  • Ich sehe überhaupt keinen Grund, warum sich Qt und die Bluetooth API gegenseitig ausschließen sollten. Das eine hat mit dem anderen überhaupt nichts zu tun. Genausowenig wie MFC. Qt und MFC sind einfach zusätzliche Bibliotheken, die können dich nicht daran hindern, irgendwelche anderen Bibliotheken einzusetzen.

    Wenn du die Klasse geschrieben hast, würdest du vielleicht sowas machen:

    BluetoothEnumerator _enumerator = null;
    
    void OnFormCreated()
    {
      _enumerator = new BluetoothEnumerator();
      _enumerator.OnDeviceListChanged += DeviceListChanged();
    }
    
    void DeviceListChanged()
    {
      List<string> deviceNames = _enumerator.GetDeviceNames();
      listBox1.Clear();
      listBox1.Items.Add(deviceNames);
    ]
    

    Das ist jetzt C# Pseudocode, weil ich grad keine Lust habe, mich an die C++/CLI Syntax zu erinnern 🙂 Ob das mit Items.Add so geht weiß ich jetzt nicht mehr, notfalls noch eine Schleife.



  • Habe mich mal kurzfristig an QT 5 gesetzt. Wenn ich nun mit QTCreator versuche die BluetoothAPI einzubinden mit #include werden die benötigten Dateien erst gar nicht von intellisense vorgeschlagen, dass ist das was ich mit nicht verfügbar meinte. Wenn du mir etwas erläuterst mit qt dann würde ich sehr gerne meine Anwendung in QT schreiben. 🙂 Wärst du so nett und kannst mir erläutern, wie ich die BluetoothAPi einbinde?

    Vielen Dank. Deine Idee werde ich morgen weiterverfolgen. 🙂



  • Ob die Intellisense richtig funktioniert ist bei C++ immer so eine Frage 😉

    Schau in die MSDN zu den von dir verwendeten Funktionen. Da steht fast immer, welchen Header man inkludieren und welche Lib man dazulinken musst. Im QtCreator (du kannst übrigens auch Visual Studio für Qt verwenden) musst du dann die Include und die Linkpfade angeben. Bei Visual Studio waren wohl schon die richtigen Pfade voreingestellt, vielleicht kannst da in den Projekteinstllungen schauen, wo das Zeug bei dir rumliegt.



  • Nun weiß ich zwar wo mein Fehler liegt, aber nicht wie ich es lösen kann. Das mit QT schiebe ich mal zu seite, weil die Konfigurationen einfach zu langwierig sind. 😞

    Stelle mal die Frage neu, eventuell kann mir jemand behilflich sein mit c++/cli



  • Was ist dir noch nicht klar?


Anmelden zum Antworten