AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Window System Menu Manipulator Library v2.0

 
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
HuBa



Joined: 24 Feb 2007
Posts: 175
Location: Budapest, Hungary

PostPosted: Thu May 17, 2007 8:53 pm    Post subject: Window System Menu Manipulator Library v2.0 Reply with quote

Few months ago I was wondering how can I prevent a window from accidental closing.
And now I needed a solution to prevent from moving, resizing (unmovable, anchored window).

The suggested solution is simple: removing menu items from window's SystemMenu by deleting the last 2 menu item in menu list. (See also here)

This will surely solve the problem but it's not as elegant as it should be, because some window appends additional commands to the systemmenu. So removing by menu position is not the best idea.

Fortunately there is another way: removing by system command ID.
SystemCommand IDs don't depend on position so they allow more flexible operation.

After implementing the close/move/resize methods, I added other functions too (minimize/maximize/restore/separatorline).
You can use this library by inserting #include WinSysMenuAPI.ahk into your script.

The functions can be used on the script's own Gui window too:
Code:
Gui +LastFoundExist  ; Set the GUI window as the last found
GUIhWnd := WinExist()  ; Get last found window handle
DisableWindowMoving(GUIhWnd)  ; Prevent window from moving

You can always restore the original menu by calling RevertSystemMenu() function.

Code:
; WinSysMenuAPI.ahk - Window System Menu Manipulator Library
;
; Functions to remove or reenable window managing menu items and commands.
;
; Example:
;   DisableWindowClosing(WinExist(ahk_class TTOTAL_CMD))
;   This will prevent closing Total Commander by mouse, but you can still close it with Alt+F4.
;
; If you call a function without the hWnd parameter,
; it will be performed on the active window.
;
; The functions can be used on the script's own Gui window too:
;   Gui +LastFoundExist  ; Set the GUI window as the last found
;   GUIhWnd := WinExist()  ; Get last found window handle
;   DisableWindowMoving(GUIhWnd)  ; Prevent window from moving
;
; You can always restore the original menu by calling RevertSystemMenu() function.
;
; Tested with AutoHotkey 1.0.47.04
;
; Created by HuBa
; Contact: http://www.autohotkey.com/forum/profile.php?mode=viewprofile&u=4693
;
; Discussion forum: http://www.autohotkey.com/forum/topic19303.html
;
; For system command constants see: http://source.winehq.org/source/include/winuser.h

GetSystemMenu(ByRef hWnd, Revert = False)  ; Get system menu handle
{
  hWnd := hWnd ? hWnd : WinExist("A")  ; Active window handle
  Return DllCall("GetSystemMenu", "UInt", hWnd, "UInt", Revert)
}

DrawMenuBar(hWnd)  ; Internal function: this is needed to apply menu changes
{
  Return DllCall("DrawMenuBar", "UInt", hWnd)
}

RevertSystemMenu(hWnd = "")  ; Restores all removed menu items
{
  Return DrawMenuBar(GetSystemMenu(hWnd, True))  ; Revert system menu
}


RemoveMenu(hWnd, Position, Flags = 0)  ; MF_BYCOMMAND = 0x0000
{
  DllCall("RemoveMenu", "UInt", GetSystemMenu(hWnd), "UInt", Position, "UInt", Flags)
  Return DrawMenuBar(hWnd)
}

DeleteWindowResizing(hWnd = "") {
  Return RemoveMenu(hWnd, 0xF000)  ; SC_SIZE = 0xF000
}

DeleteWindowMoving(hWnd = "") {
  Return RemoveMenu(hWnd, 0xF010)  ; SC_MOVE = 0xF010
}

DeleteWindowMinimizing(hWnd = "") {
  Return RemoveMenu(hWnd, 0xF020)  ; SC_MINIMIZE = 0xF020
}

DeleteWindowMaximizing(hWnd = "") {
  Return RemoveMenu(hWnd, 0xF030)  ; SC_MAXIMIZE = 0xF030
}

DeleteWindowArranging(hWnd = "") {
  Return RemoveMenu(hWnd, 0xF110)  ; SC_ARRANGE = 0xF110
}

DeleteWindowRestoring(hWnd = "") {
  Return RemoveMenu(hWnd, 0xF120)  ; SC_RESTORE = 0xF120
}

DeleteWindowClosing(hWnd = "") {
  Return RemoveMenu(hWnd, 0xF060)  ; SC_CLOSE = 0xF060
}

DeleteWindowMenuSeparator(hWnd = "") {  ; Removes the line above Close menuitem
  Return RemoveMenu(hWnd, 0)
}


