Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Bluetooth Geräte in der Näher erkennen (https://www.delphipraxis.net/158132-bluetooth-geraete-der-naeher-erkennen.html)

Cylence 7. Feb 2011 07:53

Bluetooth Geräte in der Näher erkennen
 
Hallo,

ich möchte Bluetooth Geräte in der Nähe erkennen. Ich habe dazu schon etwas gefunden, was an sich auch mehr oder weniger geht:

Delphi-Quellcode:

uses
  jwaBluetoothApis;
 

procedure TForm1.BitBtn1Click(Sender: TObject);
var
  hRadio,hDeviceFind : THANDLE;
  hfind : HBLUETOOTH_RADIO_FIND;
  btfrp : TBlueToothFindRadioParams;
  radioInfo : BLUETOOTH_RADIO_INFO;
  deviceInfo : BLUETOOTH_DEVICE_INFO;
  deviceSearchParams : BLUETOOTH_DEVICE_SEARCH_PARAMS;
  Err, x : integer;
begin
  Memo1.Lines.Clear;
  x := 0;
  RefreshBtDevices;
  try
   try
    btfrp.dwSize := sizeof(btfrp);
    hFind := BluetoothFindFirstRadio(@btfrp, hRadio);
    BluetoothEnableDiscovery(hRadio,True);
    if (hFind > 0) then begin
      repeat
        BluetoothEnableDiscovery(hRadio,True);
        radioInfo.dwSize := sizeof(radioInfo);
        if (ERROR_SUCCESS = BluetoothGetRadioInfo(hRadio, radioInfo))
         then Memo1.Lines.Add('Radio: '+ radioInfo.szName)
         else Memo1.Lines.Add('unknown error');
        deviceInfo.dwSize := sizeof(deviceInfo);
        deviceSearchParams.dwSize := sizeof(deviceSearchParams);
        deviceSearchParams.fReturnUnknown := true;
        deviceSearchParams.fReturnRemembered := true;
        deviceSearchParams.hRadio := hRadio;
        hDeviceFind := BluetoothFindFirstDevice(deviceSearchParams, deviceInfo);
        BluetoothUpdateDeviceRecord(deviceInfo);
        Memo1.Lines.Add('Device: '+deviceInfo.szName);
        if deviceInfo.fConnected then Memo1.Lines.Add('Device is connected')
         else Memo1.Lines.Add('Device is not connected');
        try
          Memo1.Lines.Add('Last seen: '+ DateTimeToStr(SystemTimeToDateTime(deviceInfo.stLastSeen)));
        except

        end;
        try
          Memo1.Lines.Add('Class of Device: ' + IntToStr(deviceInfo.ulClassofDevice));
        except

        end;
        if (hDeviceFind>0) then begin
           while(BluetoothFindNextDevice(hDeviceFind, deviceInfo))
           do begin
              BluetoothGetDeviceInfo(hRadio, deviceInfo);
              BluetoothUpdateDeviceRecord(deviceInfo);
              Memo1.Lines.Add('Device: '+deviceInfo.szName);
              if deviceInfo.fConnected then Memo1.Lines.Add('Device is connected')
               else Memo1.Lines.Add('Device is not connected');
              try
                Memo1.Lines.Add('Last seen: '+ DateTimeToStr(SystemTimeToDateTime(deviceInfo.stLastSeen)));
              except
             
              end;
              try
                Memo1.Lines.Add('Class of Device: ' + IntToStr(deviceInfo.ulClassofDevice));
              except

              end;
           end;
           BluetoothFindDeviceClose(hDeviceFind);
        end;
        x := x+1;
      until
        (BluetoothFindNextRadio(hFind, hRadio)) or (x > 0);
      BluetoothFindRadioClose(hFind);
    end
    else begin
      Err := GetLastError;
      Memo1.Lines.Add(SysErrorMessage(Err)+' ('+inttostr(Err)+')');
    end;
   except
    on E:Exception do Memo1.Lines.Add('error'+e.Message);
   end;
  finally

  end;
end;
hier hab ich aber das Problem dann das nur die zuletzt gefundeenn geräte angezeigt werden, er aktualisiert diese nicht. Also wenn ich bei meinem Handy Bluetooth anschalte, muß ich erstmal in der windows bluetooth geräte suchen funktion kurz mal reinschaun und erst dann findet mein prog das gerät auch.
Dann habe ich das hier noch gefunden/bzw zusammengebastelt:

Delphi-Quellcode:
procedure TForm1.RefreshBtDevices;
var
  ASelParams: BLUETOOTH_SELECT_DEVICE_PARAMS;
  ASelParamsSize: dword;
begin
  ASelParamsSize := SizeOf(BLUETOOTH_SELECT_DEVICE_PARAMS);
  FillChar(ASelParams, ASelParamsSize, 0);
  with ASelParams do begin
    dwSize := ASelParamsSize;
    hwndParent := handle;
    fShowRemembered := False;
    fAddNewDeviceWizard := False;
    fShowUnknown := True;
    fShowAuthenticated := True;
    fSkipServicesPage := True;
    fForceAuthentication := False;
    cNumOfClasses := 0;
    cNumDevices := 0;
  end;
  XCounter := 0;
  fAbort := False;
  tHideBTWIndow.Create(False);
  BluetoothSelectDevices(@ASelParams);  
  BluetoothSelectDevicesFree(@ASelParams);
  fAbort := True;
end;

procedure tHideBTWIndow.Execute;
var
 TheWindowHandle: THandle;
begin
  priority := tpHigher;
  try
    while not Form1.fAbort do begin
     TheWindowHandle := FindAWindow('Bluetooth-Gerät auswählen', '');
     if TheWindowHandle<>0 then ShowWindow(TheWindowHandle,sw_Hide);
     if TheWindowHandle<>0 then PostMessage(TheWindowHandle,WM_CLOSE, 0, 0);
    end;
  except

  end;
end;
damit kann ich nun die Geräte aktualisieren, es erscheint dann immer das Windows BT Geräte suchen fenster, was ich mit einem Thread Schleisse. .... Sehr unschön so würd ich mal sagen. Kann ich irgendwie anders Windows sagen das es JETZT SOFORT nach neuen Bluetoot Geräten suchen soll? Wäre toll wenn mir jemand einen Tipp geben könnte.

Gruß tom

Deep-Sea 7. Feb 2011 08:31

AW: Bluetooth Geräte in der Näher erkennen
 
  1. Delphi-Quellcode:
    until (BluetoothFindNextRadio(hFind, hRadio)) or (x > 0);
    Du brichst die Schleife ab, wenn du ein weiteres Radio findest (oder wenn x größer 0 ist) aber machst weiter, wenn du KEINS findest? Sicher, dass du das so wolltest?
  2. Nutze doch auch für die Devices eine repeat-Schleife, dann musst du den kompletten Block mit dem Hinzufügen zum Memo nicht zwei mal schreiben: DRY.
  3. Vlt. solltest du bei deviceSearchParams den Wert fIssueInquiry auf true setzen :wink: (Und dir ggf. auch mal die anderen Werte ansehen, die es da noch so gibt.)

Cylence 7. Feb 2011 09:09

AW: Bluetooth Geräte in der Näher erkennen
 
Hi,

ja das mit dem Abbrechen aus der Schleife kommt, weil er sonst unendlich oft immer das selbe radio netzt wieder einliest, warum auch immer...
das is jetzt auch nur so ein First Test Code ;-)
naja mit dem Inqiry True hab ich keine Änderung bemerkt, geht immer noch nur wenn ich vorher das Selectdevices mache, erst dann wird aktualisiert. Aber da erscheint a das Windows Fenster wegen den geräten kurz und das taugt mir nicht, das geflacker kurz...
Die anderen Werte hab ich schon ausprobiert, auch beim SelectDevices, da gibts zb fAddNewDeviceWizard := False; usw.

