![]() |
Event wenn Digitalkamera angeschlossen wird...
Moin,
da ich vorhin über dieses Forum gestolpert bin bei der Suche nach der Lösung meines Problems, stelle ich die Frage auch direkt mal hier... Also, folgendes: Ich habe mir dieser Tage eine Digitalkamera von Casio gekauft *tusch* und musste dabei leider feststellen, das die beiligende Software "Photo Loader" nicht das Gelbe vom Ei ist... Deshalb wollte ich mal prüfen, ob es möglich ist, so etwas in der Art selbst zu fabrizieren. Das Casio-Program nistet sich im System-Tray ein (das ist natürlich in Delphi kein Problem) und wird aktiv, sobald man die Kamera an den USB anschliesst. Und das ist das Problem, das ich hier mal zur Sprache bringen will... :mrgreen: Komponenten, die mir in dieser Sache weiterhelfen habe ich bisher keine gefunden. Die JvHidControllerClass aus dem Jedi Projekt hat mich auch kaum weitergebracht, da eine Kamera scheinbar kein HID zu sein scheint... Mein zweiter Ansatz war, die WM_DEVICECHANGE-Nachrichten auszuwerten. Das funktioniert auch soweit irgendwie, ich bekomme die Nachricht, wenn ich sie anschliesse und bekomme auch den neuen Laufwerksbuchstaben raus. Eindeutig identifizeren kann ich das Gerät aber irgendwie nicht. Und nur ein Test auf das Verzeichnis "DCIM" halte ich für nicht gut genug. Ich denke, der richtige Weg geht wahrscheinlich über die API-Funktionen rund um ![]() Hat jemand schon mal in dieser Richtung was gemacht, oder weiss jemand ne gute Komponente, die das Problem lösen kann? Oder hat jemand nen Link zu einer Doku, die mir vielleicht weiterhelfen könnte? Eins noch eben: Es geht NICHT darum, eine Steuerungssoftware via USB für Digicams zu schreiben. Die meisten Kameras liefern einen Treiber mit, der sie als "Wechseldatenträger" im System anmeldet. Das Kopieren der Bilder lässt sich dann mit den ganz normalen Datei-Routinen von Delphi lösen. Hmm... ziemlich viel Text. Hoffentlich konnte ich klarmachen, was ich wollte... ansonsten stehe ich gerne für Rückfragen zu Verfügung. :mrgreen: Mit freundlichem Gruß Wormid |
Re: Event wenn Digitalkamera angeschlossen wird...
wm_DeviceChange ist schon der richtige Ansatz, mehr kanste auch nicht mit Treibern machen. Das Problem: der USB Treiber ist ein stinknormaler MS USB Treiber für FAT formatierte Systeme. Es ist eigentlich nicht vorgesehen das die CASIO dem System mitteilt das sie als CASIO Gerät am USB hängt. Das liegt daran das die CASIO selber nur die USB Anforderungen direkt an das MicroDrive, eg. CF Controller weiterleitet. Was du also herrausbekommen könntest wäre das am anderen Ende des USB Kabels ein MicroDrive/CF Speicherkarte bzw. ein CF Controller werkelt.
Dein Ansatz nach dem Ordner DCIM zu suchen ist somit der einfachste und meiner Meinung nach beste. Nur solltest du dies konfigurierbar machen. Ich z.B. nutze bei meiner QV5700 einen separaten CF2 Cardreader, was ich da reinschiebe interessiert den USB Treiber überhaupt nicht, Hauptsache FAT formatiert. Da aber jede Formatierung einer solchen Karte auch eine Serialnummer zur Partition verwaltet, kannste die ja auswerten. Erst falls das CF Medium komplett neu formatiert wird, wird diese verändert. Oder du könntest auf der Karte eine eigene Datei in Root ablegen. Gruß Hagen |
Re: Event wenn Digitalkamera angeschlossen wird...
Moin,
hmm... ich bin also zumindestens auf dem richtigen Weg, das freut mich ja zu hören. :mrgreen: Dateien auf der Karte erstellen kommt für mich nicht in Frage, die Originalsoftware kann das auch ohne, also will ich das auch. Außerdem möchte ich meine Software (falls es denn mal eine wird) schon "generic" halten - sie soll also nicht CASIO-spezifisch sein. Den Ordner "DCIM" sollte es eigentlich auf allen Cam-Speichermedien geben, die sich an das "DCF"-Richtlienen halten, also kann man da ruhig drauf testen. Jetzt stellt sich mir nur die Frage, wie ich aus meinem Programm raus erkennen kann, was für ein Medium das ist. Ich möchte ja nicht auf jedes USB-Zip-Drive oder jedes externe CD-Drive zugreifen, sobald der Nutzer da ein Medium einlegt. (Zumindestens meine Cam hat den Media-Type "DBTF_NET", ich weiss aber nicht, ob sich nicht z.b. ein USB-MemoryStick als "DBTF_MEDIA" outet, deswegen ist das auch kein guter Ansatz.) Also gut, dann bleibe ich bei WM_DEVICECHANGE und versuche das damit weiter. Kann mir denn jemand sagen, wie ich rausbekomme, mit was für einem Gerät ich es dann zu tun habe? (GetVolumeInformation gibt ausser einer 5-stelligen Seriennummer nix zurück.) Windows zeigt ja das Gerät auch als "USB-CASIO DIGITAL CAMERA" an... also muss die Info irgendwo verfügbar sein. Jemand ne Idee? Bin für jeden Lösungsansatz dankbar! Gruß Wormid |
Re: Event wenn Digitalkamera angeschlossen wird...
Ich hoffe du hast die DBT.pas
Wenn nicht kann ich sie dir senden. Nun kannst du dich informieren lassen wann ein Device neu ins System kommt, danach musst du nur sehen welche USB Devices ( Vendor ID und Prod ID ) ankekommen ist ... Registry lesen. ... Du bekommst auch mit wan eine CD ausgeworfen wird. Ich muss mal sehen ob ich noch was zu USB finde. Ich habe mir die Componente mal geschrieben gehabt ( TRuDBT ) um auf das entfernen eines USB-Seriell Adapters zu regieren. Danach mache ich den Port dicht der gezogen wird! Und ich kann auch sehen wann ein neuer Port angesteckt wurde.
Delphi-Quellcode:
uses DBT ! TDeviceType = ( dtOEM, dtDEVNODE, dtVOLUME, dtPORT, dtNET, dtDEVICEINTERFACE, dtHANDLE); TPortEvent = procedure( Sender: TObject; Port: String ) of object; TDeviceChangeEvent = procedure ( Sender: TObject; FirstDriveLetter : Char) of object; T??? = class(TComponent) private FWindowHandle : HWND; FOnPortRemovePending : TPortEvent; FOnPortRemoved : TPortEvent; FOnPortArrival : TPortEvent; procedure WndProc(var Msg: TMessage); protected procedure WMDeviceChange(var Msg : TWMDeviceChange); dynamic; published property AfterArrival : TDeviceChangeEvent read FAfterArrival write FAfterArrival; property AfterRemove : TDeviceChangeEvent read FAfterRemove write FAfterRemove; property OnPortRemovePending : TPortEvent read FOnPortRemovePending write FOnPortRemovePending; property OnPortRemoved : TPortEvent read FOnPortRemoved write FOnPortRemoved; property OnPortArrival : TPortEvent read FOnPortArrival write FOnPortArrival; end; procedure Register; implementation function CDDevTypeToStr( Value: Longint ): String; begin case Value of DBT_DEVTYP_OEM : Result := 'oem-defined device type'; DBT_DEVTYP_DEVNODE : Result := 'devnode number'; DBT_DEVTYP_VOLUME : Result := 'logical volume'; DBT_DEVTYP_PORT : Result := 'port serial or parallel'; DBT_DEVTYP_NET : Result := 'network resource'; DBT_DEVTYP_DEVICEINTERFACE : Result := 'device interface class'; DBT_DEVTYP_HANDLE : Result := 'file system handle'; end; end; constructor T???.Create(AOwner : TComponent); begin inherited Create(AOwner); FWindowHandle := AllocateHWnd(WndProc); end; destructor T???.Destroy; begin DeallocateHWnd(FWindowHandle); inherited Destroy; end; function T???.GetFirstDriveLetter(UnitMask : LongInt) : Char; var DriveLetter : ShortInt; begin DriveLetter := Ord('A'); while (UnitMask and 1) = 0 do begin UnitMask := UnitMask shr 1; inc(DriveLetter); end; Result := Char(DriveLetter); end; procedure T???.WndProc(var Msg: TMessage); begin if (Msg.Msg = WM_DEVICECHANGE) then begin try WMDeviceChange(TWMDeviceChange(Msg)); except Application.HandleException(Self); end; end else Msg.Result := DefWindowProc( FWindowHandle, Msg.Msg, Msg.wParam, Msg.lParam); end; procedure T???.WMDeviceChange(var Msg : TWMDeviceChange); var lpdb : PDevBroadcastHdr; lpdbv : PDevBroadcastVolume; lpdbp : PDevBroadCastPort; Port : PChar; begin lpdb := PDevBroadcastHdr(Msg.dwData); case Msg.Event of DBT_DEVICEARRIVAL : begin if lpdb^.dbch_devicetype = DBT_DEVTYP_VOLUME then begin lpdbv := PDevBroadcastVolume(Msg.dwData); if (lpdbv^.dbcv_flags and DBTF_MEDIA) = 1 then if Assigned(FAfterArrival) then FAfterArrival(Self, GetFirstDriveLetter(lpdbv^.dbcv_unitmask)); exit; end; if lpdb^.dbch_devicetype = DBT_DEVTYP_PORT then begin lpdbp := PDevBroadCastPort(Msg.dwData); if Assigned( FOnPortArrival ) and ( lpdbp^.dbcp_devicetype = DBT_DEVTYP_PORT ) then FOnPortArrival( Self, PChar( @lpdbp^.dbcp_name )); end; end; DBT_DEVICEQUERYREMOVE: begin end; DBT_DEVICEQUERYREMOVEFAILED: begin end; DBT_DEVICEREMOVEPENDING: begin if lpdb^.dbch_devicetype = DBT_DEVTYP_PORT then begin lpdbp := PDevBroadCastPort(Msg.dwData); if Assigned( FOnPortRemovePending ) and ( lpdbp^.dbcp_devicetype = DBT_DEVTYP_PORT ) then FOnPortRemovePending( Self, PChar( @lpdbp^.dbcp_name )); end; end; DBT_DEVICEREMOVECOMPLETE : begin if lpdb^.dbch_devicetype = DBT_DEVTYP_VOLUME then begin lpdbv := PDevBroadcastVolume(Msg.dwData); if (lpdbv^.dbcv_flags and DBTF_MEDIA) = 1 then if Assigned(FAfterArrival) then FAfterRemove(Self, GetFirstDriveLetter(lpdbv^.dbcv_unitmask)); end; if lpdb^.dbch_devicetype = DBT_DEVTYP_PORT then begin lpdbp := PDevBroadCastPort(Msg.dwData); if Assigned( FOnPortRemoved ) and ( lpdbp^.dbcp_devicetype = DBT_DEVTYP_PORT ) then FOnPortRemoved( Self, PChar( @lpdbp^.dbcp_name )); end; end; DBT_DEVICETYPESPECIFIC: begin end; DBT_CUSTOMEVENT: begin end; end; end; procedure Register; begin RegisterComponents( xxx, [T???]); end; mfg Rumpi & Pascal wenn du noch Fragen hast ... einfach fragen |
Re: Event wenn Digitalkamera angeschlossen wird...
Ich habe jetzt auch mal ein bisle rumexperimentiert.
Getestet habe ich mit einem externen USB CF Reader in den ich mein MicroDrive eingesteckt habe. Wenn ich den Reader ab/anstöpsle dann kommt die wm_DeviceChange Message. Entferne bzw. Füge das MicroDrive/CF Speicherkarte in den CF Reader ein, dann kommt keine wm_DeviceChange. Da man aber bei solchen Readern eben NICHT den Reader selber vom USB entfernt/anstöpselt, sondern eben die karte im Reader, ist cm_DeviceChange unbrauchbar. Ich vermute das eine CASIO am USB der man die Karte entfernt/ einstöpselt genauso verhält. Gruß Hagen |
Re: Event wenn Digitalkamera angeschlossen wird...
@Rumpi:
Zitat:
Zitat:
Und thx für den Code, den kann ich dann vielleicht als Basis für meine Bastelei nehmen... Bisher läuft das alles noch irgendwie in TForm1 und Button1-Manier ab. *g* @negaH: Beim einstöpseln der Cam erhielt auch ich eine WM_DEVICECHANGE. Beim Trennen der Verbindung allerdings nicht. (Ich will aber nicht ausschliessen, das der Fehler in meiner "Routine" liegt...) Was mich wundert ist, das du keine Nachricht bekommst, wenn eine neue CF eingelegt wird... Man kann ja auch mitbekommen, wenn jemand ne CD einlegt über diese Nachricht, da wird das Laufwerk ja auch nicht physikalisch getrennt/verbunden. Wie das ist, wenn ich meine Karte rausnehme, das kann ich leider nicht testen... Dafür muss ich den Batteriefachdeckel öffnen... und dann ist die Cam aus, also vom Bus getrennt. Ich werde da morgen nochmal dran rumprobieren. Bin allerdings weiterhin für Tips dankbar! (Vor allem wüsste ich gerne, wie die Original-Software das macht... ist es möglich, das der USB-Treiber noch ne andere Nachricht in System brüllt? So ne WM_USER + X Geschichte?) |
Re: Event wenn Digitalkamera angeschlossen wird...
Zitat:
Zitat:
Zitat:
Wenn die Originalsoftware bei die CASIO als USB Device korrekt identifiziert, aber über einen externen CF Reader nicht, dann ist wm_DeviceChange die wahrscheinlichste Lösung dafür. Meine Version von "Photo Loader" arbeitet nur korrekt wenn ich die Kamera als USB Device anschließe ! Gruß Hagen |
Re: Event wenn Digitalkamera angeschlossen wird...
Zitat:
Im Grunde ist jetzt noch die einzigste Frage die offen ist, die, wie ich VendorID/String usw. von einem USB-Device auslese. Dabei muss die Lösung nichtmal USB-spezifisch sein. Die Cam erscheint ja als Wechseldatenträger im System... das muss man doch alles irgendwie auslesen können. Nur wie gesagt, Versuche mit GetVolumeInformation z.B. schlugen fehl. Gruß Wormid (Ich werde dann jetzt noch mal ein bissel im MSDN rumsuchen... :coder: ) |
Re: Event wenn Digitalkamera angeschlossen wird...
wm_DeviceChange gibt dir den Laufwerksbuchstaben der Kamera, einfach auf diesem Drive nach DCIM suchen.
Gruß Hagen |
Re: Event wenn Digitalkamera angeschlossen wird...
Zumindestens therotisch habe ich es jetzt glaube ich eine saubere Lösung... ausprobieren kann ich es erst morgen, weil ein bissel testrei ist das schon...
Da ich, wie Du ja richtig behauptest, den Laufwerksbuchstaben des neuen Gerätes habe, kann ich den ja auch für weitere Recherchen nutzen. Also, Ärmel hochgekrempeln und Regedit quälen... Beginnend von hier: HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices kann ich mir scheinbar alle benötigten Daten zusammensuchen, die ich brauche, um zu sehen, ob das ne (Casio)Cam ist, die da angeschlossen wurde... Aber ich erspar mir und euch jetzt die Details, sonst müsste ich Kilobyteweise reg-Files posten. Ich sag es mal so für heute: Gute Nacht! *g* Gruß Wormid |
Re: Event wenn Digitalkamera angeschlossen wird...
Über die Registry gehts anscheinend, trotzdem wäre es nett von dir den genauen Weg dahin aufzuzeigen :)
Gruß Hagen |
Re: Event wenn Digitalkamera angeschlossen wird...
Das werde ich machen... wenn ich ihn denn habe. *g*
Ich brauch selbst noch etwas, um den genauen Weg rauszufinden, befürchte ich. Aber ich bin dabei... Gruß Wormid |
Re: Event wenn Digitalkamera angeschlossen wird...
Hi,
ich glaube du kannst nach DeviceChange mit SetupDiGetClassDevsEx siehe: ![]() weiter machen die entsprechende API Übersetzung findest du bei Jedi. Wenn du Class GUID deiner Hardware kennst musst du mit SetupDigetClassDevsEx abfragen ob deine Hardware eingetroffen ist. Danach aber nicht vergessen mit SetupDiDestroyDeviceInfoList die Liste zu zerstören. mfg Rumpi & Pascal |
Re: Event wenn Digitalkamera angeschlossen wird...
Hi,
ich misch mich mal kurz ein. Du könntest doch auch mit der Function GetLogicalDrives die Logischen Laufwerke mittels eines Timers abfragen. Vergleichst du das Ergebnis mit dem Ergebnis der letzten Anfrage, dann erkennst du ob ein Laufwerk hinzu- oder weggekommen ist. Dann nur noch überprüfen ob es sich den dem Laufwerk um ein Wechseldatenträger handelt mit einem DCIM-Verzeichnis und du weißt, ob es sich um eine Kamera, oder eine Speicherkarte einer Kamera handelt. Und beim entfernen braucht du ja nur überprüfen, ob es sich bei dem entfernten Laufwerk um deins handelt (das hast du ja, vom einstecken). (hmm. kann man das verstehen, was ich da gerade zusammengekritzelt habe :mrgreen: :mrgreen: ) So würde ich das machen. Sofern dieses Timer-ereignis nicht den Programm ablauf stört. |
Re: Event wenn Digitalkamera angeschlossen wird...
Moinsen,
einmal zu dem Hinweis von Rumpi: Ich würde ungern mit Dingen wie SetupDigetClassDevsEx rumspielen, da das a) sehr kompliziert scheint, und b) auf XP und 2000 beschränkt ist. Es muss doch nen einfachen Weg geben, die VendorID (Casio: 07cf) und die ProdID (1001) von einem Device zu erfragen. Dann kann man den Rest bequem aus der Registry saugen. Zu der Idee von Captnemo: Es ist nicht notwendig, per Timer alles abzufragen. Es wird ja das Event WM_DEVICECHANGE gefeuert, wenn die Cam oder andere USB-Storage-Devices angeschlossen werden. Dann kann man bequem aus der Message auslesen, welcher Laufwerksbuchstabe neu hinzugekommen ist. Aber dann nur auf vorhandensein des Ordners "DCIM" zu testen, das war/ist mir zu stumpf, irgendwie. Aber wahrscheinlich wird es doch auf irgendwie sowas hinauslaufen, ob mir das gefällt oder nicht... :? Gruß Wormid |
Re: Event wenn Digitalkamera angeschlossen wird...
Die SetupDi-Funktionen sind auch unter Win 98 vorhanden und es lassen sich die USB-Geraete genau wie die HID-Geraete enumerieren.
Ich habe die HID Komponente geschrieben und haette auch eine USB Komponente vorraetig. Die Komponente kann man dann fragen ob ein bestimmtes USB-Geraet vorhanden ist, also VendorID und ProductID. Letztlich grabe ich die Infos auch aus der Registry, aber auf korrektem und sicherem Weg. Kontakte mich doch direkt robert_marquardt@gmx.de |
Re: Event wenn Digitalkamera angeschlossen wird...
Wird denn WM_DEVICECHANCED auch ausgelöst, wenn ein USB-Gerät wieder entfernt wird?
|
Re: Event wenn Digitalkamera angeschlossen wird...
Beim meinen ersten Versuchen habe ich die Message nicht registriert beim entfernen das Gerätes. Aber sicher bin ich mir da nicht.
Gruß Wormid |
Re: Event wenn Digitalkamera angeschlossen wird...
Zitat:
mfg Rumpi & Pascal |
Re: Event wenn Digitalkamera angeschlossen wird...
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo!
Auch ich stehe vor der Aufgabe, meine Olypmus Camera, die sich als USB Storage meldet, automatisch zuzuordnen. Nach sorgfältigen Lesen dieses Themas habe ich mich der hervoragenden HID-Componente von Robert Marquardt (Ein großes Danke an dieser Stelle) gewidmet. Ich habe die Klasse "TJvHidPnPInfo" aus der "JvHidControllerClass.pas" extrahiert, zu "TUSBstorInfo" umbenannt und die Funktion "procedure TJvHidDeviceController.FillInList(var List: TList)" zur "procedure FillUSBStoragesInList(var List: TList; CurrentlyActive: boolean);" umgebaut, damit sie die installierten bzw. aktiven USB Storages zurückgibt, also über die SetupDi-Funktionen. Das funktioniert bei mir sehr gut (bei meiner Olympus C-300). Fehlt aber immernoch die Zuordnung zu dem Laufwerksbuchstaben. (Über "HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices" geht es meiner Meinung nach nicht, da dieser Eintrag unter Win9x nicht besteht und das einen Rattenschwanz von Registry-Verfolgungen nach sich zieht.) Demo-Projekt mit allen benutzten Dateien ist als Attachment angehängt. Grüße Quinten |
Re: Event wenn Digitalkamera angeschlossen wird...
Kontakte mich mal direkt und ich schicke dir meine USB Komponente.
Das ist so ziemlich das was du da gerade umgebaut hast. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:55 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz