 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
Peter
Joined: 30 Dec 2005 Posts: 264
|
Posted: Sat May 05, 2007 11:48 am Post subject: GuiControl doesn't work for Static Gui Variables |
|
|
In AHK v1.0.46.01+, Gui can use static variables, but GuiControl doesn't seem to work then. (Tested on AHK v1.0.46.07 and v1.0.46.14)
Maybe it's meant to be like that, but I can't find it mentioned in AHK Help.
| Code: | GuiControlVar()
Return
GuiControlVar()
{
Static UserGroup ; Only when this Gui variable is Global, GuiControl works OK
guiRA= 1
Gui, %guiRA%:add, DDL, vUserGroup w200, V%A_AhkVersion%||
GuiControl,%guiRA%:, UserGroup, |Administrators||Backup Operators|Power Users|Users
Gui, %guiRA%:show,
Return
GuiClose:
ExitApp
Return
} |
|
|
| Back to top |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10465
|
Posted: Sat May 05, 2007 4:04 pm Post subject: |
|
|
The problem also extends to ByRef variables. It will be fixed in the next release and the changelog will say: Fixed GuiControl, GuiControlGet, and "Gui ListView/TreeView" to support static variables and ByRef's that point to globals/statics.
Thanks for reporting it. |
|
| Back to top |
|
 |
Peter
Joined: 30 Dec 2005 Posts: 264
|
Posted: Wed Jul 04, 2007 6:24 pm Post subject: |
|
|
The previous bug is solved, but I'm not sure about the behaviour under a label in Function.
GuiControl under the label doesn't work.
Is this a known limitation or some bug as well? (Tested in AHK V1.0.47.00)
| Code: | GuiControlVar()
Return
GuiControlVar()
{
Static guiRA
Static UserGroup ; when making UserGroup global, GuiControl in TestLabel works OK
guiRA= 1
Gui, %guiRA%:add, DDL, vUserGroup w200, V%A_AhkVersion%||
Gui, %guiRA%:show,
GuiControl,%guiRA%:, UserGroup, |Administrators||Backup Operators|Power Users|Users
; Here works "GuiControl" OK, but in TestLabel Timer routine it doesn't.
SetTimer, TestLabel ,1000
Return
TestLabel:
SetTimer, TestLabel, off
GuiControl,%guiRA%:, UserGroup, |TestLabel||
Return
GuiClose:
ExitApp
Return
} |
|
|
| Back to top |
|
 |
PhiLho
Joined: 27 Dec 2005 Posts: 6721 Location: France (near Paris)
|
Posted: Thu Jul 05, 2007 12:22 pm Post subject: |
|
|
SetTimer doesn't work well in functions, because the function was exited when the timer goes off, so context (local variables) is lost.
I believe this has been discussed before, so I searched. I found at least two related topics, started by yourself!
Array%index% doesn't work in label inside a function
Crash with SysGet in label inside function _________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2") |
|
| Back to top |
|
 |
Peter
Joined: 30 Dec 2005 Posts: 264
|
Posted: Thu Jul 05, 2007 6:23 pm Post subject: |
|
|
| PhiLho wrote: | | I believe this has been discussed before, so I searched. I found at least two related topics, started by yourself! | That's right, I use labels in a function a lot, because I avoid global variables whenever possible.
However, ordinary Static variables are always accessible (e.g. guiRA in my code).
So I don't know it's a bug or a limitation for Static variables in Gui .
I can always use my old method again, but it's a bit tricky method, so I prefer Static variables for Gui.
(BTW, I don't see any problem using SetTimer in a function. I use it many times wihout any problem.) |
|
| Back to top |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10465
|
Posted: Fri Jul 06, 2007 1:51 am Post subject: |
|
|
This behavior is unexpected; but it turns out there's two reasons for it:
1) The current architecture has no means of supporting static variables for GUI controls unless the function was actually called (not entered via a subroutine like SetTimer).
2) Performance: Keeping this limitation speeds up GUI variables when they're looked up outside of a function.
Due to obscurity, I really don't want this in the documentation. I checked both spots where it could be mentioned, but it would really make a mess of the already-complicated wording. |
|
| Back to top |
|
 |
corrupt
Joined: 29 Dec 2004 Posts: 2384
|
Posted: Fri Jul 06, 2007 4:14 am Post subject: |
|
|
| Chris wrote: | | Due to obscurity, I really don't want this in the documentation. I checked both spots where it could be mentioned, but it would really make a mess of the already-complicated wording. | Grab yer broom... it's goin' under the carpet with the rest of the mess... |
|
| Back to top |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10465
|
Posted: Fri Jul 06, 2007 1:57 pm Post subject: |
|
|
| Supporting timers and other externally-called subroutines inside functions was never intended. At the time it was discovered, I was tempted to disable it but decided to keep it because some people said they were using it. Unfortunately, that feature is limited; certain types of extensions (like the one in this topic) can't be added to it without redesigning certain key data structures, which would increase memory load across-the-board (even in scripts that don't use the feature). |
|
| Back to top |
|
 |
corrupt
Joined: 29 Dec 2004 Posts: 2384
|
Posted: Fri Jul 06, 2007 3:36 pm Post subject: |
|
|
| Understood, but intentionally leaving gotcha information out of the documentation seems unprofessional IMHO... Maybe users here should start a new manual that contains an alphabetical list of gotchas and things that you don't want to add to the documentation? |
|
| Back to top |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10465
|
Posted: Fri Jul 06, 2007 3:53 pm Post subject: |
|
|
| By all means. My rule-of-thumb is that if 99.9% of readers would want their time back after reading something, including it would do more harm than good. |
|
| Back to top |
|
 |
