Seite 1 von 1

Problem: Dateityp-Auswahl im OpenFileRequester

Verfasst: 09.11.2006 16:23
von hschmidt
Hallo Purebasic-Freunde,

ich bin neu hier und habe auch schon gleich ein erstes Problem auf Lager. Vielleicht kann mir jemand helfen.
Ich habe ein Problem bei der Dateitypen-Auswahl im Open(Save-)FileRequester. Die Dateitypen können nicht in jedem Fall fehlerfrei ausgewählt werden. Nach der Auswahl eine neuen Dateitypen bleibt das fenster einfach leer.
Merkwürdigerweise funktionert es einwandfrei, wenn ich keinen Sound abspiele (wo auch immer da der Zusammenhang ist).
Hier der Code:

Code: Alles auswählen

Procedure sound_click()
SoundFileName$ = "c:\windows\media\Windows XP-Ping.wav"
If SoundFileName$
  If LoadSound(77, SoundFileName$)
;
    PlaySound(77,0) ; <---- bitte mal Zeile remarken und nochmal testen
;    
  Else
    MessageRequester("Error", "Can't load the sound.", 0)
  EndIf
EndIf
  
EndProcedure

Procedure showwin()
    HideWindow(0,0)
EndProcedure

Procedure save_req()
  StandardFile$ = "C:\autoexec.bat"   
  Pattern$ = "Text (*.txt)|*.txt;*.bat|PureBasic (*.pb)|*.pb|Alle Dateien (*.*)|*.*"
  Pattern = 0    ; wir verwenden den ersten von drei möglichen Pattern als Standard
  File$ = OpenFileRequester("Bitte Datei zum Speichern auswählen", StandardFile$, Pattern$, Pattern)
  If File$
    MessageRequester("Information", "Sie haben folgende Datei ausgewählt:"+Chr(10)+File$, 0)
  Else
    MessageRequester("Information", "Der Requester wurde abgebrochen.", 0) 
  EndIf
  HideWindow(0, 1)
EndProcedure

;- Hier beginnt das Hauptprogramm

If InitSound() = 0
  MessageRequester("Error", "Can't init sound or no sound card is available",  0)
  End
EndIf

