in reply to Win32::GUI::Menu icon problem - I need help !
Win32::GUI doesn't actually allow you to change the icons of menu items directly. Instead you will need to use some Win32 API functions. You can find more information about this method on the Win32::GUI mailing lists here. Unfortunately, this method only works up to Windows XP. For later versions, one method that you could use is owner-drawn menu items. Here is an example:
#!perl use strict; use warnings; use PeekPoke qw(peek poke); use Win32::API; use Win32::GUI qw(); use Win32::GUI::Constants qw( CW_USEDEFAULT WM_MEASUREITEM WM_DRAWITEM ODA_DRAWENTIRE SRCCOPY ); use constant { MENU_ITEMS => 6, # These are needed for creating menu icons MIIM_BITMAP => 0x00000080, MIM_STYLE => 0x00000010, MNS_CHECKORBMP => 0x04000000, MNS_NOCHECK => 0x80000000, HBMMENU_CALLBACK => 0xFFFFFFFF, HBMMENU_SYSTEM => 1, HBMMENU_MBAR_RESTORE => 2, HBMMENU_MBAR_MINIMIZE => 3, HBMMENU_MBAR_CLOSE => 5, HBMMENU_MBAR_CLOSE_D => 6, HBMMENU_MBAR_MINIMIZE_D => 7, HBMMENU_POPUP_CLOSE => 8, HBMMENU_POPUP_RESTORE => 9, HBMMENU_POPUP_MAXIMIZE => 10, HBMMENU_POPUP_MINIMIZE => 11, }; # Import the Win32 API functions we need Win32::API->Import( 'user32.dll', 'SetMenuItemInfo', 'LILP', 'L' ); Win32::API->Import( 'user32.dll', 'SetMenuInfo', 'LP', 'L' ); # Create a simple menu # We specify our own menu item id since we need to check the id of the + item # that needs to be drawn in the WM_DRAWITEM hook below. my $mnuMain = Win32::GUI::Menu->new( 'Menu' => 'mnuMenu', map { ( "> Item $_" => { -name => "mnuMenuItem$_", -id => $_ } ) +} 1 .. MENU_ITEMS, ); # Remove check mark space my $menuinfo = pack 'LLLILLL', 28, # Size MIM_STYLE, # Mask MNS_NOCHECK, # Style 0, # Max height of menu 0, # Background brush 0, # Context help identifier 0; # Application defined value SetMenuInfo( $mnuMain->{mnuMenu}->{-handle}, $menuinfo ); # Create some simple bitmaps my @bitmaps; foreach( 1 .. MENU_ITEMS ){ my $r = int rand 256; my $g = int rand 256; my $b = int rand 256; my $data = pack 'C*', map { $r, $g, $b, 0 } 0 .. ( ( 16 ** 2 ) - 1 + ); push @bitmaps, Win32::GUI::Bitmap::Create( 16, 16, 1, 32, $data ); } # Specify that bitmap for each menu item will be owner drawn my $menuiteminfo = pack 'IIIIILLLLLIL', 48, # Size MIIM_BITMAP, # Mask 0, # Type 0, # State 0, # ID 0, # SubMenu 0, # Checked bitmap 0, # Unchecked bitmap 0, # Item Data 0, # Type Data 0, # Length of menu item text HBMMENU_CALLBACK; # Bitmap will be owner drawn SetMenuItemInfo( $mnuMain->{mnuMenu}->{-handle}, $_, 0, $menuiteminfo +) foreach 1 .. MENU_ITEMS; # Create a window my $winMain = Win32::GUI::Window->new( -name => 'winMain', -text => 'Win32::GUI Menu Icons', -pos => [ CW_USEDEFAULT, CW_USEDEFAULT ], -size => [ 320, 240 ], -menu => $mnuMain, ); # Create a hook for the WM_MEASUREITEM message that specifies the size + of the icon $winMain->Hook( WM_MEASUREITEM, sub { # dump \@_; my( $self, $wParam, $lParam, $type, $msgcode ) = @_; return 1 unless $type == 0; return 1 unless $msgcode == WM_MEASUREITEM; if( $wParam == 0 ){ # Process if message was sent by a menu poke( $lParam + 12, 16 ); # 12 is the offset of the item +Width member poke( $lParam + 16, 16 ); # 16 is the offset of the item +Height member } return 1; }, ); # Create a hook for the WM_DRAWITEM message to draw the bitmap for eac +h menu item $winMain->Hook( WM_DRAWITEM, sub { my( $self, $wParam, $lParam, $type, $msgcode ) = @_; if( $wParam == 0 ){ # Process if message is sent by a menu # Unpack data from the structure my %drawitem; @drawitem{qw(CtlType CtlID itemID itemAction itemState hwn +dItem hDC left top right bottom itemData)} = unpack 'IIIIILLllllL', u +npack 'P48', pack 'L', $lParam; # Draw the bitmap if( $drawitem{'itemAction'} == ODA_DRAWENTIRE ){ my $hDC = $drawitem{'hDC'}; my $memdc = Win32::GUI::DC::CreateCompatibleDC($hDC +); my $oldimage = $memdc->SelectObject( $bitmaps[ $drawit +em{'itemID'} - 1 ] ); Win32::GUI::DC::BitBlt( $hDC, $drawitem{'left'}, $drawitem{'top'}, $drawitem{'right'} - $drawitem{'left'}, $drawitem{'bottom'} - $drawitem{'top'}, $memdc, 0, 0, SRCCOPY ); } return 1; } }, ); $winMain->Show(); Win32::GUI::Dialog(); __END__
Update: Link fixed.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Win32::GUI::Menu icon problem - I need help !
by Ahmet (Novice) on Dec 14, 2010 at 06:02 UTC | |
by kejohm (Hermit) on Dec 14, 2010 at 07:55 UTC | |
by Ahmet (Novice) on Dec 14, 2010 at 10:50 UTC |