Problem: Dateityp-Auswahl im OpenFileRequester

Anfängerfragen zum Programmieren mit PureBasic.
hschmidt
Beiträge: 11
Registriert: 09.11.2006 16:15

Problem: Dateityp-Auswahl im OpenFileRequester

Beitrag 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)
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag 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.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
#NULL
Beiträge: 2237
Registriert: 20.04.2006 09:50

Beitrag 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.
my pb stuff..
Bild..jedenfalls war das mal so.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag 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.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
hschmidt
Beiträge: 11
Registriert: 09.11.2006 16:15

Beitrag 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
Benutzeravatar
#NULL
Beiträge: 2237
Registriert: 20.04.2006 09:50

Beitrag von #NULL »

dann solltest du statt

Code: Alles auswählen

WindowEvent() 
Delay(10)
dennoch lieber

Code: Alles auswählen

WaitWindowEvent(10) 
benutzen.
my pb stuff..
Bild..jedenfalls war das mal so.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag 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:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
hschmidt
Beiträge: 11
Registriert: 09.11.2006 16:15

Beitrag 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.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

>> Welchen Timeout-Wert würdest Du erfahrungsgemäß einsetzen?
Zwischen 100 + 200 ms sollte in den allermeisten Fällen genügen.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Antworten