Seite 1 von 4

CD-Laufwerk wurde geöffnet?

Verfasst: 26.11.2006 23:07
von THEEX
Hmmm, gibt es irgendeine Möglichkeit, mit der man feststellen kann ob ein Laufwerk geöffnet/geschlossen wurde? Ich nehm mal an, über Winapi?

Verfasst: 28.11.2006 13:57
von Tsuki-Namida
okay ich kenne mich mit der api nicht so besonderst aus aber ich denke mal das, das nicht möglich ist nach zufragen ob ein laufwerk geöffnet ist oder nicht... das kann windows nämlich auch nicht... aber man kann nachfragen ob eine CD drinne liegt per API...

Verfasst: 28.11.2006 15:30
von Kaeru Gaman
>> ob ein Laufwerk geöffnet/geschlossen wurde?

> ob ein laufwerk geöffnet ist oder nicht...

es muss ja wohl ein ereignis beim schließen ausgelöst werden,
immerhin springt ja der autorun an, falls er aktiviert ist.
ähnliches könnte es auch fürs öffnen geben.
ob der momentanzustand abfragbar ist, k.p.

@Kain
> das kann windows nämlich auch nicht...
woher beziehst du die information?

Verfasst: 28.11.2006 16:49
von H.Brill
Vielleicht hilft hier die MCI - Schnittstelle.
Zumindest kann man meines Wissens damit
das CD Laufwerk öffnen, schließen und den Status
abfragen

set cdaudio | Alaisname door open
set cdaudio | Alaisname door closed
status cdaudio |Aliasname ready

wie das genau mit PB geht, weiß ich im Moment auch
nicht. So wie oben stehts jedenfalls mal in der MCI Dokumentation.

Verfasst: 28.11.2006 17:46
von Kukulkan
Hallo,

Ein subclassing mit

Code: Alles auswählen

Global OldProc.l
g_lOldProc.l = SetWindowLong_(MeinHWND, GWL_WNDPROC, @WndProc)
ein Subclassing erstellen.

Dann in der WndProc Procedure schauen ob die Message ein WM_DEVICECHANGE ist. Ungetestet in das Fenster getippt:

Code: Alles auswählen

Procedure.l WndProc(hWnd.l, Msg.l, wp.l, lp.l)
  If Msg.l = WM_DEVICECHANGE
    If wp.l = DBT_DEVICEARRIVAL
      ; CD geöffnet
    EndIf
    If wp.l = DBT_DEVICEREMOVECOMPLETE
      ; CD geschlossen
    EndIf
  EndIf
  ProcedureReturn CallWindowProc_(OldProc.l, hWnd.l, Msg.l, wp.l, lp.l)
EndProcedure
Kanns leider nicht genauer machen (echt gerade keine Zeit). Nicht vergessen beim Programmende das wieder zu beenden!

Code: Alles auswählen

SetWindowLong_(MeinHWND, GWL_WNDPROC, OldProc.l)
Wie gesagt, UNGETESTET!

Volker

Verfasst: 28.11.2006 19:21
von H.Brill
Hab grad mal was probiert.
Evtl. reicht dir das ja schon.

Code: Alles auswählen

