 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
Lexikos
Joined: 17 Oct 2006 Posts: 2494 Location: Australia, Qld
|
Posted: Sun Aug 12, 2007 6:13 am Post subject: Menu Icons v2 (stdlib) |
|
|
Menu Icons
Provides a set of functions for implementing icons in menus.
Version History
v2 (2007-10-19)- Now stdlib compatible (added MI_ prefix to functions.)
- Merged everything into MI.ahk, removing wrapper functions in the process.
v2.1 (2007-12-25)- Added MI_EnableOwnerDrawnMenus(), which can be used to enable owner-drawn menus for a given window (as an alternative to MI_ShowMenu().)
- MI_SetMenuStyle() now accepts a menu name or handle.
Known Issues
- Using MI_EnableOwnerDrawMenus on the script's main window:
- breaks the "Pause Script" menu item; and
- makes ListLines less useful, since interacting with the main window causes script to execute.
Usage example(s):
| Code: | ; Uncomment this if MI.ahk is not in your function library:
;#include %A_ScriptDir%\MI.ahk
#NoEnv
; Sample menu items.
Menu, M, Add, 16x16 Icon, ItemClick
Menu, M, Add, 32x32 Icon, ItemClick
Menu, M, Add, 48x48 Icon, ItemClick
; Set item 1's icon to shell32.dll, icon 4, 16x16.
MI_SetMenuItemIcon("M", 1, "shell32.dll", 4, 16)
; Set item 2's icon to shell32.dll, icon 4, 32x32.
MI_SetMenuItemIcon("M", 2, "shell32.dll", 4, 32)
; Windows 2000 or later required (supports sizes other than 16x16 and 32x32):
MI_SetMenuItemIcon("M", 3, "shell32.dll", 4, 48)
; Usually looks better:
MI_SetMenuStyle("M", 0x4000000)
; Note: This menu is shown automatically after setting up the tray menu.
;
; Icons in the Tray menu!
;
; Refer to a menu by handle for efficiency.
hTM := MI_GetMenuHandle("Tray")
if (A_OSVersion != "WIN_VISTA")
{ ; It is necessary to hook the tray icon for owner-drawing to work.
; (Owner-drawing is not used on Windows Vista.)
OnMessage(0x404, "AHK_NOTIFYICON")
OnMessage(0x111, "WM_COMMAND") ; To track "pause" status.
MI_SetMenuStyle(hTM, 0x4000000) ; MNS_CHECKORBMP (optional)
}
SplitPath, A_AhkPath,, SpyPath
SpyPath = %SpyPath%\AU3_Spy.exe
MI_SetMenuItemIcon(hTM, 1, A_AhkPath, 1, 16) ; open
MI_SetMenuItemIcon(hTM, 2, A_WinDir "\hh.exe", 1, 16) ; help
;-
MI_SetMenuItemIcon(hTM, 4, SpyPath, 1, 16) ; spy
; reload - icon needed!
MI_SetMenuItemIcon(hTM, 6, A_AhkPath, 2, 16) ; edit
;-
MI_SetMenuItemIcon(hTM, 8, A_AhkPath, 3, 16) ; suspend
MI_SetMenuItemIcon(hTM, 9, A_AhkPath, 4, 16) ; pause
MI_SetMenuItemBitmap(hTM, 10, 8) ; exit
MI_ShowMenu("M")
return
ItemClick:
return
AHK_NOTIFYICON(wParam, lParam)
{
global hTM, M_IsPaused
if (lParam = 0x205) ; WM_RBUTTONUP
{
; Update "Suspend Script" and "Pause Script" checkmarks.
DllCall("CheckMenuItem","uint",hTM,"uint",65305,"uint",A_IsSuspended ? 8:0)
DllCall("CheckMenuItem","uint",hTM,"uint",65306,"uint",M_IsPaused ? 8:0)
; Show menu to allow owner-drawing.
MI_ShowMenu(hTM)
return 0
}
}
WM_COMMAND(wParam, lParam, Msg, hwnd)
{
Critical
global M_IsPaused
id := wParam & 0xFFFF
if id in 65306,65403 ; tray pause, file menu pause
{
; When the script is not paused, WM_COMMAND() is called once for
; AutoHotkey --** and once for OwnerDrawnMenuMsgWin **--.
DetectHiddenWindows, On
WinGetClass, cl, ahk_id %hwnd%
if cl != AutoHotkey
return
; This will become incorrect if "pause" is used from the script.
M_IsPaused := ! M_IsPaused
}
} |

