Jump to content

Recommended Posts

Posted

Hi there,

I found this topic and Yashied posted a way to add an icon to a menu without using an UDF.

I want to implement this part into my script because the UDF isn't fully compatible with Windows 7 and 64bit systems (exactly where I am on...)

So I tried this:

_GUICtrlMenu_SetItemBmp ($hMenu, 0, _CreateBitmapFromIcon(_WinAPI_GetSysColor($COLOR_MENU), @ScriptDir & '\favicon.ico', 43, 16, 16))
Func _CreateBitmapFromIcon($iBackground, $sIcon, $iIndex, $iWidth, $iHeight)

    Local $hDC, $hBackDC, $hBackSv, $hIcon, $hBitmap

    $hDC = _WinAPI_GetDC(0)
    $hBackDC = _WinAPI_CreateCompatibleDC($hDC)
    $hBitmap = _WinAPI_CreateSolidBitmap(0, $iBackground, $iWidth, $iHeight)
    $hBackSv = _WinAPI_SelectObject($hBackDC, $hBitmap)
    $hIcon = $sIcon;_WinAPI_PrivateExtractIcon($sIcon, $iIndex, $iWidth, $iHeight)
    If Not @error Then
    _WinAPI_DrawIconEx($hBackDC, 0, 0, $hIcon, 0, 0, 0, 0, $DI_NORMAL)
    _WinAPI_DestroyIcon($hIcon)
    EndIf
    _WinAPI_SelectObject($hBackDC, $hBackSv)
    _WinAPI_ReleaseDC(0, $hDC)
    _WinAPI_DeleteDC($hBackDC)
    Return $hBitmap
EndFunc ;==>_CreateBitmapFromIcon

Func _WinAPI_PrivateExtractIcon($sIcon, $iIndex, $iWidth, $iHeight)

    Local $hIcon, $tIcon = DllStructCreate('hwnd'), $tID = DllStructCreate('hwnd')
    Local $Ret = DllCall('user32.dll', 'int', 'PrivateExtractIcons', 'str', $sIcon, 'int', $iIndex, 'int', $iWidth, 'int', $iHeight, 'ptr', DllStructGetPtr($tIcon), 'ptr', DllStructGetPtr($tID), 'int', 1, 'int', 0)

    If (@error) Or ($Ret[0] = 0) Then
    Return SetError(1, 0, 0)
    EndIf
    $hIcon = DllStructGetData($tIcon, 1)
    If ($hIcon = Ptr(0)) Or (Not IsPtr($hIcon)) Then
    Return SetError(1, 0, 0)
    EndIf
    Return $hIcon
EndFunc
But it doesn't display the icon... How come, and how to fix it?

Thanks in advance,

Rawox

favicon.ico

Posted

This works on my Win7 x64 VM!

#include <GDIPlus.au3>
#include <GuiMenu.au3>
#include <GuiConstantsEx.au3>
#include <WinAPI.au3>

Global $iMemo


$file = FileOpenDialog("Select ICO file", @ScriptDir, ("Icons (*.ico)"))

If @error Then Exit

$Ret = DllCall("shell32", "long", "ExtractAssociatedIcon", "int", 0, "str", $file, "int*", 0)
$hIcon = $Ret[0]

_GDIPlus_Startup()
$hBitmap = DllCall($ghGDIPDll,"int", "GdipCreateBitmapFromHICON", "ptr", $hIcon, "int*", 0)
$hBitmap = $hBitmap[2]
_WinAPI_DestroyIcon($hIcon)

_Main()

_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_Shutdown()

Exit

