DllCall: Calling GetSystemMenu() on an external program will corrupt its System Menu when the Script exits

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Guest

DllCall: Calling GetSystemMenu() on an external program will corrupt its System Menu when the Script exits

02 Jul 2017, 18:19

If you run this line...

Code: Select all

hMenu:=DllCall("GetSystemMenu", "UInt", hwnd, "UInt", 0)
...then whatever window is referred to by hwnd will end up with a "corrupt" System Menu after the AutoHotkey Script exits. In case anyone doesn't know: the "System Menu" is a menu on most windows that shows when you press Alt+Space...it's the menu that opens when you left or right click the top left icon of normal windows (some windows are custom drawn & aren't "normal").

I've seen (& can 100% reproduce) 2 types of a "corrupt" System Menu...
  • The menu can simply lose its normal icons & get some other slightly different (bigger) icons & just generally look weird: left side of menu basically doesn't have margins
  • The menu can freak out completely: same larger icons & no left margins, but also with a large blank space between the icons & the menu item text
I tested & confirmed the bug happens on...
  • OS
    • Windows 10 1703 15063.413 (Creators Update)
    AutoHotkey
    • Noticed on 1.1.25.02 & 1.1.05.01, also tested & confirmed on 1.1.26.00 & as far back as 1.0.44.04
...I don't know if this is some new Windows bug or some old unnoticed bug that has always happened, but AutoHotkey can trigger it as far back as 1.0.44.04 (maybe farther, I don't know when DllCall was implemented or I would test that version {I tried to test 1.0.28.01, but it said DllCall wasn't valid}).

Again, I don't know if this is a bug in AutoHotkey, something that can be fixed...or a bug in Windows, but maybe something AutoHotkey can workaround.

Code: Select all

#SingleInstance force
#NoEnv

msgbox, 64, Steps to Reproduce...,
(LTrim
	Steps to Reproduce...

	`     1. Run Notepad (or some victim window)

	`     2. Check its System Menu, remember what it looks like

	`     3. Press F9 when Notepad is the active window

	`     4. Click OK in this msgbox

	`     5. Check that window's System Menu again
)

ExitApp
return

;// Run this & press F8 to "reset" the system menu...
F8::DllCall("GetSystemMenu", "UInt", hwndActive:=WinExist("a"), "UInt", 1)

;// Run this & press F9 to corrupt the system menu...
F9::

hwndActive:=WinExist("a")

;//Tooltip, Calling GetSystemMenu()...
hMenu:=DllCall("GetSystemMenu", "UInt", hwndActive, "UInt", 0)
;//Sleep, 319
;//Tooltip

msgbox, F9 was pressed, continue with the next step!
return
Unrelated, but I wanted to say this: I completely disagree with the description of this Bug Reports forum, which is currently...
  • Report problems with documented functionality
...I understand you get incorrect Bug Reports & you're trying to limit that, but I'm sure the bug I just reported is not "documented functionality", I'm sure the help doesn't say "We won't corrupt the System Menu". You can't document bugs, since they are bugs.
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: DllCall: Calling GetSystemMenu() on an external program will corrupt its System Menu when the Script exits

03 Jul 2017, 01:14

Guest wrote:If you run this line...

Code: Select all

hMenu:=DllCall("GetSystemMenu", "UInt", hwnd, "UInt", 0)
...then whatever window is referred to by hwnd will end up with a "corrupt" System Menu after the AutoHotkey Script exits. In case anyone doesn't know: the "System Menu" is a menu on most windows that shows when you press Alt+Space...it's the menu that opens when you left or right click the top left icon of normal windows (some windows are custom drawn & aren't "normal").

I've seen (& can 100% reproduce) 2 types of a "corrupt" System Menu...
  • The menu can simply lose its normal icons & get some other slightly different (bigger) icons & just generally look weird: left side of menu basically doesn't have margins
  • The menu can freak out completely: same larger icons & no left margins, but also with a large blank space between the icons & the menu item text
I tested & confirmed the bug happens on...
  • OS
    • Windows 10 1703 15063.413 (Creators Update)
    AutoHotkey
    • Noticed on 1.1.25.02 & 1.1.05.01, also tested & confirmed on 1.1.26.00 & as far back as 1.0.44.04
...I don't know if this is some new Windows bug or some old unnoticed bug that has always happened, but AutoHotkey can trigger it as far back as 1.0.44.04 (maybe farther, I don't know when DllCall was implemented or I would test that version {I tried to test 1.0.28.01, but it said DllCall wasn't valid}).

Again, I don't know if this is a bug in AutoHotkey, something that can be fixed...or a bug in Windows, but maybe something AutoHotkey can workaround.

Code: Select all

#SingleInstance force
#NoEnv

msgbox, 64, Steps to Reproduce...,
(LTrim
	Steps to Reproduce...

	`     1. Run Notepad (or some victim window)

	`     2. Check its System Menu, remember what it looks like

	`     3. Press F9 when Notepad is the active window

	`     4. Click OK in this msgbox

	`     5. Check that window's System Menu again
)

ExitApp
return

;// Run this & press F8 to "reset" the system menu...
F8::DllCall("GetSystemMenu", "UInt", hwndActive:=WinExist("a"), "UInt", 1)

;// Run this & press F9 to corrupt the system menu...
F9::

hwndActive:=WinExist("a")

;//Tooltip, Calling GetSystemMenu()...
hMenu:=DllCall("GetSystemMenu", "UInt", hwndActive, "UInt", 0)
;//Sleep, 319
;//Tooltip

msgbox, F9 was pressed, continue with the next step!
return
AutoHotkey has absolutely nothing to do with how DllCalls work. This is a bug within the WinAPI. AutoHotkey can't fix that.
Unrelated, but I wanted to say this: I completely disagree with the description of this Bug Reports forum, which is currently...
  • Report problems with documented functionality
...I understand you get incorrect Bug Reports & you're trying to limit that, but I'm sure the bug I just reported is not "documented functionality", I'm sure the help doesn't say "We won't corrupt the System Menu". You can't document bugs, since they are bugs.
Yeah since this is not the behaviour of AutoHotkey but Windows behaviour. This is not a bug within AutoHotkey but one within Windows. AutoHotkey doesn't document it since how the dll function works that get's called by DllCall has nothing to do with AHK.
Recommends AHK Studio
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: DllCall: Calling GetSystemMenu() on an external program will corrupt its System Menu when the Script exits

03 Jul 2017, 09:27

Thanks for sharing this. I had the same problems you described on Windows 7, either getting a double-thickness menu, or a roughly normal-sized menu.

The issue seems to be with the bRevert parameter:
GetSystemMenu function (Windows)
https://msdn.microsoft.com/en-us/librar ... s.85).aspx

Here are some tests (tested on Notepad):

Code: Select all

q:: ;alt-space menu will look funny after reload
WinGet, hWnd, ID, A
hMenu := DllCall("GetSystemMenu", Ptr,hWnd, Int,0, Ptr)
Reload
return

w:: ;alt-space menu will look normal after reload
WinGet, hWnd, ID, A
hMenu := DllCall("GetSystemMenu", Ptr,hWnd, Int,0, Ptr)
hMenu := DllCall("GetSystemMenu", Ptr,hWnd, Int,1, Ptr)
Reload
return

e:: ;alt-space menu will look funny immediately
WinGet, hWnd, ID, A
hMenu := DllCall("GetSystemMenu", Ptr,hWnd, Int,0, Ptr)
DllCall("DestroyMenu", Ptr,hMenu)
SendInput !{Space}
return
On a related point, I noticed that quite often, Adobe Reader XI's alt-space menu looks a bit unusual, even though I don't ever try to interact with it, and was roughly twice as wide as it should be.

So maybe you can use some of the information above to fix your script. I suppose you are retrieving the hMenu of the alt-space menu (sysmenu) in order to invoke one of its items, or retrieve some changing text from it, or to get an item checked/enabled state. Sometimes there are workarounds so that you don't even need to retrieve the hMenu. Cheers.

[EDIT:] Sometimes all you need is the menu item ID for use with WM_COMMAND, sometimes it's more complicated.
Get Info from Context Menu (x64/x32 compatible) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=31971
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Guest

Re: DllCall: Calling GetSystemMenu() on an external program will corrupt its System Menu when the Script exits

03 Jul 2017, 10:19

This is NOT an "Ask For Help" topic!!!...I posted this in Bug Reports, cuz this is CLEARLY a Bug, it doesn't matter if the bug is in Windows or AutoHotkey, it is a bug!

I am highly offended by nnnik (or someone) unilaterally MOVING my CLEAR Bug Report out of Bug Reports & into Ask For Help...he didn't leave my topic in Bug Reports for even 1 day!...he just chose, unilaterally, without any other discussions (for example, with LEXIKOS!!!), that "nope, this guy's an idiot, this isn't a bug" & moved it. I want this moved back to Bug Reports, AT LEAST until someone official can determine if this...
  • Is an AutoHotkey bug, for example: if AHK is free()'ing (or DestroyMenu()'ing) an hMenu that it shouldn't
  • Is a Windows bug that needs reported to Microsoft
  • Is not a bug, I'm an idiot & the System Menu SHOULD get corrupted like that (aka "by design")
...I, for one, don't think I'm an idiot, I think this is CLEARLY a bug (& should never have been moved out of the place for bug reports)...& there is nothing my script should have to do to avoid it. I'm not saying that AutoHotkey is at fault, but I DO THINK it might be POSSIBLE to see if MAYBE AutoHotkey can avoid this, even if it might be a bug in Windows.

I recommend making a subforum of Bug Reports for "Windows Bugs" or "Not AutoHotkey Bugs"...IF! (& ONLY IF) this is 100% confirmed (BY LEXIKOS) to NOT BE an AutoHotkey bug...this may still be an AutoHotkey bug, even if you don't think so, only Lexikos can confirm that...(I think it's possible that AutoHotkey is FREEING the hMenu on shutdown, so despite this using DllCall, it might STILL be an AHK bug!)...did you NOTICE that the corruption only happens on when the AutoHotkey script EXITS???