Deep-Sea 7. Feb 2011 09:24

AW: Bluetooth Geräte in der Näher erkennen
 
Ich habe in einem Testprogramm folgendes gefunden:
Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
var
  hDeviceFind:THANDLE;
  deviceInfo:BLUETOOTH_DEVICE_INFO;
  deviceSearchParams:BLUETOOTH_DEVICE_SEARCH_PARAMS;
begin
  deviceInfo.dwSize := SizeOf(deviceInfo);
  With deviceSearchParams do
  begin
    dwSize := SizeOf(deviceSearchParams);
    fReturnAuthenticated := true;
    fReturnRemembered := true;
    fReturnUnknown := true;
    fReturnConnected := true;
    fIssueInquiry := true;
    cTimeoutMultiplier := 2;
    hRadio := 0;
  end;
  hDeviceFind := BluetoothFindFirstDevice(deviceSearchParams, deviceInfo);
  If hDeviceFind = 0 then RaiseLastOSError
  else try
    repeat
      ShowMessage('Device: ' + deviceInfo.szName);
      //BluetoothDisplayDeviceProperties(0, deviceInfo);
    until not BluetoothFindNextDevice(hDeviceFind, deviceInfo);
  finally
    BluetoothFindDeviceClose(hDeviceFind);
  end;