Func _Main()
    Local $hGUI, $hFile, $hEdit, $hHelp, $hMain
    Local Enum $idNew = 1000, $idOpen, $idSave, $idExit, $idCut, $idCopy, $idPaste, $idAbout

    ; Create GUI
    $hGUI = GUICreate("Menu", 400, 300)

    ; Create File menu
    $hFile = _GUICtrlMenu_CreateMenu ()
    _GUICtrlMenu_InsertMenuItem ($hFile, 0, "&New", $idNew)
    _GUICtrlMenu_InsertMenuItem ($hFile, 1, "&Open", $idOpen)
    _GUICtrlMenu_InsertMenuItem ($hFile, 2, "&Save", $idSave)
    _GUICtrlMenu_InsertMenuItem ($hFile, 3, "", 0)
    _GUICtrlMenu_InsertMenuItem ($hFile, 4, "E&xit", $idExit)

    ; Create Edit menu
    $hEdit = _GUICtrlMenu_CreateMenu ()
    _GUICtrlMenu_InsertMenuItem ($hEdit, 0, "&Cut", $idCut)
    _GUICtrlMenu_InsertMenuItem ($hEdit, 1, "C&opy", $idCopy)
    _GUICtrlMenu_InsertMenuItem ($hEdit, 2, "&Paste", $idPaste)

    ; Create Help menu
    $hHelp = _GUICtrlMenu_CreateMenu ()
    _GUICtrlMenu_InsertMenuItem ($hHelp, 0, "&About", $idAbout)

    ; Create Main menu
    $hMain = _GUICtrlMenu_CreateMenu ()
    _GUICtrlMenu_InsertMenuItem ($hMain, 0, "&File", 0, $hFile)
    _GUICtrlMenu_InsertMenuItem ($hMain, 1, "&Edit", 0, $hEdit)
    _GUICtrlMenu_InsertMenuItem ($hMain, 2, "&Help", 0, $hHelp)

    ; Set window menu
    _GUICtrlMenu_SetMenu ($hGUI, $hMain)

    ; Create memo control
    $iMemo = GUICtrlCreateEdit("", 2, 2, 396, 276, 0)
    GUICtrlSetFont($iMemo, 9, 400, 0, "Courier New")
    GUISetState()

    ; Set New menu item to have a bitmap
    _GUICtrlMenu_SetItemBmp ($hFile, 0, _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap))
    MemoWrite("Item bitmap handle: 0x" & Hex(_GUICtrlMenu_GetItemBmp ($hFile, 0)))

    ; Loop until user exits
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
EndFunc ;==>_Main

; Write message to memo
Func MemoWrite($sMessage)
    GUICtrlSetData($iMemo, $sMessage & @CRLF, 1)
EndFunc ;==>MemoWrite

After selecting an icon press file and you should see the icon for item new.

BR,

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Posted

Here a fast and inelegant solution:

#AutoIt3Wrapper_Icon=c:\_Downloads\popup.au3.ico
#include <GDIPlus.au3>
#include <GuiMenu.au3>
#include <GuiConstantsEx.au3>
#include <WinAPI.au3>

Global $iMemo


$file = FileOpenDialog("Select ICO file", @ScriptDir, ("Icons (*.ico)"))

If @error Then Exit

$Ret = DllCall("shell32", "long", "ExtractAssociatedIcon", "int", 0, "str", $file, "int*", 0)
$hIcon = $Ret[0]

_GDIPlus_Startup()
$hImage = DllCall($ghGDIPDll,"int", "GdipCreateBitmapFromHICON", "ptr", $hIcon, "int*", 0)
$hImage = $hImage[2]
_WinAPI_DestroyIcon($hIcon)

$dest_x = 16
$dest_y = 16
$iX = _GDIPlus_ImageGetWidth($hImage)
$iY = _GDIPlus_ImageGetHeight($hImage)
$hGUI = GUICreate("", $iX, $iY)
$hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)
$hBitmap = _GDIPlus_BitmapCreateFromGraphics($dest_x, $dest_y, $hGraphics)
$hBuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
_GDIPlus_GraphicsDrawImageRect($hBuffer, $hImage, 0, 0, $dest_x, $dest_y)
GUIDelete($hGUI)

_Main()

_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_BitmapDispose($hImage)
_GDIPlus_GraphicsDispose($hBuffer)
_GDIPlus_GraphicsDispose($hGraphics)
_GDIPlus_Shutdown()

