Jump to content

_CreateBitmapFromIcon


Rawox
 Share

Recommended Posts

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

Link to comment
Share on other sites

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

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
 Share

  • Recently Browsing   0 members

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