Seite 1 von 3

Ein zweites Fenster vom Thread schließen [X]

Verfasst: 16.09.2007 20:48
von RSBasic
Hallo,
ich habe rasch ein Beispiel gecodet und habe ein Problem.
Folgendes: Ich habe ein Main-Fenster, vom Main-Fenster erstelle ich noch ein Fenster (ein zweites Window), auf dem zweiten Window erstelle ich einen Thread.
Dieser Thread soll zum Beispiel Aufgaben erledigen und zum Schluss das zweite Fenster schließen.
Da ist das Problem: "...zum Schluss das zweite Fenster schließen."
Er kann ja nicht einfach das zweite Fenster schließen, wenn das zweite Fenster ja den Thread erstellt hat.
Hier das Beispiel-Code:

Code: Alles auswählen

Procedure Thread()
  Debug "Test 1"
  Delay(500)
  Debug "Test 2"
  Delay(500)
  Debug "Test 3"
  Delay(500)
  CloseWindow(1)
  Debug "Geschlossen?"
EndProcedure

Procedure Window1()
  If OpenWindow(1,0,0,100,100,"Window 0",#PB_Window_WindowCentered)
    If CreateGadgetList(WindowID(1))
      TextGadget(2,10,10,100,20,"Test 2",0)
    EndIf
    CreateThread(@Thread(), 154)
  EndIf
EndProcedure

If OpenWindow(0,0,0,200,200,"Window 0",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  If CreateGadgetList(WindowID(0))
    TextGadget(1,10,10,100,20,"Test 1",0)
  EndIf
  Window1()
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Habt ihr eine Lösung/Alternative?

Verfasst: 16.09.2007 21:39
von HeX0R
Sende das im Thread ans Fenster (evtl. solltest du dem Thread das tatsächliche Handle des Fensters lieber übergeben):

Code: Alles auswählen

SendMessage_(windowid(1), #wm_close, #null, #null)

Verfasst: 16.09.2007 21:46
von NicTheQuick
Zunächst einmal solltest du die Hilfe zu Threads nochmal genauer lesen. Du
musst nämlich dem Thread genau einen Parameter des Typs Long
geben, sonst kann es zu einem Stack-Fehler kommen.
Ansonsten kannst du ein Fenster nur dann in einem Thread schließen, wenn
das Fenster auch dort erstellt wurde.

Hier also die Alternative:

Code: Alles auswählen

Procedure Thread(*close.Long)
  *close\l = #False
  Debug "Test 1"
  Delay(500)
  Debug "Test 2"
  Delay(500)
  Debug "Test 3"
  Delay(500)
  *close\l = #True
  Debug "Geschlossen?"
EndProcedure

Global close.l

Procedure Window1()
  If OpenWindow(1,0,0,100,100,"Window 1",#PB_Window_WindowCentered)
    If CreateGadgetList(WindowID(1))
      TextGadget(2,10,10,100,20,"Test 2",0)
    EndIf
    CreateThread(@Thread(), @close)
  EndIf
EndProcedure

If OpenWindow(0,0,0,200,200,"Window 0",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  If CreateGadgetList(WindowID(0))
    TextGadget(1,10,10,100,20,"Test 1",0)
  EndIf
  Window1()
  Repeat
    If close And IsWindow(1)
      CloseWindow(1)
    EndIf
  Until WaitWindowEvent(10) = #PB_Event_CloseWindow
EndIf

Verfasst: 16.09.2007 21:50
von RSBasic
@HeX0R
Danke für deine Hilfe :D
Aber es gibt trotzdem ein Problem.
Da es nur eine Wiederholschleife für das Main-Fenster und das zweite Fenster gibt, wird daher nach dem #wm_close das komplette Programm geschlossen.
Die Alternative "SendMessage_(windowid(1), #wm_close, #null, #null)" ist nicht schlecht, aber kann man nicht so machen, dass nur das zweite Fenster sich schließt?

\\Edit:
@NicTheQuick
Danke für deine Hilfe, es funktioniert :) :D

Verfasst: 16.09.2007 21:51
von HeX0R
Siehe:

Code: Alles auswählen

Procedure Thread(hWnd)
	Debug "Test 1"
	Delay(500)
	Debug "Test 2"
	Delay(500)
	Debug "Test 3"
	Delay(500)
	SendMessage_(hWnd, #WM_CLOSE, #Null, #Null)
EndProcedure

Procedure Window1()
	If OpenWindow(1,0,0,100,100,"Window 0",#PB_Window_WindowCentered)
		If CreateGadgetList(WindowID(1))
			TextGadget(2,10,10,100,20,"Test 2",0)
		EndIf
		CreateThread(@Thread(), WindowID(1))
	EndIf
EndProcedure

If OpenWindow(0,0,0,200,200,"Window 0",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
	If CreateGadgetList(WindowID(0))
		TextGadget(1,10,10,100,20,"Test 1",0)
	EndIf
	Window1()
	Repeat
		Select WaitWindowEvent()
			Case #PB_Event_CloseWindow
				Select EventWindow()
					Case 0
						Break
					Case 1
						CloseWindow(1)
				EndSelect
		EndSelect
	ForEver
EndIf
A weng Eigenhirnschmalz wäre halt auch noch nützlich gewesen ;)

Verfasst: 16.09.2007 21:53
von RSBasic
@HeX0R
Ist auch ne Möglichkeit, aber ein Nachteil bei der Sache ist, dass das Fenster nur bei einer Mausbewegung sich schließt.

Verfasst: 16.09.2007 21:55
von NicTheQuick
Wie gesagt: Eigengehirnschmalz: WaitWindowEvent(10)

Verfasst: 16.09.2007 21:55
von HeX0R
Oder PostMessage anstatt SendMessage

Verfasst: 16.09.2007 21:56
von RSBasic
@NicTheQuick & @HeX0R
OK OK :mrgreen:

Verfasst: 17.09.2007 00:40
von Kaeru Gaman
@Nic
Lösung mit nem Flag, das byRef übergeben wird. sieht gut aus.


....gäbs nicht die möglichkeit, die Close-Message in die Queue zu packen,
dass sie vom WindowEvent() der Hauptschleife verarbeitet wird?

ist das der ansatz mit SendMessage/PostMessage?

..sorry, einfach mal dumm gefragt... ich kenn die Basis-theorie besser als die API selber...