Exit

Func _Main()
    Local $hGUI, $hFile, $hEdit, $hHelp, $hMain
    Local Enum $idNew = 1000, $idOpen, $idSave, $idExit, $idCut, $idCopy, $idPaste, $idAbout

    ; Create GUI
    $hGUI = GUICreate("Menu", 400, 300)

    ; Create File menu
    $hFile = _GUICtrlMenu_CreateMenu ()
    _GUICtrlMenu_InsertMenuItem ($hFile, 0, "&New", $idNew)
    _GUICtrlMenu_InsertMenuItem ($hFile, 1, "&Open", $idOpen)
    _GUICtrlMenu_InsertMenuItem ($hFile, 2, "&Save", $idSave)
    _GUICtrlMenu_InsertMenuItem ($hFile, 3, "", 0)
    _GUICtrlMenu_InsertMenuItem ($hFile, 4, "E&xit", $idExit)

    ; Create Edit menu
    $hEdit = _GUICtrlMenu_CreateMenu ()
    _GUICtrlMenu_InsertMenuItem ($hEdit, 0, "&Cut", $idCut)
    _GUICtrlMenu_InsertMenuItem ($hEdit, 1, "C&opy", $idCopy)
    _GUICtrlMenu_InsertMenuItem ($hEdit, 2, "&Paste", $idPaste)

    ; Create Help menu
    $hHelp = _GUICtrlMenu_CreateMenu ()
    _GUICtrlMenu_InsertMenuItem ($hHelp, 0, "&About", $idAbout)

    ; Create Main menu
    $hMain = _GUICtrlMenu_CreateMenu ()
    _GUICtrlMenu_InsertMenuItem ($hMain, 0, "&File", 0, $hFile)
    _GUICtrlMenu_InsertMenuItem ($hMain, 1, "&Edit", 0, $hEdit)
    _GUICtrlMenu_InsertMenuItem ($hMain, 2, "&Help", 0, $hHelp)

    ; Set window menu
    _GUICtrlMenu_SetMenu ($hGUI, $hMain)

    ; Create memo control
    $iMemo = GUICtrlCreateEdit("", 2, 2, 396, 276, 0)
    GUICtrlSetFont($iMemo, 9, 400, 0, "Courier New")
    GUISetState()

    ; Set New menu item to have a bitmap
    _GUICtrlMenu_SetItemBmp ($hFile, 0, _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap))
    MemoWrite("Item bitmap handle: 0x" & Hex(_GUICtrlMenu_GetItemBmp ($hFile, 0)))

    ; Loop until user exits
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
EndFunc ;==>_Main

; Write message to memo
Func MemoWrite($sMessage)
    GUICtrlSetData($iMemo, $sMessage & @CRLF, 1)
EndFunc ;==>MemoWrite

When I find a better way I will post it!

BR,

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Posted

Even though UEZ's method should work flawlessly, Yashied's function works as well. You've just used it incorrectly:

_GUICtrlMenu_SetItemBmp ($hMenu, 0, _CreateBitmapFromIcon(_WinAPI_GetSysColor($COLOR_MENU), @ScriptDir & '\favicon.ico', 0, 16, 16))

You've specified 43 as the index, but it should be 0 for .ico files.

Posted (edited)

This version is more elegant than from post #4:

#include <GDIPlus.au3>
#include <GuiMenu.au3>
#include <GuiConstantsEx.au3>
#include <WinAPI.au3>
#include <WinAPIEx.au3>
#include <WindowsConstants.au3>
#Include <Constants.au3>
Global $iMemo


$file = FileOpenDialog("Select ICO file", @ScriptDir, ("Icons (*.ico)"))

If @error Then Exit

$Ret = DllCall("shell32", "long", "ExtractAssociatedIcon", "int", 0, "str", $file, "int*", 0)
$hIcon = $Ret[0]

