Event für SetGadgetText funktioniert nicht.

Für allgemeine Fragen zur Programmierung mit PureBasic.
funkheld
Beiträge: 651
Registriert: 31.12.2009 11:58

Event für SetGadgetText funktioniert nicht.

Beitrag von funkheld »

Hallo, ich habe ein Programm umgebaut um es mit einem Button zu starten.
Das Programm startet und die texte_e werden erst nach Beendigung reingeschrieben im Editfenster. Eigentlich sollte der Text "starte..." erscheinen, dann soll die Aufnahme erfolgen usw.

Wie kann man das so proggen?

Gruss

Code: Alles auswählen

Global text_e.s

Enumeration
  #Window_0
  #Button_0
  #Editor_0
  #Font_0
EndEnumeration

Procedure SaveWave(NrSeconds , Outputfile$)
   wf.WAVEFORMATEX
   wf\wFormatTag        = #WAVE_FORMAT_PCM
   wf\nChannels         = 2
   wf\nSamplesPerSec    = 44100
   wf\wBitsPerSample    = 16
   wf\nAvgBytesPerSec   = (wf\wBitsPerSample / 8) * wf\nChannels * wf\nSamplesPerSec
   wf\nBlockAlign       = (wf\wBitsPerSample / 8) * wf\nChannels
   
   If waveInOpen_(@hwi , #WAVE_MAPPER , wf , 0 , 0 , #WAVE_FORMAT_DIRECT) = #MMSYSERR_NOERROR
      wh.WAVEHDR
      wh\lpData         = AllocateMemory(wf\nAvgBytesPerSec * NrSeconds)
      wh\dwBufferLength   = MemorySize(wh\lpData)
      wh\dwFlags         = 0   
      If wh\lpData
         If waveInPrepareHeader_(hwi , wh , SizeOf(WAVEHDR)) = #MMSYSERR_NOERROR      
            If waveInAddBuffer_(hwi , wh , SizeOf(WAVEHDR)) = #MMSYSERR_NOERROR
               If waveInStart_(hwi) = #MMSYSERR_NOERROR               
                  waveInStop_(hwi)
                  waveInUnprepareHeader_(hwi,wh,SizeOf(WAVEHDR))               
                  If CreateFile(0,Outputfile$)
                     WriteData(0 , @"RIFF" , 4)
                     WriteLong(0 , 44 + wh\dwBytesRecorded)                  
                     WriteData(0 , @"WAVE" , 4)
                     WriteData(0 , @"fmt " , 4)
                     WriteLong(0 , 16)
                     WriteData(0 , wf , SizeOf(WAVEFORMATEX) - 2)
                     WriteData(0 , @"data" , 4)               
                     WriteLong(0 , wh\dwBytesRecorded)
                     WriteData(0 , wh\lpData , wh\dwBytesRecorded)
                     CloseFile(0)
                  EndIf
               EndIf         
            EndIf
         EndIf
         FreeMemory(wh\lpData)
      EndIf      
      waveInClose_(hwi)
   EndIf
 EndProcedure
 
OpenWindow(#Window_0, 400, 150, 300,300, "Window_0", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar)
SetCurrentDirectory("data/") 

ButtonGadget(#Button_0, 10,10, 80, 25, "Datei laden")

EditorGadget(#Editor_0, 10, 50, 200,200)
LoadFont(#Font_0, "Lucida Console", 9)
SetGadgetFont(#Editor_0, FontID(#Font_0)) 

Repeat
  
  Event = WaitWindowEvent(1)
  
  Select Event
    Case #PB_Event_Gadget
      EventGadget = EventGadget()
      EventType = EventType()
      
      If EventGadget = #Button_0  
        text_e+"starte..."
        SetGadgetText(#Editor_0, text_e)

        SaveWave(10 , "Test.wav")
        
        text_e+"fertig..."
        SetGadgetText(#Editor_0, text_e)
      EndIf
      
    Case #PB_Event_CloseWindow
      EventWindow = EventWindow()
      If EventWindow = #Window_0
        CloseWindow(#Window_0)
        Break
      EndIf
  EndSelect
  
ForEver


Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7039
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Event für SetGadgetText funktioniert nicht.

Beitrag von STARGÅTE »

Nachdem du SetGadgetText(#Editor_0, text_e)
schreibst, wird sofort SaveWave(10 , "Test.wav") gestartet.

Es fehlt also ein WindowEvent, um die Ereignisse (und Änderungen) zu verwalten.
Desweiteren wird das ganze Fenster einfrieren, wenn SaveWave() lange braucht.

Also entweder einen Thread benutzen, damit das Speichern parallel abläuft, oder ein WindowEvent() einbinden...
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
HeX0R
Beiträge: 3070
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win11 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2 + 3
Kontaktdaten:

Re: Event für SetGadgetText funktioniert nicht.

Beitrag von HeX0R »

Bei solchen Dingen kommst du eigentlich nicht um einen Thread herum.
So in etwa würde ich das machen:

Code: Alles auswählen

EnableExplicit

CompilerIf #PB_Compiler_Thread = 0
	CompilerError "Please enable threadsafe!"
CompilerEndIf

Enumeration
	#Window_0
	#Button_0
	#Editor_0
	#Font_0
EndEnumeration

Structure _THREAD_VARS_
	NrSeconds.i
	OutputFile.s
	ThreadID.i
EndStructure

Procedure SaveWaveThread(*T._THREAD_VARS_)
	Protected wf.WAVEFORMATEX, wh.WAVEHDR, hwi
	
	wf\wFormatTag      = #WAVE_FORMAT_PCM
	wf\nChannels       = 2
	wf\nSamplesPerSec  = 44100
	wf\wBitsPerSample  = 16
	wf\nAvgBytesPerSec = (wf\wBitsPerSample / 8) * wf\nChannels * wf\nSamplesPerSec
	wf\nBlockAlign     = (wf\wBitsPerSample / 8) * wf\nChannels

	If waveInOpen_(@hwi, #WAVE_MAPPER, wf, 0, 0, #WAVE_FORMAT_DIRECT) = #MMSYSERR_NOERROR
		wh\lpData           = AllocateMemory(wf\nAvgBytesPerSec * *T\NrSeconds)
		wh\dwBufferLength   = MemorySize(wh\lpData)
		wh\dwFlags          = 0
		If wh\lpData
			If waveInPrepareHeader_(hwi, wh, SizeOf(WAVEHDR)) = #MMSYSERR_NOERROR
				If waveInAddBuffer_(hwi, wh, SizeOf(WAVEHDR)) = #MMSYSERR_NOERROR
					If waveInStart_(hwi) = #MMSYSERR_NOERROR
						waveInStop_(hwi)
						waveInUnprepareHeader_(hwi, wh, SizeOf(WAVEHDR))
						If CreateFile(0, *T\Outputfile)
							WriteData(0, @"RIFF", 4)
							WriteLong(0, 44 + wh\dwBytesRecorded)
							WriteData(0, @"WAVE", 4)
							WriteData(0, @"fmt ", 4)
							WriteLong(0, 16)
							WriteData(0, wf, SizeOf(WAVEFORMATEX) - 2)
							WriteData(0, @"data", 4)
							WriteLong(0, wh\dwBytesRecorded)
							WriteData(0, wh\lpData, wh\dwBytesRecorded)
							CloseFile(0)
						EndIf
					EndIf
				EndIf
			EndIf
			FreeMemory(wh\lpData)
		EndIf
		waveInClose_(hwi)
	EndIf
EndProcedure

Procedure main()
	Protected Event, EventGadget, EventType, EventWindow, EventTimeout, text_e.s
	Protected T._THREAD_VARS_
	
	OpenWindow(#Window_0, 400, 150, 300, 300, "Window_0", #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MinimizeGadget | #PB_Window_TitleBar)
	SetCurrentDirectory("F:/")

	ButtonGadget(#Button_0, 10, 10, 80, 25, "Datei laden")

	EditorGadget(#Editor_0, 10, 50, 200, 200)
	LoadFont(#Font_0, "Lucida Console", 9)
	SetGadgetFont(#Editor_0, FontID(#Font_0))

	EventTimeout = #PB_Default
	Repeat

		Event = WaitWindowEvent(EventTimeout)

		Select Event
			Case #PB_Event_Gadget
				EventGadget = EventGadget()
				EventType   = EventType()
	
				If EventGadget = #Button_0
					text_e + "starte..."
					SetGadgetText(#Editor_0, text_e)
					DisableGadget(#Button_0, 1)
					T\NrSeconds  = 10
					T\OutputFile = "Test.wav"
					T\ThreadID   = CreateThread(@SaveWaveThread(), @T)
					EventTimeout = 50
				EndIf

			Case #PB_Event_CloseWindow
				EventWindow = EventWindow()
				If EventWindow = #Window_0
					If T\ThreadID = 0
						CloseWindow(#Window_0)
						Break
					Else
						Debug "thread not ready yet!"
					EndIf
				EndIf
				
			Case 0
				If T\ThreadID And IsThread(T\ThreadID) = 0
					T\ThreadID = 0
					DisableGadget(#Button_0, 0)
					text_e + "fertig..."
					SetGadgetText(#Editor_0, text_e)
					EventTimeout =  #PB_Default
				EndIf
		EndSelect

	ForEver
EndProcedure

main()
funkheld
Beiträge: 651
Registriert: 31.12.2009 11:58

Re: Event für SetGadgetText funktioniert nicht.

Beitrag von funkheld »

Jup, danke.

Funktioniert gut mit deiner Lösung.

gruss
Antworten