engunneer
Joined: 30 Aug 2005 Posts: 6349 Location: Pacific Northwest, US
|
Posted: Fri Jul 06, 2007 4:45 pm Post subject: |
|
|
corrupt,
You should start a additional documentation page on the official wiki. Title it Gotchas if you want, but I think a better name would be, well, better. _________________
Unless otherwise noted, all code is untested.
Common Answers: 1.(Loops, Viruses, etc.) 2. Search 3.RTFM |
|
| Back to top |
|
 |
Peter
Joined: 30 Dec 2005 Posts: 264
|
Posted: Fri Jul 06, 2007 5:41 pm Post subject: |
|
|
| Chris wrote: | | Supporting timers and other externally-called subroutines inside functions was never intended. At the time it was discovered, I was tempted to disable it but decided to keep it because some people said they were using it. | Yes, thank you for keeping that, because I use it quite often .
But my example was maybe not accurate pointing to the problem. Because the limitation in using Static Gui variables has it's effect on control labels as well. (Actually that was my inital script problem) | Code: | GuiControlVar()
Return
GuiControlVar()
{
Static guiRA
Static btnTest,chkTest ; when making btnTest & chkTest global, GuiControl in TestLabel works OK
guiRA= 1
Gui, %guiRA%:add, button, vbtnTest gTestLabel w250, Change buttontext && enable checkbox
Gui, %guiRA%:add, checkbox, vchkTest disabled w250, Checkbox
Gui, %guiRA%:show,
Return
TestLabel:
GuiControl,%guiRA%:, btnTest, Text on button is changed! ; this doesn't work
GuiControl,%guiRA%:enable, chkTest ; this doesn't work
MsgBox,Remark: GuiControl is in the Function label "%A_thisLabel%", and does not support Static Gui Variables.
Return
GuiClose:
ExitApp
Return
}
| I'm not saying that you have to solve the probem, but I'm not sure the situation is that exceptional. Unless if 99.9% of the readers will never use Static Gui variables, which could be possible.
I agree with other users here, to make this information somewhere easy accessible. If there's e.g. a link to "exceptional limitations" in the manual, then it's up to the reader whether he/she wants to check it out. |
|
| Back to top |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10465
|
Posted: Fri Jul 06, 2007 6:09 pm Post subject: |
|
|
This situation isn't exceptional merely because of the rarity of using static variables for GUI controls. It's exceptional because the problem doesn't occur unless the GUI control labels (or timers) are also inside a function. So if you want to use static variables for GUI controls -- and those controls need timers or GUI event-driven subroutines -- you should put those subroutines outside of the function and have them call the function in a special mode (e.g. by passing a special value via parameter). This is because calling a function is the only way that the program is designed to allow access to static variables dynamically (which includes GUI variables because they are looked up dynamically).
I don't wish to mention this on the GUI page because it's already so long that most readers give up long before reaching the end. However, I've revised the wording on the Functions page to mention it: | Quote: | A function may contain externally-called subroutines such as timers, GUI g-labels, and menu items. This is generally done to encapsulate them in a separate file for use with #Include, which prevents them from interfering with the script's auto-execute section. However, the following limitations apply:
Such subroutines should use only static and global variables (not locals) if their function is ever called normally. This is because a subroutine thread that interrupts a function-call thread (or vice versa) would be able to change the values of local variables seen by the interrupted thread. Furthermore, any time a function returns to its caller, all of its local variables are made blank to free their memory.
Such subroutines should use only global variables (not static variables) as GUI control variables.
When a function is entered by a subroutine thread, any references to dynamic variables made by that thread are treated as globals (including commands that create arrays). |
Thanks for pointing out the extent of the problem. |
|
| Back to top |
|
 |
Peter
Joined: 30 Dec 2005 Posts: 264
|
Posted: Fri Jul 06, 2007 10:18 pm Post subject: |
|
|
| Chris wrote: | | So if you want to use static variables for GUI controls -- and those controls need timers or GUI event-driven subroutines -- you should put those subroutines outside of the function and have them call the function in a special mode (e.g. by passing a special value via parameter). | I took me some time before I understood what you meant. Actually it can be a useful workaround. In case somebody else can use clarification by an example, this is Chris workaround: | Code: | GuiControlVar()
Return
GuiControlVar(Label="")
{
Static guiRA,btnTest,chkTest
If (Label= "TestLabel1") {
GuiControl,%guiRA%:, btnTest, Text on button is changed!
GuiControl,%guiRA%:enable, chkTest
Return
}
guiRA= 1
Gui, %guiRA%:add, button, vbtnTest gTestLabel1 w250, Change buttontext && enable checkbox
Gui, %guiRA%:add, checkbox, vchkTest disabled w250, Checkbox
Gui, %guiRA%:show,
Return
GuiClose:
ExitApp
Return
}
TestLabel1: ; Remark: All these labels can be inside the function as well, that works fine too
TestLabel2: ; just add the control-labels you need, and add another If-routine in the script.
TestLabeln:
GuiControlVar(A_thisLabel)
Return |
|
|
| Back to top |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10465
|
Posted: Sat Jul 07, 2007 1:47 am Post subject: |
|
|
| Thanks for the example and the comments it contains. |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|