_GDIPlus_Startup()
$hImage = DllCall($ghGDIPDll,"int", "GdipCreateBitmapFromHICON", "ptr", $hIcon, "int*", 0)
$hImage = $hImage[2]
_WinAPI_DestroyIcon($hIcon)

$dest_x = 16
$dest_y = 16

$hBitmap = _GDIPlus_BitmapCreateFromScan0($dest_x, $dest_y)
$hContext = _GDIPlus_ImageGetGraphicsContext($hBitmap)
_GDIPlus_GraphicsDrawImageRect($hContext, $hImage, 0, 0, $dest_x, $dest_y)
$hIcon = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)

_Main()

_GDIPlus_GraphicsDispose($hContext)
_WinAPI_DeleteObject($hIcon)
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_Shutdown()

Exit


Func _Main()
    Local $hGUI, $hFile, $hEdit, $hHelp, $hMain
    Local Enum $idNew = 1000, $idOpen, $idSave, $idExit, $idCut, $idCopy, $idPaste, $idAbout

    ; Create GUI
    $hGUI = GUICreate("Menu", 400, 300)

    ; Create File menu
    $hFile = _GUICtrlMenu_CreateMenu ()
    _GUICtrlMenu_InsertMenuItem ($hFile, 0, "&New", $idNew)
    _GUICtrlMenu_InsertMenuItem ($hFile, 1, "&Open", $idOpen)
    _GUICtrlMenu_InsertMenuItem ($hFile, 2, "&Save", $idSave)
    _GUICtrlMenu_InsertMenuItem ($hFile, 3, "", 0)
    _GUICtrlMenu_InsertMenuItem ($hFile, 4, "E&xit", $idExit)

    ; Create Edit menu
    $hEdit = _GUICtrlMenu_CreateMenu ()
    _GUICtrlMenu_InsertMenuItem ($hEdit, 0, "&Cut", $idCut)
    _GUICtrlMenu_InsertMenuItem ($hEdit, 1, "C&opy", $idCopy)
    _GUICtrlMenu_InsertMenuItem ($hEdit, 2, "&Paste", $idPaste)

    ; Create Help menu
    $hHelp = _GUICtrlMenu_CreateMenu ()
    _GUICtrlMenu_InsertMenuItem ($hHelp, 0, "&About", $idAbout)

    ; Create Main menu
    $hMain = _GUICtrlMenu_CreateMenu ()
    _GUICtrlMenu_InsertMenuItem ($hMain, 0, "&File", 0, $hFile)
    _GUICtrlMenu_InsertMenuItem ($hMain, 1, "&Edit", 0, $hEdit)
    _GUICtrlMenu_InsertMenuItem ($hMain, 2, "&Help", 0, $hHelp)

    ; Set window menu
    _GUICtrlMenu_SetMenu ($hGUI, $hMain)

    ; Create memo control
    $iMemo = GUICtrlCreateEdit("", 2, 2, 396, 276, 0)
    GUICtrlSetFont($iMemo, 9, 400, 0, "Courier New")
    GUISetState()

    ; Set New menu item to have a bitmap
    _GUICtrlMenu_SetItemBmp ($hFile, 0, $hIcon)
    MemoWrite("Item bitmap handle: 0x" & Hex(_GUICtrlMenu_GetItemBmp ($hFile, 0)))

    ; Loop until user exits
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
EndFunc ;==>_Main

; Write message to memo
Func MemoWrite($sMessage)
    GUICtrlSetData($iMemo, $sMessage & @CRLF, 1)
EndFunc ;==>MemoWrite

Func _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight, $iStride = 0, $iPixelFormat = 0x0026200A, $pScan0 = 0)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iWidth, "int", $iHeight, "int", $iStride, "int", $iPixelFormat, "ptr", $pScan0, "int*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    $GDIP_STATUS = $aResult[0]
    Return $aResult[6]
EndFunc ;==>_GDIPlus_BitmapCreateFromScan0

BR,

UEZ

PS: transparent icons are not supported with this method!

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...