Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Crazy Scripting : Include an Icon in your script


  • Please log in to reply
75 replies to this topic
SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005
[ Moderator!: Split from : <!-- m -->http://www.autohotke...pic.php?t=31670<!-- m --> ]

How to include an Icon in your script ?

The following template script demonstrates the loading of an icon included in the script itself and sets the
Tray Icon
Titlebar Icon
Alt-Tab menu Icon
#NoTrayIcon                                                ;    Hide the default Tray icon

IconDataHex =
( Join
[color=#808080]000001000100101010000100040028010000160000002800000010000000200000000100040000000000C00000
0000000000000000000000000000000000C6080800CE101000CE181800D6212100D6292900E13F3F00E7525200
EF5A5A00EF636300F76B6B00F7737300FF7B7B00FFC6C600FFCEC600FFDEDE00FFFFFF00CCCCCCCCCCCCCCCCC0
0000000000000CC11111111111111CC22222CFFE22222CC33333CFFE33333CC44444CFFE44444CC55555CFFE55
555CC55555CFFE55555CC55555CFFE55555CC66666CFFE66666CC77777777777777CC88888CFFC88888CC99999
CFFC99999CCAAAAAAAAAAAAAACCBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCC00000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000[/color]
)

VarSetCapacity( IconData,( nSize:=StrLen(IconDataHex)//2) )
Loop %nSize% ; MCode by Laszlo Hars: http://www.autohotkey.com/forum/viewtopic.php?t=21172
  NumPut( "0x" . SubStr(IconDataHex,2*A_Index-1,2), IconData, A_Index-1, "Char" )
IconDataHex := ""                                          ; Hex contents needed no more

hICon := DllCall( "CreateIconFromResourceEx", UInt,&IconData+22, UInt,NumGet(IconData,14)
       , Int,1, UInt,0x30000, Int,16, Int,16, UInt,0 )

; Thanks Chris : http://www.autohotkey.com/forum/viewtopic.php?p=69461#69461
Gui +LastFound               ; Set our GUI as LastFound window ( affects next two lines )
SendMessage, ( WM_SETICON:=0x80 ), 0, hIcon                ; Set the Titlebar Icon
SendMessage, ( WM_SETICON:=0x80 ), 1, hIcon                ; Set the Alt-Tab icon

; Creating NOTIFYICONDATA : www.msdn.microsoft.com/en-us/library/aa930660.aspx
; Thanks Lexikos : www.autohotkey.com/forum/viewtopic.php?p=162175#162175
PID := DllCall("GetCurrentProcessId"), VarSetCapacity( NID,444,0 ), NumPut( 444,NID )
DetectHiddenWindows, On
NumPut( WinExist( A_ScriptFullPath " ahk_class AutoHotkey ahk_pid " PID),NID,4 )
DetectHiddenWindows, Off
NumPut( 1028,NID,8 ), NumPut( 2,NID,12 ), NumPut( hIcon,NID,20 )

Menu, Tray, Icon                                           ; Show the default Tray icon ..
DllCall( "shell32\Shell_NotifyIcon", UInt,0x1, UInt,&NID ) ; .. and immediately modify it

Gui, Show, w640 h480
Return

GuiClose:
 ExitApp

About the hex data:

With IconEx, extract any interesting 16x16 icon
Convert binary to hex
Replace the hex data in template with it.

About Alt-Tab icon

Alt-Tab menu requires a 32x32 sized icon. so you may have repeat the procedure create and load it. The icon used in the template was created by me .. and I have designed it in such a way that it does not show artifacts when resized to 32x32.

On a related note,
My script posted in the following topic demonstrates Animation of Tray Icon :

HDD Activity Monitoring LED posted by SeanI converted four 16x16x4b icons to hex, chopped off the first 44 chars, made them into a single string, and refer the individual Icondata with an offset of 296.

:)

Edit:NumPut( hIcon,NID,20 ) was missing in the code, now added. Sorry for the inconvenience

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
The above script changes the Alt-TAB icon, the taskbar icon and the title bar icon to "i", but leaves the tray icon blank. Is it a Vista problem?

SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005

Is it a Vista problem?


Not a problem really.. I think Vista requires a minimum of 256 colors for a tray icon whereas I have used a 16 color icon - to contain script size.

I will try in Vista and post again.

:)

Edit: Seems to be a different problem.. I tried 4bit, 8bit and 32bit .. nothing works :(

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
Maybe an appropriate call to Shell_NotifyIcon with NIM_SETVERSION (0x00000004) helps?

SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005
NumPut( hIcon,NID,20 ) was missing in the code, now added. Sorry for the inconvenience.

I posted tested code from PSPad and it was a matter of ^a ^c and ^v .
I would understand if I had missed the starting or ending line, but this, I keep guessing. :(

Also I tested my other HDD indicator, and it works fine in Vista.

:)

heresy
  • Members
  • 291 posts
  • Last active: Sep 26 2008 10:47 PM
  • Joined: 11 Mar 2008
Thanks SKAN for kindly answer as always

i don't get it perfectly yet
but i know that you're the person who can explain complicated things as easy as possible.
if i can't understand yours, i shall not understand anything else.
so i'll deal with it until i can get it mine :)
THANK YOU SO MUCH!

it aren't goes to your great Tips & Tricks collection?
Easy WinAPI - Dive into Windows API World
Benchmark your AutoHotkey skills at PlayAHK.com

jfty.009260
  • Members
  • 8 posts
  • Last active: Jul 31 2008 02:49 PM
  • Joined: 18 Mar 2008
Crazy scripting indeed...brilliant.

rickly
  • Guests
  • Last active:
  • Joined: --
SKAN, your Crazy Scripting scripts are truely ingenious and usefull, but I think I found a bug in this one. I could not get this script to function as described (hICon always returned 0, with ErrorLevel and A_LastError = 0). After some investigation I found that the second param of the dll call to CreateIconFromResourceEx had the wrong value. After changing the second param from 0 to nSize, all is working well.

Thanks for all your contibutions.

How to include an Icon in your script ?

The following template script demonstrates the loading of an icon included in the script itself and sets the Tray Icon ...

...
hICon := DllCall( "CreateIconFromResourceEx", UInt,&IconData
                , UInt,[color=darkred]0[/color], Int,1, UInt,196608, Int,16, Int,16, UInt,0 )
...

and

hICon := DllCall( "CreateIconFromResourceEx", UInt,[color=red]&IconData+22[/color]
                , UInt,[color=darkred]0[/color], Int,1, UInt,196608, Int,16, Int,16, UInt,0 )

but at MSDN

HICON CreateIconFromResourceEx(
PBYTE pbIconBits,
DWORD cbIconBits,
...
cbIconBits [in] Specifies the size, in bytes, of the set of bits pointed to by the pbIconBits parameter.

So the corrected code for the dll call is:
...
hICon := DllCall( "CreateIconFromResourceEx", UInt,&IconData
                , UInt,[color=green]nSize[/color], Int,1, UInt,196608, Int,16, Int,16, UInt,0 )
...
and
hICon := DllCall( "CreateIconFromResourceEx", UInt,[color=red]&IconData+22[/color]
                , UInt,[color=green]nSize[/color], Int,1, UInt,196608, Int,16, Int,16, UInt,0 )


SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005

Crazy Scripting scripts are truely ingenious and useful


Thank for the nice words. :)

I found a bug in this one


I do not remember how I justified passing the null value. :roll:
I need to comment my code elaborate enough.. for my own referece.
It works fine for me in XP SP2 though. I need to test is Vista and then I will correct my code.

Many thanks for reporting this.

Regards, :)
kWo4Lk1.png

Hybridx24
  • Guests
  • Last active:
  • Joined: --
I'm using Vista and I was using the .Ico replacement technique (which is actually brilliant :p) and I'm having a few issues... I can't get it to work without disabling my whole Joystick configuration (my script makes my 360 controller work as a mouse). Whenever the Icon shows up in the tray, the controller doesn't work, but when I modify it, the controller works but there is no tray icon (which defeats the whole purpose of the code...). Any ideas as to what be going wrong?

Hybridx24
  • Guests
  • Last active:
  • Joined: --
Here's the code that doesn't work (the custom icon shows up, but the joystick doesn't work):
#NoTrayIcon

IconDataHex =
( join
2800000010000000200000000100040000000000C000000000000000000000000000000000000000C6080800CE
101000CE181800D6212100D6292900E13F3F00E7525200EF5A5A00EF636300F76B6B00F7737300FF7B7B00FFC6
C600FFCEC600FFDEDE00FFFFFF00CCCCCCCCCCCCCCCCC00000000000000CC11111111111111CC22222CFFE2222
2CC33333CFFE33333CC44444CFFE44444CC55555CFFE55555CC55555CFFE55555CC55555CFFE55555CC66666CF
FE66666CC77777777777777CC88888CFFC88888CC99999CFFC99999CCAAAAAAAAAAAAAACCBBBBBBBBBBBBBBCCC
CCCCCCCCCCCCCC0000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000
)
VarSetCapacity( IconData,( nSize:=StrLen(IconDataHex)//2) )
Loop %nSize% ; MCode by Laszlo Hars: http://www.autohotkey.com/forum/viewtopic.php?t=21172
  NumPut( "0x" . SubStr(IconDataHex,2*A_Index-1,2), IconData, A_Index-1, "Char" )
IconDataHex := ""            ; contents needed no more
hICon := DllCall( "CreateIconFromResourceEx", UInt,&IconData
                , UInt,0, Int,1, UInt,196608, Int,16, Int,16, UInt,0 )
             
; Thanks Chris : http://www.autohotkey.com/forum/viewtopic.php?p=69461#69461       
Gui +LastFound               ; Set our GUI as LastFound window ( affects next two lines )
SendMessage, ( WM_SETICON:=0x80 ), 0, hIcon  ; Set the Titlebar Icon
SendMessage, ( WM_SETICON:=0x80 ), 1, hIcon  ; Set the Alt-Tab icon

; Creating NOTIFYICONDATA : http://msdn.microsoft.com/en-us/library/aa930660.aspx
; Thanks Lexikos : http://www.autohotkey.com/forum/viewtopic.php?p=162175#162175
PID := DllCall("GetCurrentProcessId"), VarSetCapacity( NID,444,0 ), NumPut( 444,NID )
DetectHiddenWindows, On
NumPut( WinExist( A_ScriptFullPath " ahk_class AutoHotkey ahk_pid " PID),NID,4 )
DetectHiddenWindows, Off
NumPut( 1028,NID,8 ), NumPut( 2,NID,12 ), NumPut( hIcon,NID,20 )
Menu, Tray, Icon                                           ;   Shows the default Tray icon
DllCall( "shell32\Shell_NotifyIcon", UInt,0x1, UInt,&NID ) ; and we immediately modify it.
Gui, Show, w640 h480               
Return

GuiClose:
 ExitApp

#NoEnv
;Menu, Tray, Icon, %A_WinDir%\system32\joy.cpl
Menu, Tray, Tip, Xbox 360 Controller (Hybrid Edition)



--------------------------------------



Here's the code that does work (the custom icon doesn't show up, but the joystick works):

#NoTrayIcon

IconDataHex =
( join
2800000010000000200000000100040000000000C000000000000000000000000000000000000000C6080800CE
101000CE181800D6212100D6292900E13F3F00E7525200EF5A5A00EF636300F76B6B00F7737300FF7B7B00FFC6
C600FFCEC600FFDEDE00FFFFFF00CCCCCCCCCCCCCCCCC00000000000000CC11111111111111CC22222CFFE2222
2CC33333CFFE33333CC44444CFFE44444CC55555CFFE55555CC55555CFFE55555CC55555CFFE55555CC66666CF
FE66666CC77777777777777CC88888CFFC88888CC99999CFFC99999CCAAAAAAAAAAAAAACCBBBBBBBBBBBBBBCCC
CCCCCCCCCCCCCC0000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000
)
VarSetCapacity( IconData,( nSize:=StrLen(IconDataHex)//2) )
Loop %nSize% ; MCode by Laszlo Hars: http://www.autohotkey.com/forum/viewtopic.php?t=21172
  NumPut( "0x" . SubStr(IconDataHex,2*A_Index-1,2), IconData, A_Index-1, "Char" )
IconDataHex := ""            ; contents needed no more
hICon := DllCall( "CreateIconFromResourceEx", UInt,&IconData
                , UInt,0, Int,1, UInt,196608, Int,16, Int,16, UInt,0 )
             
; Thanks Chris : http://www.autohotkey.com/forum/viewtopic.php?p=69461#69461       
Gui +LastFound               ; Set our GUI as LastFound window ( affects next two lines )
SendMessage, ( WM_SETICON:=0x80 ), 0, hIcon  ; Set the Titlebar Icon
SendMessage, ( WM_SETICON:=0x80 ), 1, hIcon  ; Set the Alt-Tab icon

; Creating NOTIFYICONDATA : http://msdn.microsoft.com/en-us/library/aa930660.aspx
; Thanks Lexikos : http://www.autohotkey.com/forum/viewtopic.php?p=162175#162175
PID := DllCall("GetCurrentProcessId"), VarSetCapacity( NID,444,0 ), NumPut( 444,NID )
DetectHiddenWindows, On
NumPut( WinExist( A_ScriptFullPath " ahk_class AutoHotkey ahk_pid " PID),NID,4 )
DetectHiddenWindows, Off
NumPut( 1028,NID,8 ), NumPut( 2,NID,12 ), NumPut( hIcon,NID,20 )
Menu, Tray, Icon                                           ;   Shows the default Tray icon
DllCall( "shell32\Shell_NotifyIcon", UInt,0x1, UInt,&NID ) ; and we immediately modify it.

#NoEnv
;Menu, Tray, Icon, %A_WinDir%\system32\joy.cpl
Menu, Tray, Tip, Xbox 360 Controller (Hybrid Edition)

--------------------

Note: I don't have a GUI for my AHK script.

Hybridc24
  • Guests
  • Last active:
  • Joined: --
God I'm making an account after this post... :p

What I forgot in my previous post; This is what I removed to make the joystick work but the icon doesn't show up now:

Gui, Show, w640 h480               
Return

GuiClose:
 ExitApp


SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005
Dear Hybrid, :)

[*:klayckm4]Do not use Menu,Tray, Tip after calling Shell_NotifyIcon() - it resets the icon to AHK default ( Green-H ).
[*:klayckm4]Also note, that suspending / pausing the script will reset the tray icon, and so, you have to handle it from your code
[*:klayckm4]You are not using a GUI and you may remove the redundant calls to set Alt-Tab and Titlebar icons.
Here is an example on how to workaround Pause:

#NoTrayIcon

IconDataHex =
( join
2800000010000000200000000100040000000000C000000000000000000000000000000000000000C6080800CE
101000CE181800D6212100D6292900E13F3F00E7525200EF5A5A00EF636300F76B6B00F7737300FF7B7B00FFC6
C600FFCEC600FFDEDE00FFFFFF00CCCCCCCCCCCCCCCCC00000000000000CC11111111111111CC22222CFFE2222
2CC33333CFFE33333CC44444CFFE44444CC55555CFFE55555CC55555CFFE55555CC55555CFFE55555CC66666CF
FE66666CC77777777777777CC88888CFFC88888CC99999CFFC99999CCAAAAAAAAAAAAAACCBBBBBBBBBBBBBBCCC
CCCCCCCCCCCCCC0000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000
)
VarSetCapacity( IconData,( nSize:=StrLen(IconDataHex)//2) )
Loop %nSize% 
  NumPut( "0x" . SubStr(IconDataHex,2*A_Index-1,2), IconData, A_Index-1, "Char" )
IconDataHex := ""            
hICon := DllCall( "CreateIconFromResourceEx", UInt,&IconData
                , UInt,nSize, Int,1, UInt,196608, Int,16, Int,16, UInt,0 )
             
PID := DllCall("GetCurrentProcessId"), VarSetCapacity( NID,444,0 ), NumPut( 444,NID )
DetectHiddenWindows, On
NumPut( WinExist( A_ScriptFullPath " ahk_class AutoHotkey ahk_pid " PID),NID,4 )
DetectHiddenWindows, Off
NumPut( 1028,NID,8 ), NumPut( 2,NID,12 ), NumPut( hIcon,NID,20 )
[color=red]Menu, Tray, Tip, Xbox 360 Controller (Hybrid Edition)[/color] ; Use this command before Shell_NotifyIcon()
Menu, Tray, Icon                                           
DllCall( "shell32\Shell_NotifyIcon", UInt,0x1, UInt,&NID )
Return

Pause::
  Pause
  DllCall( "shell32\Shell_NotifyIcon", UInt,0x1, UInt,&NID )
Return

Regards, :)
kWo4Lk1.png

Hybrid
  • Members
  • 4 posts
  • Last active: Jul 31 2008 10:55 PM
  • Joined: 22 Jul 2008
Well, the pause icon part of the script didn't seem to work, but I don't really care since you managed to fix everything that I wanted in the first place. :D

#NoTrayIcon

IconDataHex =
( join
2800000010000000200000000100040000000000C000000000000000000000000000000000000000C6080800CE
101000CE181800D6212100D6292900E13F3F00E7525200EF5A5A00EF636300F76B6B00F7737300FF7B7B00FFC6
C600FFCEC600FFDEDE00FFFFFF00CCCCCCCCCCCCCCCCC00000000000000CC11111111111111CC22222CFFE2222
2CC33333CFFE33333CC44444CFFE44444CC55555CFFE55555CC55555CFFE55555CC55555CFFE55555CC66666CF
FE66666CC77777777777777CC88888CFFC88888CC99999CFFC99999CCAAAAAAAAAAAAAACCBBBBBBBBBBBBBBCCC
CCCCCCCCCCCCCC0000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000
)
VarSetCapacity( IconData,( nSize:=StrLen(IconDataHex)//2) )
Loop %nSize%
  NumPut( "0x" . SubStr(IconDataHex,2*A_Index-1,2), IconData, A_Index-1, "Char" )
IconDataHex := ""           
hICon := DllCall( "CreateIconFromResourceEx", UInt,&IconData
                , UInt,nSize, Int,1, UInt,196608, Int,16, Int,16, UInt,0 )
             
PID := DllCall("GetCurrentProcessId"), VarSetCapacity( NID,444,0 ), NumPut( 444,NID )
DetectHiddenWindows, On
NumPut( WinExist( A_ScriptFullPath " ahk_class AutoHotkey ahk_pid " PID),NID,4 )
DetectHiddenWindows, Off
NumPut( 1028,NID,8 ), NumPut( 2,NID,12 ), NumPut( hIcon,NID,20 )
Menu, Tray, Tip, Xbox 360 Controller (Hybrid Edition) ; Use this command before Shell_NotifyIcon()
Menu, Tray, Icon                                           
DllCall( "shell32\Shell_NotifyIcon", UInt,0x1, UInt,&NID )

I just kept it at that and it did the trick... thanks so much for all your help SKAN, it's people like you who make communities like this great. :D:D

SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005

Well, the pause icon part of the script didn't seem to work


Thanks for the info. I never took time to test this in Vista and W2K .. I should.
And thanks for the nice words friend.

:)
kWo4Lk1.png