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 

Menu Icons v2 (stdlib)
Goto page 1, 2, 3, 4, 5, 6  Next
 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
Lexikos



Joined: 17 Oct 2006
Posts: 4465
Location: Qld, Australia

PostPosted: Sun Aug 12, 2007 6:13 am    Post subject: Menu Icons v2 (stdlib) Reply with quote

Menu Icons
Provides a set of functions for implementing icons in menus.

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
Covered by Lexikos' default copyright license.

Version History
v2.21 (2010-03-13)
  • Fixed: WM_COMMAND messages received by subclassed GUI windows were erroneously forwarded to the script's main window. This broke button gLabels.
  • Fixed: Unicode incompatibility in MI_ExtractIcon.
v2.2 (2009-01-08)
  • Changed MI_SetMenuItemIcons to automatically delete the previous icon or bitmap.
  • If individual menu items are to be removed, call MI_SetMenuItemIcons(MenuNameOrHandle, ItemPos, 0) to remove the icon.
  • Added MI_RemoveIcons, to be called before deleting a menu.
  • Misc optimizations (thanks animeaime).
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.
v2 (2007-10-19)
  • Now stdlib compatible (added MI_ prefix to functions.)
  • Merged everything into MI.ahk, removing wrapper functions in the process.

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 Laughing.)

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 Sat Mar 13, 2010 3:23 am; edited 6 times in total
Back to top
View user's profile Send private message Visit poster's website
Laszlo



Joined: 14 Feb 2005
Posts: 4512
Location: Boulder, CO

PostPosted: Sun Aug 12, 2007 5:52 pm    Post subject: Reply with quote

Beautiful! Thanks for sharing it!
Back to top
View user's profile Send private message
Hardeep



Joined: 02 Jul 2006
Posts: 87

PostPosted: Sun Aug 12, 2007 8:50 pm    Post subject: Reply with quote

Thanks for sharing your work. Really nice... Smile
Back to top
View user's profile Send private message
Chris
Site Admin


Joined: 02 Mar 2004
Posts: 10667

PostPosted: Sun Sep 02, 2007 2:20 am    Post subject: Reply with quote

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
View user's profile Send private message Send e-mail
Lexikos



Joined: 17 Oct 2006
Posts: 4465
Location: Qld, Australia

PostPosted: Sun Sep 02, 2007 2:43 am    Post subject: Reply with quote

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.)
Smile
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. Laughing
Back to top
View user's profile Send private message Visit poster's website
Chris
Site Admin


Joined: 02 Mar 2004
Posts: 10667

PostPosted: Sun Sep 02, 2007 2:50 am    Post subject: Reply with quote

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
View user's profile Send private message Send e-mail
Lexikos



Joined: 17 Oct 2006
Posts: 4465
Location: Qld, Australia

PostPosted: Sun Sep 02, 2007 3:50 am    Post subject: Reply with quote

Chris wrote:
Since Vista is still relatively young, it's a pleasant surprise that you've provided a way to exploit menu styles from AutoHotkey.
It's mostly thanks to these two articles:
Shell Blog: Vista Style Menus, Part 1 - Adding icons to standard menus
nanoANT: Themed menu’s icons, a complete Vista and XP solution (also details using "checkmark" bitmaps, and owner-drawn icons.)

(also just added those links to my first post)
Back to top
View user's profile Send private message Visit poster's website
Sean



Joined: 12 Feb 2007
Posts: 2195

PostPosted: Sun Sep 02, 2007 7:39 am    Post subject: Reply with quote

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
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 4114
Location: Belgrade

PostPosted: Sun Sep 02, 2007 10:23 am    Post subject: Reply with quote

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
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 4465
Location: Qld, Australia

PostPosted: Sun Sep 02, 2007 10:52 am    Post subject: Reply with quote

majkinetor wrote:
BTW, is it possible to merge includes, and to provide some docu about API?
It is possible. Wink 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. Smile
Back to top
View user's profile Send private message Visit poster's website
Sean



Joined: 12 Feb 2007
Posts: 2195

PostPosted: Sun Sep 02, 2007 4:45 pm    Post subject: Reply with quote

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
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 4465
Location: Qld, Australia

PostPosted: Fri Oct 19, 2007 2:10 pm    Post subject: Reply with quote

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. Razz 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
View user's profile Send private message Visit poster's website
majkinetor!
Guest





PostPosted: Fri Oct 19, 2007 4:09 pm    Post subject: Reply with quote

Great, thx !
Back to top
nitrix
Guest





PostPosted: Tue Oct 23, 2007 8:35 pm    Post subject: Reply with quote

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: 4465
Location: Qld, Australia

PostPosted: Wed Oct 24, 2007 1:05 am    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page 1, 2, 3, 4, 5, 6  Next
Page 1 of 6

 
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