How to Disable ( Grey-out ) the Close Button?
http://www.autohotke...p?p=62506#62506
The Solution is as simple as this:
Removing the menu item "Close" from the (Window's) System menu
"greys out" the Close button!
Compare the snapshots below:-____
I present here two functions that will ease the task:
DisableCloseButton() will disable the Close button of the active window.DisableCloseButton(hWnd="") { If hWnd= hWnd:=WinExist("A") hSysMenu:=DllCall("GetSystemMenu","Int",hWnd,"Int",FALSE) nCnt:=DllCall("GetMenuItemCount","Int",hSysMenu) DllCall("RemoveMenu","Int",hSysMenu,"UInt",nCnt-1,"Uint","0x400") DllCall("RemoveMenu","Int",hSysMenu,"UInt",nCnt-2,"Uint","0x400") DllCall("DrawMenuBar","Int",hWnd) Return "" }[*:1z29pp84] Note: Disabling the Close button helps one to avoid accidental closure of a window.... Nothing more!. ALT+F4 will still close the window![/list]
RedrawSysmenu() will reset the System menu of the active window to default state.RedrawSysMenu(hWnd="") { If hWnd= hWnd:=WinExist("A") DllCall("GetSystemMenu","Int",hWnd,"Int",TRUE) DllCall("DrawMenuBar","Int",hWnd) Return "" }
Examples:
Disabling the Close button of an AHK GUI :Gui, +Resize Gui, Show, w400 h300, Demo Window DisableCloseButton() Return ; Copy & Paste DisableCloseButton() below
Disabling/Enabling the Close button of any Window:#F2::DisableCloseButton(WinExist("A")) #F3::RedrawSysmenu(WinExist("A")) Return ; Copy & Paste DisableCloseButton() and RedrawSysmenu() below
Disabling/Enabling the Close button of all instances of Internet Explorer Windows:^#F2:: WinGet,WindowID,List,ahk_class IEFrame Loop, % WindowID { cWindow = % WindowID%A_Index% DisableCloseButton(cWindow) } Return ^#F3:: WinGet,WindowID,List,ahk_class IEFrame Loop, % WindowID { cWindow = % WindowID%A_Index% RedrawSysMenu(cWindow) } Return ; Copy & Paste DisableCloseButton() and RedrawSysmenu() below
Credit:
Adapted from a VB example given in
Windows API reference / API-Guide 3.7[/list]
With a little alteration to DisableCloseButton() one can disable the other two buttons, I guess!...
Feedback please!....
[How To] Disable (Grey-out) the Close Button
#1
Posted 01 June 2006 - 03:05 PM
#2
Posted 19 May 2010 - 09:15 PM
I'd like to use this tip to stop myself from accidentally closing the Task Manager. I like to keep it running in the tray for the real-time CPU usage graph. This works:How to Disable ( Grey-out ) the Close Button?
...
Feedback please!
Run, taskmgr.exe,,,PID
WinWait, ahk_pid %PID%
DisableCloseButton(WinExist())
WinMinimize
DisableCloseButton(hWnd) {
hSysMenu:=DllCall("GetSystemMenu","Int",hWnd,"Int",FALSE)
nCnt:=DllCall("GetMenuItemCount","Int",hSysMenu)
DllCall("RemoveMenu","Int",hSysMenu,"UInt",nCnt-1,"Uint","0x400")
DllCall("RemoveMenu","Int",hSysMenu,"UInt",nCnt-2,"Uint","0x400")
DllCall("DrawMenuBar","Int",hWnd)
}...however, I'd like to not have to flash the window open just to get its handle. Any thoughts?
#3
Posted 19 May 2010 - 09:28 PM
I'd like to not have to flash the window open just to get its handle. Any thoughts?
winGet, tmHwnd, ID, Windows Task Manager msgbox % tmHwnd:?:
edit:
or
setformat, integerfast, H
msgbox % tmHwnd:=dllCall("FindWindow", str, "#32770", str, "Windows Task Manager")
#4
Posted 19 May 2010 - 11:04 PM
I had also forgotten to detect hidden windows. :oops:
DetectHiddenWindows, On
Run, taskmgr.exe,,Min,PID
WinWait, ahk_pid %PID%
DisableCloseButton(WinExist())
DisableCloseButton(hWnd) {
hSysMenu:=DllCall("GetSystemMenu","Int",hWnd,"Int",FALSE)
nCnt:=DllCall("GetMenuItemCount","Int",hSysMenu)
DllCall("RemoveMenu","Int",hSysMenu,"UInt",nCnt-1,"Uint","0x400")
DllCall("RemoveMenu","Int",hSysMenu,"UInt",nCnt-2,"Uint","0x400")
DllCall("DrawMenuBar","Int",hWnd)
}This code works about 50% of the time. The other half, the button is not disabled even though the handle is found.
#5
Posted 19 May 2010 - 11:53 PM
Task Manager. I like to keep it running in the tray for the real-time CPU usage graph.
Nice Idea! Here is my version
- without DetectHiddenWindows
- without compromising Ctrl+Alt+Del functionality
#NoTrayIcon
#SingleInstance, Force
If !TaskManID := DllCall("FindWindowA", Str,"#32770", Str,"Windows Task Manager" ) {
Run, taskmgr.exe,,Hide
While ! TaskManID := DllCall("FindWindowA", Str,"#32770", Str,"Windows Task Manager" )
Sleep 20
} Else {
TaskManID := DllCall("FindWindowA", Str,"#32770", Str,"Windows Task Manager" )
WinHide, ahk_id %TaskManID%
}
DisableCloseButton( TaskManID )
Return ; // End of auto-execute section /
[color=red]^!Del[/color]:: ; Ctrl+Alt+Del will toggle Hide/Show state for 'Windows Task Manager'
DllCall( "ShowWindow"
, UInt, TaskManID := DllCall("FindWindowA", Str,"#32770", Str,"Windows Task Manager" )
, UInt, !DllCall( "IsWindowVisible", UInt,TaskManID ) )
Return
[color=red]^!x[/color]::ExitApp, % DllCall( "ShowWindow", UInt,TaskManID, UInt,1 )
DisableCloseButton( hWnd ) {
hSysMenu := DllCall( "GetSystemMenu", UInt,hWnd, Int,0 )
nCnt := DllCall( "GetMenuItemCount", UInt,hSysMenu )
DllCall( "RemoveMenu", UInt,hSysMenu, UInt,nCnt-1, UInt,0x400 )
DllCall( "RemoveMenu", UInt,hSysMenu, UInt,nCnt-2, UInt, 0x400 )
DllCall( "DrawMenuBar", UInt,hWnd )
}
#6
Posted 19 May 2010 - 11:59 PM
Run, taskmgr.exe,,Hide,[color=red]PID[/color]
WinWait, ahk_pid %[color=red]PID[/color]%Did you mean TaskManID?
#7
Posted 20 May 2010 - 12:11 AM
Did you mean TaskManID?
No.. But I overlooked the fact that WinWait would require DetectHiddenWindows. Code altered..
Thanks.
#8
Posted 20 May 2010 - 12:13 AM
DllCall("FindWindow[color=red]A[/color]", Str,"#32770", Str,"Windows Task Manager" )Hi SKAN is there any difference between FindWindow and FindWindowA other than ANSI?Also
!DllCallDoes this inverse work for all function calls to dll?
BTW after running the updated version, my taskmanager does not come back if I close it from the tray :?
#9
Posted 20 May 2010 - 12:31 AM
Hi SKAN is there any difference between FindWindow and FindWindowA other than ANSI?DllCall("FindWindow[color=red]A[/color]", Str,"#32770", Str,"Windows Task Manager" )
There is no function named FindWindow() exported in user32.dll
AutoHotkey appends the 'A' for you - automatically. Sweet!
Does this inverse work for all function calls to dll?
Yes. You may use triple toggle like !!! Function() if you strictly require a BOOLEAN.
BTW after running the updated version, my taskmanager does not come back if I close it from the tray :?
#10
Posted 20 May 2010 - 12:37 AM
#NoTrayIcon
Run, taskmgr.exe,,Min
While ! TaskManID := DllCall("FindWindowA", Str,"#32770", Str,"Windows Task Manager")
Sleep 20
DisableCloseButton( TaskManID )
DisableCloseButton( hWnd ) {
hSysMenu := DllCall( "GetSystemMenu", UInt,hWnd, Int,0 )
nCnt := DllCall( "GetMenuItemCount", UInt,hSysMenu )
DllCall( "RemoveMenu", UInt,hSysMenu, UInt,nCnt-1, UInt,0x400 )
DllCall( "RemoveMenu", UInt,hSysMenu, UInt,nCnt-2, UInt, 0x400 )
DllCall( "DrawMenuBar", UInt,hWnd )
}Why does the loop work, when WinWait fails?
#11
Posted 20 May 2010 - 01:09 AM
Why does the loop work, when WinWait fails?
WinWait would require DetectHiddenWindows On, I guess.
#12
Posted 20 May 2010 - 01:14 AM
;#NoTrayIcon
DetectHiddenWindows, On
Run, taskmgr.exe,,Min,PID
WinWait, ahk_pid %PID%
h1 := WinExist()
h2 := DllCall("FindWindowA", Str,"#32770", Str,"Windows Task Manager")
If (h1 = h2)
DisableCloseButton(h1)
Else MsgBox,% h1 "`n" h2
DisableCloseButton(hWnd) {
hSysMenu:=DllCall("GetSystemMenu","Int",hWnd,"Int",FALSE)
nCnt:=DllCall("GetMenuItemCount","Int",hSysMenu)
DllCall("RemoveMenu","Int",hSysMenu,"UInt",nCnt-1,"Uint","0x400")
DllCall("RemoveMenu","Int",hSysMenu,"UInt",nCnt-2,"Uint","0x400")
DllCall("DrawMenuBar","Int",hWnd)
}But intermittently, WinExist() returns a handle and DllCall() returns 0. In these cases, it seems that WinWait has not waited long enough; but then how is WinExist() working :?:
#13
Posted 20 May 2010 - 01:35 AM
The message box should never show.
It never shows.. :roll:
Does the following produce different result?
DetectHiddenWindows, On
Run, taskmgr.exe,,Min,PID
WinWait, ahk_pid %PID%
h1 := WinExist( "Windows Task Manager ahk_class #32770" )
h2 := DllCall("FindWindowA", Str,"#32770", Str,"Windows Task Manager")
If (h1 = h2)
DisableCloseButton(h1)
Else MsgBox,% h1 "`n" h2
#14
Posted 20 May 2010 - 02:08 AM
#15
Posted 20 May 2010 - 03:28 AM
It works for any expression, not just function calls.Does this inverse work for all function calls to dll?
If you omit the 'A', the script will also work on the Unicode build of AutoHotkey_L, which appends 'W' instead of 'A'.AutoHotkey appends the 'A' for you - automatically. Sweet!
You may also use !!!!!!!!! Function(), but ! Function() will give the same result faster.You may use triple toggle like !!! Function() if you strictly require a BOOLEAN.