Bug Reports needs to be split in to 2 or 3 subforums...
  • Bug Reports
    • New Reports
    • Confirmed AutoHotkey Bugs
    • Confirmed Windows Bugs
..."New Reports" could either be a subforum of Bug Reports...or they could just be posted to the root Bug Reports forum. Posts in New Reports should NOT BE MOVED for at least 7 days, giving many people time to see them & reply.

I also think it's very odd, that nnnik, an Admin, quoted my entire post...isn't that just, bad?...I think everyone should always quote only what's necessary, only what they are replying to...& if replying to the whole post, quote none of it.
nnnik wrote:AutoHotkey has absolutely nothing to do with how DllCalls work. This is a bug within the WinAPI. AutoHotkey can't fix that.
...that's your opinion, how about we wait for Lexikos (the one writing the code) to determine that?
nnnik wrote:Yeah since this is not the behaviour of AutoHotkey but Windows behaviour.
...unless you wrote the code or asked Lexikos before taking action, I don't believe this. Did you not notice that this bug only happens AFTER AutoHotkey exits? AutoHotkey might be freeing memory at that time & MIGHT be DestroyMenu()'ing on the handle to the other process's menu, so, in fact, it COULD BE an AHK bug, not in DllCall, but in the AHK shutdown routine.
nnnik wrote:This is not a bug within AutoHotkey but one within Windows.
...you DON'T know that...you took one look at my post & moved it within 30 secs of seeing it.