end;
Leider kann ich dir nicht viel dazu sagen, da es schon einige Zeit her ist und auch testen kann ich es nicht mehr, weil ich kein Bluetooth-Gerät hier habe.

Cylence 7. Feb 2011 09:53

AW: Bluetooth Geräte in der Näher erkennen
 
Hi,

danke für den code, ist aber ausser dem timeout ist das fast gleich wie das was ich probiere, ich werds mal testen, aber ich denke das ich da immer noch das selbe problem hab das ich erst nach windows neue BT geräte suchen, dann richtige ergebnisse bekomme.

Danke schonmal, ich werds mal checken, vielleicht macht das timeout ja den unterschied :-)

Deep-Sea 7. Feb 2011 09:56

AW: Bluetooth Geräte in der Näher erkennen
 
Zitat:

Zitat von Cylence (Beitrag 1080021)
[...] aber ausser dem timeout ist das fast gleich wie das was ich probiere [...]

Und das dort nicht explizit nach Radios gesucht wird :wink:

Cylence 7. Feb 2011 17:24

AW: Bluetooth Geräte in der Näher erkennen
 
Hi nochmal,

also ich hab das jetzt so ausprobiert, und es geht nicht, es findet zwar erstmal so die Geräte, aber wenn ich dann beim Handy BT ausschalt, bleibt das Gerät trotzdem in Reichweite laut pc, und auch das Lastseen Datum/Zeit aktualisiert sich. Nur wenn ich eben vorher kurz den nach geräte suchen wizard aufmache und sofort wieder weghau, dann gehts, dann aktualisiert es wirklich was für geräte da sind und welche nicht. Aber da hab ich eben immer kurz das geflacker, wenn das fenster vom wizard aufgeht und ich es mit dem thread schliesse. Hat keiner eine Idee wie man das Bluetooth geräte suchen auch starten kann, ohne das das fenster aufgeht?

schönen Abend noch an alle :-)

tom

Cylence 8. Feb 2011 07:19

AW: Bluetooth Geräte in der Näher erkennen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hier mal das test project was ich zusammen gebaut habe...

hathor 8. Feb 2011 08:47

AW: Bluetooth Geräte in der Näher erkennen
 
Fehler:

Warum wird der Cursor bewegt?
Programm lässt sich nur mit ALT-F4 beenden.

Ursache:
- das creierte Window ist unsichtbar,
- ein Button(OK) ist deaktiviert, bekommt aber trotzdem den Focus,
- die Prioritätserhöhung ist überflüssig!

Delphi-Quellcode:
procedure tHideBTWIndow.Execute;
var
 TheWindowHandle: THandle;
begin
  priority := tpHigher; // wozu ???
  try
    while not Form1.fAbort do begin
     TheWindowHandle := FindAWindow('Bluetooth-Gerät auswählen', '');
//     if TheWindowHandle<>0 then ShowWindow(TheWindowHandle,sw_Hide);
//     if TheWindowHandle<>0 then PostMessage(TheWindowHandle,WM_CLOSE, 0, 0);
    end;
  except

  end;
end;

sx2008 8. Feb 2011 09:05

AW: Bluetooth Geräte in der Nähe erkennen
 
Keine konkrete Lösung zu deinem Problem aber vielleicht doch ein nützlicher Hinweis:
Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
var
  hDeviceFind:THANDLE;
  deviceInfo:BLUETOOTH_DEVICE_INFO;
  deviceSearchParams:BLUETOOTH_DEVICE_SEARCH_PARAMS;
begin
  deviceInfo.dwSize := SizeOf(deviceInfo);
In obigem Code wird der Low-Level-Code (das Blutoothzeug) direkt mit High-Level-Code (Events) vermischt.
Das ist nicht gut, denn es fehlt eine Abstraktionsebene bzw. es verstösst gegen das Prinzip Single Level of Abstraction.
Hier fehlt schlichtweg eine Klasse, um die Zugiffe auf die Bluetooth-API zu kapseln.


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:04 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz