 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
Lexikos
Joined: 17 Oct 2006 Posts: 7295 Location: Australia
|
Posted: Sun Jul 05, 2009 5:46 am Post subject: GuiControl + OnMessage = bad use of deref buffer? |
|
|
Laszlo recently pointed out a problem with a script which uses GuiControl and OnMessage with a picture control. After some debugging, I found that certain combinations of code can cause GuiControl to set the wrong picture or fail entirely (though in that case it failed only every second call).
| Code: | Gui, Add, Picture, H100 W100, shell32.dll ; Picture may be required.
Gui, Show
OnMessage(0x14, "WM_ERASEBKGND")
GuiControl,,Static1, % "" ; Seems it can be any expression or variable reference.
WM_ERASEBKGND(){
if (A_AhkPath) { ; Also: var := A_AhkPath
}
} |
Result on v1.0.48.03: AutoHotkey icon is shown
Result on v1.0.47.06: Empty Gui
Dev note: Making temporary copies of Line::GuiControl()'s parameters seems to solve the problem, though it would be unnecessary in many cases. |
|
| Back to top |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10716
|
Posted: Fri Sep 18, 2009 7:37 pm Post subject: |
|
|
In the particular example above, it seems that the following call triggers the OnMessage function, which changes the contents of GuiControl's parameters before it is done using them: | Code: | | SendMessage(control.hwnd, STM_SETIMAGE, IMAGE_CURSOR, NULL) |
This type of problem seems like it could be widespread. Perhaps any AutoHotkey command or built-in function that can directly or indirectly produce a call to GuiWindowProc() or MainWindowProc() theoretically could result in the launch of a callback or OnMessage function, which could corrupt the parameters that are still being used by the originating command.
In theory, just about any action done by the script could (directly or indirectly) trigger a callback or OnMessage function (e.g. keystrokes, mouse clicks, or mouse movements). But hopefully most of or all of those actions are indirect enough to cause messages to be posted rather than sent, which would not cause this issue because the program (as a general rule) does not process messages while in the middle of a command.
As you said, this issue could be solved by making copies of all the parameters, perhaps only if the script has any callbacks or is monitoring any messages.
Alternatively, perhaps the deref buffer can be privatized before GuiControl acts, then de-privatized afterward: | Code: | char *our_deref_buf = sDerefBuf;
size_t our_deref_buf_size = sDerefBufSize;
sDerefBuf = NULL;
sDerefBufSize = 0; |
This would force any newly-launched function to create a new buffer if it needs one. This approach is the same one used by ExpandArgs(), and it seems like it would perform very well in the 99.9% of cases when GuiControl does not trigger any callbacks or OnMessage functions.
Can you see any problems with this approach, or does it seem inferior to the perameter-copying idea?
The fix should probably be applied to both the GuiControl command and the Gui command (perhaps it is too rare that GuiControlGet would ever trigger a callback/OnMessage function). Perhaps Send/PostMessage also need some kind of adjustment because they access their parameters after sending the message.
Can you think of any other sections that would need fixing?
Thanks. |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7295 Location: Australia
|
Posted: Sat Sep 19, 2009 1:52 pm Post subject: |
|
|
| Chris wrote: | | Can you see any problems with this approach, | No.
| Quote: | | (perhaps it is too rare that GuiControlGet would ever trigger a callback/OnMessage function) | I think it is very likely to happen if a control is subclassed.
| Quote: | | Can you think of any other sections that would need fixing? | No. |
|
| Back to top |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10716
|
Posted: Sat Sep 19, 2009 2:10 pm Post subject: |
|
|
| Thanks. |
|
| 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
|