Cannot get StringGadget ReadOnly to work after opened window

Just starting out? Need help? Post your questions and find answers here.
ctg
User
User
Posts: 21
Joined: Mon Sep 15, 2008 1:43 am

Cannot get StringGadget ReadOnly to work after opened window

Post 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 :P

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 !
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post 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.
BERESHEIT
ctg
User
User
Posts: 21
Joined: Mon Sep 15, 2008 1:43 am

Post 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:

Image

Any guess as to what I've got wrong? [I guess that's its point - discovering flaws in code?]
Last edited by ctg on Mon Sep 15, 2008 2:32 am, edited 2 times in total.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

It fixed it here..
BERESHEIT
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

The Polink error will be because you're using a userlibrary not compiled for this version of PureBasic.
BERESHEIT
ctg
User
User
Posts: 21
Joined: Mon Sep 15, 2008 1:43 am

Post 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.
ctg
User
User
Posts: 21
Joined: Mon Sep 15, 2008 1:43 am

Post 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 :D

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.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post 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
BERESHEIT
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

I didn't see the code for the non-threaded version but the problem was most likely in the event loop.
BERESHEIT
ctg
User
User
Posts: 21
Joined: Mon Sep 15, 2008 1:43 am

Post by ctg »

netmaestro wrote: Here is the compiled exe for you to test and see if it works for you: http://www.greatlakescode.com/test.exe
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 :D :P

EDIT: Saw your reply after I posted. Sorry.
ctg
User
User
Posts: 21
Joined: Mon Sep 15, 2008 1:43 am

Post 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()
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post 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()
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post 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()
BERESHEIT
ctg
User
User
Posts: 21
Joined: Mon Sep 15, 2008 1:43 am

Post by ctg »

Thanks guys, much appreciated ! :D
Post Reply