Page 1 of 1
Cannot get StringGadget ReadOnly to work after opened window
Posted: Mon Sep 15, 2008 1:51 am
by ctg
G'day everyone
I have been a [few month] reader of the forums here and found quite a few snippets of code that have helped out in small programs I've written. I am a new 'user' to programming altogether, so please do not expect me to understand the latest lingo
Now, down to the problem...
I have a #PB_String_ReadOnly tag set on a String Gadget when a button is clicked, and it works without a problem, including removing the tag. The issue arises when I open a new window [and subsequently close it], and I am unable to either enable or disable the tag on the field. I have posted some quick code I assembled for the purpose of troubleshooting the cause.
Code: Select all
;{- Enumerations / DataSections
;{ Windows
Enumeration
#Window_0
#Window_1
EndEnumeration
;}
;{ Gadgets
Enumeration
#Button_0
#Button_1
#Button_2
#Button_3
#String_TestField
#String_TestField2
EndEnumeration
;}
Define.l Event, EventWindow, EventGadget, EventType, EventMenu
;}
Procedure test()
If OpenWindow(#Window_1, 550, 300, 200, 200, "Window_1", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar)
If CreateGadgetList(WindowID(#Window_1))
ButtonGadget(#Button_3, 35, 50, 110, 30, "Close")
EndIf
EndIf
SetActiveWindow(#Window_1)
Repeat
Event = WaitWindowEvent()
Select Event
; ///////////////////
Case #PB_Event_Gadget
EventGadget = EventGadget()
EventType = EventType()
If EventGadget = #Button_3
CloseWindow(#Window_1)
SetActiveWindow(#Window_0)
Break
EndIf
; ////////////////////////
Case #PB_Event_CloseWindow
EventWindow = EventWindow()
If EventWindow = #Window_1
CloseWindow(#Window_1)
Break
EndIf
EndSelect
ForEver
EndProcedure
Procedure OpenWindow_Window_0()
If OpenWindow(#Window_0, 450, 200, 400, 400, "Window_0", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar)
If CreateGadgetList(WindowID(#Window_0))
ButtonGadget(#Button_0, 35, 50, 110, 30, "Open other window")
ButtonGadget(#Button_1, 35, 110, 110, 30, "Unlock text field")
ButtonGadget(#Button_2, 35, 170, 110, 30, "Kill")
StringGadget(#String_TestField, 125, 250, 110, 25, "",#PB_String_ReadOnly)
StringGadget(#String_TestField2, 125, 280, 110, 25, "")
EndIf
EndIf
Repeat
Event = WaitWindowEvent()
Select Event
; ///////////////////
Case #PB_Event_Gadget
EventGadget = EventGadget()
EventType = EventType()
If EventGadget = #Button_0
CreateThread(@test(),0)
ElseIf EventGadget = #Button_1
SetActiveGadget(#String_TestField)
StringGadget(#String_TestField, 125, 250, 110, 25, "TEST")
ElseIf EventGadget = #Button_2
End
EndIf
; ////////////////////////
Case #PB_Event_CloseWindow
EventWindow = EventWindow()
If EventWindow = #Window_0
CloseWindow(#Window_0)
Break
EndIf
EndSelect
ForEver
EndProcedure
OpenWindow_Window_0()
If anyone has any pointers, I'd be very grateful and a happy camper. Cheers !
Posted: Mon Sep 15, 2008 2:15 am
by netmaestro
You're sending your thread proc a parameter but the procedure isn't taking one in. Change Procedure test() to Procedure test(void) and it should work fine. Also, because you state your problem as an unexpected behaviour and not a crash, I'm guessing you aren't compiling threadsafe. Compiling with threadsafe is recommended anytime your program is using threads.
Posted: Mon Sep 15, 2008 2:27 am
by ctg
netmaestro wrote:You're sending your thread proc a parameter but the procedure isn't taking one in.
Hmm, I thought this didn't matter, but I'm probably wrong. It's just that I've created many threads in this fashion without one issue. Creating a thread was actually part of my testing and isn't required. Even calling the procedure from inside the other procedure does the same function [and gives me the same problem]
Change Procedure test() to Procedure test(void) and it should work fine.
Tried, but to no avail. Thanks for the suggestion though.
Also, because you state your problem as an unexpected behaviour and not a crash, I'm guessing you aren't compiling threadsafe. Compiling with threadsafe is recommended anytime your program is using threads.
Ah yes, I've seen it in the compiler options. I enabled it a week or so ago but it threw an error of some description. I'll enable it on a threaded app in future. Thanks.
EDIT: I enabled threadsafe on a largish app I've written/assembled and it throws the error I mentioned earlier:
Any guess as to what I've got wrong? [I guess that's its point - discovering flaws in code?]
Posted: Mon Sep 15, 2008 2:31 am
by netmaestro
It fixed it here..
Posted: Mon Sep 15, 2008 2:32 am
by netmaestro
The Polink error will be because you're using a userlibrary not compiled for this version of PureBasic.
Posted: Mon Sep 15, 2008 2:32 am
by ctg
netmaestro wrote:The Polink error will be because you're using a userlibrary not compiled for this version of PureBasic.
Ah ok, Thanks.
Posted: Mon Sep 15, 2008 2:33 am
by ctg
netmaestro wrote:It fixed it here..
O.o. Just re-tried it [with threading] and it did too [tried it without threading and just as a call]. Thanks mate, much appreciated
EDIT: Is there a particular reason why it doesn't work when not threaded? That's how I tested it initially and why I mentioned I still couldn't get it to work.
Posted: Mon Sep 15, 2008 2:45 am
by netmaestro
Sure, no problem. It's your code with Procedure test(void) and compiled with the threadsafe option checked:
Code: Select all
;{- Enumerations / DataSections
;{ Windows
Enumeration
#Window_0
#Window_1
EndEnumeration
;}
;{ Gadgets
Enumeration
#Button_0
#Button_1
#Button_2
#Button_3
#String_TestField
#String_TestField2
EndEnumeration
;}
Define.l Event, EventWindow, EventGadget, EventType, EventMenu
;}
Procedure test(void)
If OpenWindow(#Window_1, 550, 300, 200, 200, "Window_1", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar)
If CreateGadgetList(WindowID(#Window_1))
ButtonGadget(#Button_3, 35, 50, 110, 30, "Close")
EndIf
EndIf
SetActiveWindow(#Window_1)
Repeat
Event = WaitWindowEvent()
Select Event
; ///////////////////
Case #PB_Event_Gadget
EventGadget = EventGadget()
EventType = EventType()
If EventGadget = #Button_3
CloseWindow(#Window_1)
SetActiveWindow(#Window_0)
Break
EndIf
; ////////////////////////
Case #PB_Event_CloseWindow
EventWindow = EventWindow()
If EventWindow = #Window_1
CloseWindow(#Window_1)
Break
EndIf
EndSelect
ForEver
EndProcedure
Procedure OpenWindow_Window_0()
If OpenWindow(#Window_0, 450, 200, 400, 400, "Window_0", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar)
If CreateGadgetList(WindowID(#Window_0))
ButtonGadget(#Button_0, 35, 50, 110, 30, "Open other window")
ButtonGadget(#Button_1, 35, 110, 110, 30, "Unlock text field")
ButtonGadget(#Button_2, 35, 170, 110, 30, "Kill")
StringGadget(#String_TestField, 125, 250, 110, 25, "",#PB_String_ReadOnly)
StringGadget(#String_TestField2, 125, 280, 110, 25, "")
EndIf
EndIf
Repeat
Event = WaitWindowEvent()
Select Event
; ///////////////////
Case #PB_Event_Gadget
EventGadget = EventGadget()
EventType = EventType()
If EventGadget = #Button_0
CreateThread(@test(),0)
ElseIf EventGadget = #Button_1
SetActiveGadget(#String_TestField)
StringGadget(#String_TestField, 125, 250, 110, 25, "TEST")
ElseIf EventGadget = #Button_2
End
EndIf
; ////////////////////////
Case #PB_Event_CloseWindow
EventWindow = EventWindow()
If EventWindow = #Window_0
CloseWindow(#Window_0)
Break
EndIf
EndSelect
ForEver
EndProcedure
OpenWindow_Window_0()
Here is the compiled exe for you to test and see if it works for you:
http://www.greatlakescode.com/test.exe
Posted: Mon Sep 15, 2008 2:47 am
by netmaestro
I didn't see the code for the non-threaded version but the problem was most likely in the event loop.
Posted: Mon Sep 15, 2008 2:51 am
by ctg
Thanks mate, works a treat. Unfortunately I got it to work after I posted the reply, so I got it to work with threading
I tried to remove threading, as I only added it to test my code to see if I could replicate the issue [which I could]. After calling the proc, without creating a thread, it does not work, even when using a void value as a proc parameter. Any pointers?
I certainly appreciate the help mate
EDIT: Saw your reply after I posted. Sorry.
Posted: Mon Sep 15, 2008 3:00 am
by ctg
Here is the code for the non-threaded version. [2 changed lines of code, everything else is the same]
Code: Select all
;{- Enumerations / DataSections
;{ Windows
Enumeration
#Window_0
#Window_1
EndEnumeration
;}
;{ Gadgets
Enumeration
#Button_0
#Button_1
#Button_2
#Button_3
#String_TestField
#String_TestField2
EndEnumeration
;}
Define.l Event, EventWindow, EventGadget, EventType, EventMenu
;}
Procedure test(void)
If OpenWindow(#Window_1, 550, 300, 200, 200, "Window_1", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar)
If CreateGadgetList(WindowID(#Window_1))
ButtonGadget(#Button_3, 35, 50, 110, 30, "Close")
EndIf
EndIf
SetActiveWindow(#Window_1)
Repeat
Event = WaitWindowEvent()
Select Event
; ///////////////////
Case #PB_Event_Gadget
EventGadget = EventGadget()
EventType = EventType()
If EventGadget = #Button_3
CloseWindow(#Window_1)
SetActiveWindow(#Window_0)
Break
EndIf
; ////////////////////////
Case #PB_Event_CloseWindow
EventWindow = EventWindow()
If EventWindow = #Window_1
CloseWindow(#Window_1)
Break
EndIf
EndSelect
ForEver
EndProcedure
Procedure OpenWindow_Window_0()
If OpenWindow(#Window_0, 450, 200, 400, 400, "Window_0", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar)
If CreateGadgetList(WindowID(#Window_0))
ButtonGadget(#Button_0, 35, 50, 110, 30, "Open other window")
ButtonGadget(#Button_1, 35, 110, 110, 30, "Unlock text field")
ButtonGadget(#Button_2, 35, 170, 110, 30, "Kill")
StringGadget(#String_TestField, 125, 250, 110, 25, "",#PB_String_ReadOnly)
StringGadget(#String_TestField2, 125, 280, 110, 25, "")
EndIf
EndIf
Repeat
Event = WaitWindowEvent()
Select Event
; ///////////////////
Case #PB_Event_Gadget
EventGadget = EventGadget()
EventType = EventType()
If EventGadget = #Button_0
test(0)
ElseIf EventGadget = #Button_1
SetActiveGadget(#String_TestField)
StringGadget(#String_TestField, 125, 250, 110, 25, "TEST")
ElseIf EventGadget = #Button_2
End
EndIf
; ////////////////////////
Case #PB_Event_CloseWindow
EventWindow = EventWindow()
If EventWindow = #Window_0
CloseWindow(#Window_0)
Break
EndIf
EndSelect
ForEver
EndProcedure
OpenWindow_Window_0()
Posted: Mon Sep 15, 2008 3:09 am
by Sparkie
Added UseGadgetList(WindowID(#Window_0))
Code: Select all
;{- Enumerations / DataSections
;{ Windows
Enumeration
#Window_0
#Window_1
EndEnumeration
;}
;{ Gadgets
Enumeration
#Button_0
#Button_1
#Button_2
#Button_3
#String_TestField
#String_TestField2
EndEnumeration
;}
Define.l Event, EventWindow, EventGadget, EventType, EventMenu
;}
Procedure test(void)
If OpenWindow(#Window_1, 550, 300, 200, 200, "Window_1", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar)
If CreateGadgetList(WindowID(#Window_1))
ButtonGadget(#Button_3, 35, 50, 110, 30, "Close")
EndIf
EndIf
SetActiveWindow(#Window_1)
Repeat
Event = WaitWindowEvent()
Select Event
; ///////////////////
Case #PB_Event_Gadget
EventGadget = EventGadget()
EventType = EventType()
If EventGadget = #Button_3
CloseWindow(#Window_1)
SetActiveWindow(#Window_0)
Break
EndIf
; ////////////////////////
Case #PB_Event_CloseWindow
EventWindow = EventWindow()
If EventWindow = #Window_1
CloseWindow(#Window_1)
Break
EndIf
EndSelect
ForEver
EndProcedure
Procedure OpenWindow_Window_0()
If OpenWindow(#Window_0, 450, 200, 400, 400, "Window_0", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar)
If CreateGadgetList(WindowID(#Window_0))
ButtonGadget(#Button_0, 35, 50, 110, 30, "Open other window")
ButtonGadget(#Button_1, 35, 110, 110, 30, "Unlock text field")
ButtonGadget(#Button_2, 35, 170, 110, 30, "Kill")
StringGadget(#String_TestField, 125, 250, 110, 25, "",#PB_String_ReadOnly)
StringGadget(#String_TestField2, 125, 280, 110, 25, "")
EndIf
EndIf
Repeat
event = WaitWindowEvent()
Select event
; ///////////////////
Case #PB_Event_Gadget
EventGadget = EventGadget()
EventType = EventType()
If EventGadget = #Button_0
test(0)
ElseIf EventGadget = #Button_1
If IsGadget(#String_TestField)
FreeGadget(#String_TestField)
EndIf
UseGadgetList(WindowID(#Window_0))
StringGadget(#String_TestField, 125, 250, 110, 25, "TEST")
SetActiveGadget(#String_TestField)
ElseIf EventGadget = #Button_2
End
EndIf
; ////////////////////////
Case #PB_Event_CloseWindow
EventWindow = EventWindow()
If EventWindow = #Window_0
CloseWindow(#Window_0)
Break
EndIf
EndSelect
ForEver
EndProcedure
OpenWindow_Window_0()
Posted: Mon Sep 15, 2008 3:15 am
by netmaestro
It's best to have just one event loop, here is more or less how I'd approach it:
Code: Select all
;{- Enumerations / DataSections
;{ Windows
Enumeration
#Window_0
#Window_1
EndEnumeration
;}
;{ Gadgets
Enumeration
#Button_0
#Button_1
#Button_2
#Button_3
#String_TestField
#String_TestField2
EndEnumeration
;}
Define.l Event, EventWindow, EventGadget, EventType, EventMenu
;}
Procedure OpenWindow_Window_0()
If OpenWindow(#Window_0, 450, 200, 400, 400, "Window_0", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar)
If CreateGadgetList(WindowID(#Window_0))
ButtonGadget(#Button_0, 35, 50, 110, 30, "Open other window")
ButtonGadget(#Button_1, 35, 110, 110, 30, "Unlock text field")
ButtonGadget(#Button_2, 35, 170, 110, 30, "Kill")
StringGadget(#String_TestField, 125, 250, 110, 25, "",#PB_String_ReadOnly)
StringGadget(#String_TestField2, 125, 280, 110, 25, "")
EndIf
EndIf
Repeat
Event = WaitWindowEvent()
EventWindow = EventWindow()
Select EventWindow
Case #Window_1
Select Event
Case #PB_Event_Gadget
EventGadget = EventGadget()
EventType = EventType()
If EventGadget = #Button_3
CloseWindow(#Window_1)
SetActiveWindow(#Window_0)
EndIf
Case #PB_Event_CloseWindow
CloseWindow(#Window_1)
EndSelect
Case #Window_0
Select Event
Case #PB_Event_Gadget
EventGadget = EventGadget()
EventType = EventType()
Select EventGadget
Case #Button_0
If OpenWindow(#Window_1, 550, 300, 200, 200, "Window_1", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar)
If CreateGadgetList(WindowID(#Window_1))
ButtonGadget(#Button_3, 35, 50, 110, 30, "Close")
EndIf
SetActiveWindow(#Window_1)
EndIf
Case #Button_1
UseGadgetList(WindowID(#Window_0))
SetActiveGadget(#String_TestField)
StringGadget(#String_TestField, 125, 250, 110, 25, "TEST")
Case #Button_2
End
EndSelect
Case #PB_Event_CloseWindow
CloseWindow(#Window_0)
Break
EndSelect
EndSelect
ForEver
EndProcedure
OpenWindow_Window_0()
Posted: Mon Sep 15, 2008 3:38 am
by ctg
Thanks guys, much appreciated !