Download (or view) MI.ahk
Operating System Notes:
On Windows Vista, the script generates a 32-bit device-independent bitmap. This allows nice transparency (alpha blending) in icons, and allows Vista's menu style to apply.
On earlier versions of Windows, this method is not supported. Instead, the menu icons are owner-drawn. ShowMenu() or ShowOwnerDrawnMenu() must be called to show the menu with icons. ShowOwnerDrawnMenu() creates an invisible message window to act as the menu's owner (once per instance of the script.) As a side effect, showing a menu should not make the script/thread uninterruptible.
On Windows 2000 and later, PrivateExtractIcons() is used by SetMenuItemIcon() to extract an icon from a file. This should support any size of icon (tested with 16, 32 and 48.)
ExtractIconEx() is used on earlier versions of Windows, as PrivateExtractIcons() is not available. This supports 16x16 and 32x32 icons only. Other sizes may be specified, but the icon will be stretched to fit, regardless of which sizes are available in the source file. (However, LoadImage() can still be used to load the first icon of any given size from an .ico file.)
Other Methods
MI.Test.ahk (requires MI v1) shows a few other ways of displaying icons. In the following screenshot I've changed the menu colour to distinguish between the bitmap and the menu background. (On most versions of Windows - but not Vista - the menu background would be the same colour as the bitmap backgrounds.)
The "FakeAlphaTest" method could be used to fake transparency in a situation where owner-drawing is not an option (i.e. for some other app's menus.) The main issue with this method is:
(with Windows Standard/Classic colour scheme)
If you look closely, you can see the "background" in the bitmap is the inverse of the menu colour, and is a different colour to the selection. (Not an issue if you change the selection colour to match .)
You can see what effect owner-drawing icons has on Vista:
(no visual style)
Bitmap Manipulation
MI.Test.ahk (specifically the "FakeAlpha" tests; MI.Test.ahk requires MI v1) also demonstrates how to manipulate bitmaps using AutoHotkey. It would be possible, for example, to dynamically colour an icon.
References
Shell Blog: Vista Style Menus, Part 1 - Adding icons to standard menus
nanoANT: Themed menu’s icons, a complete Vista and XP solution
Note: I chose to write this rather than use MMenu because:- I did not want a whole new menu API.
- MMenu exclusively uses owner-drawing for icons, which disables Windows Vista's menu styles.
Last edited by Lexikos on Mon Dec 24, 2007 3:06 pm; edited 3 times in total |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 3959 Location: Pittsburgh
|
Posted: Sun Aug 12, 2007 5:52 pm Post subject: |
|
|
| Beautiful! Thanks for sharing it! |
|
| Back to top |
|
 |
Hardeep
Joined: 02 Jul 2006 Posts: 87
|
Posted: Sun Aug 12, 2007 8:50 pm Post subject: |
|
|
Thanks for sharing your work. Really nice...  |
|
| Back to top |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10467
|
Posted: Sun Sep 02, 2007 2:20 am Post subject: |
|
|
I've been catching up in this forum and only just now saw this topic. Great presentation and intuitive interface! I know it will be popular.
I haven't studied your approach carefully enough to understand the differences between it and Majkinetor's MMenu 1.0 b1. In any case, I'm sure one or both would be great to include in the standard library. |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2494 Location: Australia, Qld
|
Posted: Sun Sep 02, 2007 2:43 am Post subject: |
|
|
There are three main differences:- It uses 32-bit bitmaps on Vista instead of owner-drawing the icon. This allows Vista to apply its menu styles.
- It registers a window class and creates a message window to do the owner drawing, rather than using OnMessage. (I couldn't get OnMessage to catch the messages, though MMenu seems to. Also, I seem to recall majkinetor saying OnMessage sometimes misses the messages.)
- It is intended for use with the existing Menu commands, whereas MMenu reimplements the interface (MMenu_Add, etc.)
| Chris wrote: | | Great presentation and intuitive interface! | Thanks! It went through at least three or four function prototypes before I settled on the current interface.  |
|
| Back to top |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10467
|
Posted: Sun Sep 02, 2007 2:50 am Post subject: |
|
|
Thanks for the explanation. Since Vista is still relatively young, it's a pleasant surprise that you've provided a way to exploit menu styles from AutoHotkey.
By the way, a few months ago there were some improvements to Critical and OnMessage that may resolve the dropping of messages that Majkinetor mentioned. |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2494 Location: Australia, Qld
|
|
| Back to top |
|
 |
Sean
Joined: 12 Feb 2007 Posts: 1281
|
Posted: Sun Sep 02, 2007 7:39 am Post subject: |
|
|
I didn't know of it. Great stuffs!
What do you think about extending it to customize also the foreground/background colors, and fonts too if not too much?
There was a related request here:
http://www.autohotkey.com/forum/topic22317.html |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3615 Location: Belgrade
|
Posted: Sun Sep 02, 2007 10:23 am Post subject: |
|
|
Thx for this lexikos and for informatin about internals you provided.
| Quote: | | It registers a window class and creates a message window to do the owner drawing, rather than using OnMessage |
Very nice. Back in time I didn't have RegisterCallback so OnMessage was the only way.
| Quote: | | It is intended for use with the existing Menu commands, whereas MMenu reimplements the interface |
I never liked Menu API of AHK, as they are not practical for dynamic menus I had in some of my scripts. MMenu API allows much better control of the menu and its items.
BTW, is it possible to merge includes, and to provide some docu about API? _________________
 |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2494 Location: Australia, Qld
|
Posted: Sun Sep 02, 2007 10:52 am Post subject: |
|
|
| majkinetor wrote: | | BTW, is it possible to merge includes, and to provide some docu about API? | It is possible. There are only functions, so merging them should be no problem. It would probably make it easier to #include (at the moment you need #Include path\to\MI\directory), but I like to have them seperate for organisation sake. Perhaps I'll simply provide two versions, when I get time.
As for documentation, what did you have in mind? Is there anywhere the comments are particularly lacking?
| Sean wrote: | | What do you think about extending it to customize also the foreground/background colors, and fonts too if not too much? | At the moment, the menu isn't exactly owner-drawn, just the icons (the item's bitmap is set to HBMMENU_CALLBACK.) I'll think about adding full owner-draw capabilities.  |
|
| Back to top |
|
 |
Sean
Joined: 12 Feb 2007 Posts: 1281
|
Posted: Sun Sep 02, 2007 4:45 pm Post subject: |
|
|
| lexikos wrote: | | I'll think about adding full owner-draw capabilities. |
Good, then I don't have to. I was thinking about implementing owner-drawn menu myself, but there was no real motivation for me as I've had fully fledged custom menu system for years. |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2494 Location: Australia, Qld
|
Posted: Fri Oct 19, 2007 2:10 pm Post subject: |
|
|
Updated. v2 is stdlib compatible, and entirely contained within MI.ahk.
I also added icons to the tray menu of the example script.
See my first post for a download link and new screenshot.
| Sean wrote: | | lexikos wrote: | | I'll think about adding full owner-draw capabilities. |
Good, then I don't have to. I was thinking about implementing owner-drawn menu myself, but there was no real motivation for me as I've had fully fledged custom menu system for years. | Well, I thought about it for a while. I decided I wasn't satisfied enough with the Windows menu system to do anything further with it. I might eventually create something functionally (but not aesthetically) equivalent, using layered windows... |
|
| Back to top |
|
 |
majkinetor! Guest
|
Posted: Fri Oct 19, 2007 4:09 pm Post subject: |
|
|
| Great, thx ! |
|
| Back to top |
|
 |
nitrix Guest
|
Posted: Tue Oct 23, 2007 8:35 pm Post subject: |
|
|
this is a really great tool, thanks for sharing
BUT i do have a problem with the MI_SetMenuStyle
no matter what i choose, i does not change a thing :
; Valid (and safe to use) styles:
; MNS_AUTODISMISS 0x10000000
; MNS_CHECKORBMP 0x04000000 The same space is reserved for the check mark and the bitmap.
; MNS_NOCHECK 0x80000000 No space is reserved to the left of an item for a check mark.
i used to use Shimanov's Menu_AssignBitmap() without this problem
what i want to do is to remove the space on the left of the icons... so that my menu is more compact and menu item are not stripped
i use xp, most recent autohotkey release...
Nitrix |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2494 Location: Australia, Qld
|
Posted: Wed Oct 24, 2007 1:05 am Post subject: |
|
|
| nitrix wrote: | BUT i do have a problem with the MI_SetMenuStyle
no matter what i choose, i does not change a thing : | I use: | Code: | h_Root := MI_GetMenuHandle("Root")
;...
MI_SetMenuStyle(h_Root, 0x04000000) ; MNS_CHECKORBMP | MI_SetMenuStyle does not support menu names, hence MI_GetMenuHandle. |
|
| 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
|