jeeswg: thx for your reply, but despite this having been moved to AFH, this isn't a post that's actually Asking for Help. I encountered this behavior (bug) in a script I was writing, finding it highly odd, I created the minimal test case & came to report the bug...maybe a workaround in Script would be nice, but I'd prefer a fix in AutoHotkey (or Windows).
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: DllCall: Calling GetSystemMenu() on an external program will corrupt its System Menu when the Script exits

03 Jul 2017, 17:30

I see no change when bRevert=0, regardless of reloading. Tested on notepad, win7.
bRevert wrote: If this parameter is TRUE, GetSystemMenu resets the window menu back to the default state. The previous window menu, if any, is destroyed.
I see this however. :thumbup:
I'd be very surprised if AHK knew that the numbers in your variable hMenu was a menu handle, and tried to free/destroy it.

Good luck, I hope you get the help you need.
Guest

Re: DllCall: Calling GetSystemMenu() on an external program will corrupt its System Menu when the Script exits

03 Jul 2017, 18:19

Helgef wrote:I see no change when bRevert=0, regardless of reloading. Tested on notepad, win7.
...OK, maybe it's something new from Win8 or Win10?...can you record your testing method/results with OBS?
Helgef wrote:I'd be very surprised if AHK knew that the numbers in your variable hMenu was a menu handle, and tried to free/destroy it.
...there is the WinAPI function IsMenu() which could be used to determine if any variable/numbers were a valid menu handle. I thought AHK might be enuming vars/memory addresses, IsMenu()'ing them & then freeing them. Also, keeping the result in a variable (hMenu) is not required, I've also tested just the line DllCall("GetSystemMenu", "UInt", hwnd, "UInt", 0)...even never keeping a copy of the return value results in a corrupted sysmenu.

