![]() |
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 |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:40 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