If OpenWindow(0,10,10,500,500,"", #PB_Window_Invisible | #PB_Window_ScreenCentered | #PB_Window_TitleBar)
  HideWindow(0, 1) 
  If CreateGadgetList(WindowID(0)) 
    ButtonGadget(995,81,0,20,20,"#")
    ButtonGadget(999,0,0,20,20,"X")
  EndIf

  WindowIsOpen.l = 0

  Repeat
  
  ev = WindowEvent()
  If ev=#PB_Event_CloseWindow
    quit=1
  EndIf
  
  If ev=#PB_Event_Gadget
    If EventGadget()=999
      HideWindow(0,1)
    EndIf
    If EventGadget()=995
      save_req()
    EndIf    
  EndIf
  
  If GetAsyncKeyState_(#VK_A)
      WindowIsOpen.l = 1
  EndIf

  If WindowIsOpen.l = 1
    showwin()
    sound_click()
    WindowIsOpen.l = 0
  EndIf

  Delay(10)
  Until quit=1 
  
EndIf
End
Teste bitte mal wie folgt:
- Programm starten, es passiert nichts (Fenster versteckt)
- Taste "a" drücken, Fenster wird geöffnen
- Butten "#" öffnet SaveFileRequester
- Nach Dateitypenauswahl bleibt der das Fenster leer, obwohl es Dateien mit der entsprechenden Endung anzeigen müsste

Und nun löscht mal die Zeile 6 (PlaySound(77,0)) und versucht nochmal. Bei mir funktioniert es dann.
Kann jemand einem Laien wie mir erklären, worin der Zusammenhang besteht?
Danke und Gruß,
Horst
(WinXP, Purebasic 4.0)

Verfasst: 09.11.2006 16:53
von ts-soft
Ohne vernünftige Eventverarbeitung kanns nicht gehen. Folgende Dinge haben Schuld:

Code: Alles auswählen

ev = WindowEvent() ; hier immer mit WaitWindowEvent() arbeiten

GetAsyncKeyState_(#VK_A) ; Keyboardshortcuts benutzen

Delay(10) ; macht jede vernünftige Eventbearbeitung unmöglich
Wenn Du das umgearbeitet hast, sollte alles gehen. Falls Du nicht weißt, wie
dies vereinzelt umzusetzen ist, nochmals Fragen.

Verfasst: 09.11.2006 17:17
von #NULL
@ts-soft
hast zwar recht, glaub aber nicht dass es was mit dem problem zu tun hat. zumal so ein requester doch auch funktioniert, ohne dass man jegliche event-behandlung im hauptprogramm benutzt.

bei mit funktioniert übrigens alles (zumindest wie es sollte).
[den sound brauchst du übrigens nur einmal vor der hauptschleife laden, und nicht vor jedem abspielen erneut. bleibt zwar trotzdem nur einmal im speicher weil PB so lieb ist, aber is trotzdem quatsch, oder man nimmt noch ein FreeSound() in die procedure mit rein]
..aber wie gesagt, die dateitypen-auswahl funktioniert bei mir. es gab aber glaube ich mit PB schon probleme bei requestern, welche nicht systematisch reproduzierbar waren.

Verfasst: 09.11.2006 17:23
von ts-soft
Das ist das Hauptproblem! Wie Du schon sagst, es läuft auf manchen
Rechnern, auf anderen nicht. Weil die meisten denken, so gehts doch bei mir,
wirds auch immer wieder so verwendet.

Zum Soundabspielen in einer Windowsanwendung lieber die API verwenden:

Code: Alles auswählen

PlaySound_(FileName.s, 0, #SND_ASYNC | #SND_FILENAME | #SND_NODEFAULT | #SND_NOWAIT)
So braucht auch die Soundlib nicht initialisiert werden und die Exe bleibt
kleiner.

Verfasst: 09.11.2006 17:55
von hschmidt
ts-soft hat geschrieben:Zum Soundabspielen in einer Windowsanwendung lieber die API verwenden:

Code: Alles auswählen

PlaySound_(FileName.s, 0, #SND_ASYNC | #SND_FILENAME | #SND_NODEFAULT | #SND_NOWAIT)
So braucht auch die Soundlib nicht initialisiert werden und die Exe bleibt
kleiner.
Ihr seid aber schnell mit Antworten, vielen Dank! Jedenfall Dein Tipp funktioniert, ich nutze nun die API.
Zu Deiner ersten Antwort: WaitWindowEvent kann ich leider nicht nutzen, da das Programm im Hintergrund die Tasten shift/alt/ctrl/num/print... abfragen soll, ohne auf ein Ereignis zu warten.
Das "a" im Code war nur beispielhaft gesetzt (ich hätte mich klarer ausdrücken sollen).

Jedenfalls vielen Dank an Alle! Problem erstmal gelöst, bei der Linux-Portierung frag ich dann nochmal :-)
Horst

Verfasst: 09.11.2006 17:58
von #NULL
dann solltest du statt

Code: Alles auswählen

WindowEvent() 
Delay(10)
dennoch lieber

Code: Alles auswählen

WaitWindowEvent(10) 
benutzen.

Verfasst: 09.11.2006 18:02
von ts-soft
>> WaitWindowEvent kann ich leider nicht nutzen
WaitWindowEvent unterstützt auch einen Timeout parameter! Ansonsten
einfach in einer Timerprocedure die anderen Tasten abfragen. Das mit dem
Timeout geht auch problemlos unter Linux ab PB4

Wenns nur für Windows wäre, ist aber die Timerprocedure vorzuziehen.

Dein WindowEvent() : Delay(10) konstrukt ist nur ein Kompromiß zwischen
hoher CPU-Last und schlechter Eventverarbeitung. Sollte IMHO niemals
verwendet werden :wink:

Verfasst: 09.11.2006 18:22
von hschmidt
ts-soft hat geschrieben:>> WaitWindowEvent kann ich leider nicht nutzen
WaitWindowEvent unterstützt auch einen Timeout parameter! Ansonsten
einfach in einer Timerprocedure die anderen Tasten abfragen. Das mit dem
Timeout geht auch problemlos unter Linux ab PB4
Besten Dank, werde ich gleich mal umschreiben. Welchen Timeout-Wert würdest Du erfahrungsgemäß einsetzen?
Wenns nur für Windows wäre, ist aber die Timerprocedure vorzuziehen.
Ich möchte den Code weitestgehend "API-frei" halten, portiert sich einfacher.

Verfasst: 09.11.2006 18:26
von ts-soft
>> Welchen Timeout-Wert würdest Du erfahrungsgemäß einsetzen?
Zwischen 100 + 200 ms sollte in den allermeisten Fällen genügen.