Update
  • I've tested this a little more & I can reproduce it even by changing Step 4 from "Click OK", to "Kill the Script's process" (from Task Manger/Process Explorer or Process, Close in another Script)...so, killing the Script's process (giving it no time to clean up anything), still results in this bug. I've used the Window 10 Feedback Hub to report this to Microsoft (with a link to this topic)...if you can reproduce it, please reply here & use the Feedback Hub to tell Microsoft. I'd specifically like to know if this can be reproduced on Win8 & all the releases of Win 10 (original, AU, CU)...I'd like more results for Win7 too, just for extra confirmation of it not being present there.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: DllCall: Calling GetSystemMenu() on an external program will corrupt its System Menu when the Script exits

04 Jul 2017, 03:19

Guest wrote:...OK, maybe it's something new from Win8 or Win10?...can you record your testing method/results with OBS?
I do not know what that is, so no, I cannot. ;). I tested both your and jeeswg's test scripts.
...there is the WinAPI function IsMenu() which could be used to determine if any variable/numbers were a valid menu handle.
That is good information, thanks :thumbup:

Cheers.
lexikos
Posts: 9583
Joined: 30 Sep 2013, 04:07
Contact:

Re: DllCall: Calling GetSystemMenu() on an external program will corrupt its System Menu when the Script exits

04 Jul 2017, 03:26

Windows bug reports are outside the purview of our Bug Reports forum.

I would say it is by design: Every window with the WS_SYSMENU style has a system menu, but it’s not there until it needs to be – The Old New Thing

If GetSystemMenu() has never been called for that window, it doesn't have a system menu. When you call it for the first time, GetSystemMenu() creates the menu. It may assign ownership to the calling process, which in your case is AutoHotkey. Or it may not. The documentation doesn't say, which is probably because it was never intended to be used by a process on windows that it does not own.

This explains why the script affects Notepad, which has the standard system menu items, but has no effect on PuTTY, which has custom items in its system menu. PuTTY has already called GetSystemMenu() in order to customize it.

As far as I can tell, the "corruption" is merely that the "uxtheme" visual styling is not applied to the menu. This affects colours, borders and spacing/margins.
I thought AHK might be enuming vars/memory addresses, IsMenu()'ing them & then freeing them.
That would be very inefficient. It would be unnecessary, since menus created by the script are automatically destroyed by the OS when the process exits. It would make no sense, because any number could coincide with a valid menu handle owned by some other process. In theory, any given number (except 0 or -1, generally) could simultaneously represent a valid address in the script's process, an address in other processes, a menu handle, a window handle, a file handle, some other handle, and something that only has meaning to the script. Handle values are arbitrary and are not necessarily required to be unique between handle types or processes.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: DllCall: Calling GetSystemMenu() on an external program will corrupt its System Menu when the Script exits

04 Jul 2017, 03:36

This explains why the script affects Notepad, which has the standard system menu items, but has no effect on PuTTY, which has custom items in its system menu. PuTTY has already called GetSystemMenu() in order to customize it.
That could explain why I didn't see the effect, because I have a program which puts some stuff in the system menu of every (top-level) window I open.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: doodles333, Google [Bot] and 376 guests