EnableMenuItem(hWnd, SystemCommand, EnableFlag)
{
  DllCall("EnableMenuItem", "UInt", GetSystemMenu(hWnd), "UInt", SystemCommand, "UInt", EnableFlag)  ; MF_BYCOMMAND = 0
  Return DrawMenuBar(hWnd)
}


DisableWindowResizing(hWnd = "") {
  Return DeleteWindowResizing()  ; Disabling has no effect, use delete instead
}

DisableWindowMoving(hWnd = "") {
  Return DeleteWindowMoving()
}

DisableWindowMinimizing(hWnd = "") {
  Return DeleteWindowMinimizing()
}

DisableWindowMaximizing(hWnd = "") {
  Return DeleteWindowMaximizing()
}

DisableWindowArranging(hWnd = "") {
  Return DeleteWindowArranging()
}

DisableWindowRestoring(hWnd = "") {
  Return DeleteWindowRestoring()
}

DisableWindowClosing(hWnd = "") {
  Return EnableMenuItem(hWnd, 0xF060, 1)  ; MF_GRAYED = 0x0001
}


EnableWindowResizing(hWnd = "") {
  Return EnableMenuItem(hWnd, 0xF000, 0)  ; MF_ENABLED = 0x0000
}

EnableWindowMoving(hWnd = "") {
  Return EnableMenuItem(hWnd, 0xF010, 0)
}

EnableWindowMinimizing(hWnd = "") {
  Return EnableMenuItem(hWnd, 0xF020, 0)
}

EnableWindowMaximizing(hWnd = "") {
  Return EnableMenuItem(hWnd, 0xF030, 0)
}

EnableWindowArranging(hWnd = "") {
  Return EnableMenuItem(hWnd, 0xF110, 0)
}

EnableWindowRestoring(hWnd = "") {
  Return EnableMenuItem(hWnd, 0xF120, 0)
}

EnableWindowClosing(hWnd = "") {
  Return EnableMenuItem(hWnd, 0xF060, 0)
}


Last edited by HuBa on Fri Dec 21, 2007 1:44 am; edited 3 times in total
Back to top
View user's profile Send private message Visit poster's website
majkinetor



Joined: 24 May 2006
Posts: 4511
Location: Belgrade

PostPosted: Fri May 18, 2007 7:29 am    Post subject: Reply with quote

Thx.

It would be more reliable to move globals in functions as statics or hardcode them (you can put message name in comment)
_________________
Back to top
View user's profile Send private message
HuBa



Joined: 24 Feb 2007
Posts: 175
Location: Budapest, Hungary

PostPosted: Fri May 18, 2007 9:47 am    Post subject: Reply with quote

You are right! I was also planning to do this.
I updated the original post.
Back to top
View user's profile Send private message Visit poster's website
majkinetor



Joined: 24 May 2006
Posts: 4511
Location: Belgrade

PostPosted: Fri May 18, 2007 9:57 am    Post subject: Reply with quote

Thx for wrapping this up.

Some coding suggestions:

Now you can write:
Code:
if hWnd =
  hWnd := WinExist("A")  ; Active window handle


as

Code:
hWnd .= hwnd ? : WinExist("A")


or

Code:
hWnd := hwnd ? hwnd : WinExist("A")


you can even put it in function call.
Makes things lil bit faster and shorter
_________________
Back to top
View user's profile Send private message
Joy2DWorld



Joined: 04 Dec 2006
Posts: 561
Location: Galil, Israel

PostPosted: Wed May 23, 2007 6:43 am    Post subject: Reply with quote

hmmm...

it's like the trolls who dug too far.. too deep...


Quote:
hWnd .= hwnd ? : WinExist("A")



is cute....

although,


perhaps,

imperfect:


Code:
msgbox % hWnd .= hwnd ? : 0
msgbox % hWnd .= hwnd ? : 0
exitapp

_________________
Joyce Jamce
Back to top
View user's profile Send private message
HuBa



Joined: 24 Feb 2007
Posts: 175
Location: Budapest, Hungary

PostPosted: Fri Dec 21, 2007 1:50 am    Post subject: Reply with quote

I updated the library.

majkinetor wrote:
Some coding suggestions:
Code:
hWnd := hwnd ? hwnd : WinExist("A")


you can even put it in function call.
Makes things lil bit faster and shorter

Done.

Now there are separated functions for every DllCall and uses Windows API naming convention.

3 groups: enable, disable, delete.

It seems that the window-appearance functions are immune to disable command so I implemented them as delete.

At least the close menu behaves as expected.
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group