Global ret$
ret$ = Space(255)
; 
If OpenWindow(0, 10, 10, 500, 320, "CD - ROM Test", #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
   If CreateGadgetList(WindowID(0))
       ButtonGadget(1, 5, 10, 80, 20, "Ende")
       ButtonGadget(2, 100, 10, 80, 20, "Open Door")
       ButtonGadget(3, 200, 10, 80, 20, "Close Door")
       ButtonGadget(4, 300, 10, 80, 20, "Status")
       ButtonGadget(5, 400, 10, 80, 20, "Modus")
       ListViewGadget(6, 10, 50, 380, 250)
   EndIf
   Repeat
    EventID.l = WaitWindowEvent()
    Select EventID
       Case #PB_Event_CloseWindow
          Quit = 1
       Case #PB_Event_Gadget
         Select EventGadget()    
            Case 1
               Quit = 1
            Case 2
              ; Open door 
              mciSendString_("set cdaudio door open", ret$, 0, 0)
            Case 3
                ; Close door
                mciSendString_("set cdaudio door closed", ret$, 0, 0) 
            Case 4
                 ; Status
                 ;mciSendString_("status cdaudio ready", ret$, 255, 0)
                 ; liefert true, wenn das CD Laufwerk bereit ist.
                 mciSendString_("status cdaudio media present", ret$, 255, 0)
                 Select ret$ 
                   Case  "true"
                     AddGadgetItem(6, -1, "Status : " + "CD - ROM im Laufwerk !")
                   Case "false"
                     AddGadgetItem(6, -1, "Status : " + "KEINE CD - ROM im Laufwerk !")  
                 EndSelect 
            Case 5
               ; Modus (zeigt aktuellen Status an)
               mciSendString_("status cdaudio mode", ret$, 255, 0)
               AddGadgetItem(6, -1, ret$)               
       EndSelect
    EndSelect
   Until Quit = 1
EndIf

End

Verfasst: 29.11.2006 11:08
von Kukulkan
Hier die komplette Lösung:

Code: Alles auswählen

; CD subclassing
; Volker Schmid
; PureBasic V4

#MainWin = 0
#Info = 1
#Text = 2

#WM_DEVICECHANGE = $0219
#DBT_DEVICEARRIVAL = $8000
#DBT_DEVICEREMOVECOMPLETE = $8004
#GWL_WNDPROC = -4

Global OldProc.l 

Procedure.l WndProc(hwnd.l, msg.l, wp.l, lp.l) 
  ; subclass routine
  If msg.l = #WM_DEVICECHANGE
    ; devicemessage
    If wp.l = #DBT_DEVICEARRIVAL
      ; CD closed
      SetGadgetText(#Text, "drive-state: closed")
    EndIf 
    If wp.l = #DBT_DEVICEREMOVECOMPLETE 
      ; CD opened
      SetGadgetText(#Text, "drive-state: open")
    EndIf 
  EndIf
  
  ; continue with the original routine
  ProcedureReturn CallWindowProc_(OldProc.l, hwnd.l, msg.l, wp.l, lp.l) 
EndProcedure

If OpenWindow(#MainWin, 100, 100, 195, 140, "CD subclassing test", #PB_Window_SystemMenu)
  
  CreateGadgetList(WindowID(#MainWin))
  TextGadget(#Info, 10,  10, 160, 80, "Shows the state of the CD tray. Remind, that closing may take a while until windows recognizes the medium.")
  TextGadget(#Text, 10,  100, 160, 20, "drive-state: actual undefined")
  
  ; start subclassing
  OldProc.l = SetWindowLong_(WindowID(#MainWin), #GWL_WNDPROC, @WndProc())
  
  Repeat
    EventID.l = WaitWindowEvent()
    If EventID.l = #PB_Event_CloseWindow  ; If the user has pressed on the close button
      Quit.l = 1
    EndIf
  Until Quit.l = 1
  
  ; stop subclassing
  SetWindowLong_(WindowID(#MainWin), #GWL_WNDPROC, OldProc.l)
  
  ; close window
  CloseWindow(#MainWin)
  End
Else
  ; cant create window
EndIf
Volker

Verfasst: 29.11.2006 18:51
von THEEX
@Volker

ich sag schonmal danke für deine Mühe, hab's auf die Schnelle getestet, es scheint genau das zu sein, was ich brauche. Wenn ich Zeit hab, schau ich es mir genauer an.

Verfasst: 29.11.2006 19:08
von edel
Der Code von Volker funktioniert aber nur dann wenn AutoPlay aktiviert ist.

CD-ROM einfahren...

Verfasst: 17.12.2006 11:46
von Xaby
Folgendes ... hab mir ein Icon auf dem Desktop zu meiner PB-EXE gelegt und möchte eigentlich, dass, wenn ich da rauf klicke mein Laufwerk zu geht und anschließend einen Explorer (besser noch den Arbeitsplatz) öffnet und wärend ich so auf der CD/DVD die Verzeichnisse durchstöbere, kopiert mein Programm alle Daten auf meine Festplatte von der Scheibe.

Code: Alles auswählen

AnzahlLW.l=InitAudioCD()
Debug AnzahlLW
If AnzahlLW>0

UseAudioCD(0)
EjectAudioCD(0)

Delay(3000)

RunProgram("C:\WINDOWS\explorer.exe", ProgramParameter(0),"")

Pfad.s=FormatDate("%yyyy%mm%dd-%hh%ii",Date())

R.l=0

While R<10
  Delay(2000)
  If CopyDirectory(ProgramParameter(0),ProgramParameter(1)+"\"+Pfad+"\", "", #PB_FileSystem_Recursive)=0
    R+1
  Else
  R=10
  EndIf
Wend

EndIf
Mein Problem liegt hier:
- wenn das Laufwerk geschlossen ist, klappt es anstands los.
Explorer öffnet sich und Scheibe wird auch in den angegebenen Pfad kopiert. ProgramParameter(0) kann man auch durch AudioCDName() ersetzen ...

aber wenn das Laufwerk erst durch mein Programm reingefahren wird, liefert der Explorer die Meldung: Bitte Disc in Lauferk einlegen und die CopyAlles-Routine macht och nüscht.

Egal ob ich 3 Sekunden dazwischen packe oder 30 Sekunden.

Mein Autostart ist aktiviert. Vielleicht gibt es da Kollisionen. Will ihn aber dafür nicht extra abstellen müssen.

Hat jemand vielleicht eine Idee, wie man in dem Menü:
- Ordner öffnen
- Abspielen mit
- Keine Aktion auswählen
[ ] diese Aktion immer wählen ...

eine eigene hinzufügen kann?

Besser wäre, wenn mein Programm ordentlich gehen würde.

Dank euch.

Frohes Fest, Gruß, Folker :allright:

-------------------------------------------------------------------------
zwei posts zusammengelegt.
du bist lang genug hier, Folker, um zu wissen, wie wir über unnötige doppelposts denken.
- Kaeru fecit
-------------------------------------------------------------------------
[Verzeihung]Tut mir leid, war nicht mit Absicht, hab die Grippe[/Verzeihung]

Wahrscheinlich müsste ich deine StatusAnzeige etwas abwandeln Volker.
Kann mir auch vorstellen, dann mein Programm permanent in den Tray zu machen und wenn eine CD eingelegt wird, wird sie kopiert. Und im Tray kann ich dann das ein und ausstellen, ob sie kopiert werden sollen und wohin ... und Programm beenden.

Oder gibt es so ein Tool schon?

Gruß Folker an Volker :mrgreen: