Jump to content

How to get a pointer to a bit array of Bitmap?


Recommended Posts

Who knows how to get a pointer to a bit array of Bitmap? "GetObject" function returns 0 (see following code).

:P

local $tIcon, $tID, $hIcon, $tIconInfo

; Get icon (shell32.dll, 0, 32x32)
$tIcon = DllStructCreate('hwnd')
$tID = DllStructCreate('hwnd')
DllCall('user32.dll', 'int', 'PrivateExtractIcons', 'str', 'shell32.dll', 'int', 0, 'int', 32, 'int', 32, 'ptr', DllStructGetPtr($tIcon), 'ptr', DllStructGetPtr($tID), 'int', 1, 'int', 0)
$hIcon = DllStructGetData($tIcon, 1)

; Get icon info
$tIconInfo = DllStructCreate('byte fIcon;dword xHotspot;dword yHotspot;ptr hbmMask;ptr hbmColor')
DllCall('user32.dll', 'int', 'GetIconInfo', 'hwnd', $hIcon, 'ptr', DllStructGetPtr($tIconInfo))

; Get bitmap info
$tBitmap = DllStructCreate('long bmType;long bmWidth;long bmHeight;long bmWidthBytes;ushort bmPlanes;ushort bmBitsPixel;ptr bmBits')
DllCall('gdi32.dll', 'int', 'GetObject', 'int', DllStructGetData($tIconInfo, 'hbmColor'), 'int', DllStructGetSize($tBitmap), 'ptr', DllStructGetPtr($tBitmap))

; Pointer to the location of the bit values for the bitmap (0x00000000 - ???)
MsgBox(0, '', DllStructGetData($tBitmap, 'bmBits'))
Link to comment
Share on other sites

Why is my code, the icon is present, but the pointer is 0?

:P

I looked at this and I think that your Bitmap struct is wrong. It looks like you should be passing a pointer to a lpvObject which has had the second element HBITMAP already set to the value returned from a call to CreateDIBSection.
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

I looked at this and I think that your Bitmap struct is wrong. It looks like you should be passing a pointer to a lpvObject which has had the second element HBITMAP already set to the value returned from a call to CreateDIBSection.

That looks like chasing tail.

I rewrote Yashied's code a little:

#include <Constants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>

; create gui and pic control
GUICreate("Test GUI", 400, 140, -1, -1, $WS_SIZEBOX)
$hPic = GUICtrlCreatePic("", 10, 30, 0, 0)

; load library
$hInstance = _WinAPI_LoadLibraryEx("explorer.exe", $LOAD_LIBRARY_AS_DATAFILE)

; load bitmap
$hBitmap = _WinAPI_LoadImage($hInstance, 146, $IMAGE_BITMAP, 0, 0, 0)

; get desired informations
$iRet = _WinAPI_GetObject($hBitmap, 0, 0)
ConsoleWrite("! " & $iRet & @CRLF) ; The size of the structure that is to be filled. Should be 24.

$tBitmap = DllStructCreate("int bmType;" & _
        "int bmWidth;" & _
        "int bmHeight;" & _
        "int bmWidthBytes;" & _
        "ushort bmPlanes;" & _
        "ushort bmBitsPixel;" & _
        "ptr bmBits")

$iRet = _WinAPI_GetObject($hBitmap, DllStructGetSize($tBitmap), DllStructGetPtr($tBitmap))

ConsoleWrite($iRet & @CRLF) ; Number of bytes stored in $tBitmap structure.
ConsoleWrite("Type " & DllStructGetData($tBitmap, "bmType") & @CRLF)
ConsoleWrite("Width: " & DllStructGetData($tBitmap, "bmWidth") & @CRLF)
ConsoleWrite("Height: " & DllStructGetData($tBitmap, "bmHeight") & @CRLF)
ConsoleWrite("WidthBytes: " & DllStructGetData($tBitmap, "bmWidthBytes") & @CRLF)
ConsoleWrite("Planes: " & DllStructGetData($tBitmap, "bmPlanes") & @CRLF)
ConsoleWrite("BitsPixel: " & DllStructGetData($tBitmap, "bmBitsPixel") & @CRLF)
ConsoleWrite("Bits: " & DllStructGetData($tBitmap, "bmBits") & @CRLF)


; resize pic control 
GUICtrlSetPos($hPic, 10, 30, DllStructGetData($tBitmap, "bmWidth"), DllStructGetData($tBitmap, "bmHeight"))

; draw bitmap
$STM_SETIMAGE = 370
$iMsg = GUICtrlSendMsg($hPic, $STM_SETIMAGE, 0, $hBitmap)

; clean if necessary
If $iMsg Then ; this won't be the case since it's done only once
    _WinAPI_DeleteObject($iMsg)
EndIf

; show GUI
GUISetState()

While 1
    If GUIGetMsg() = $GUI_EVENT_CLOSE Then Exit
WEnd

It's basically the same thing and again there is no pointer to bit values.

All other stuff is there but not that one. Obviously this is not right method to gain that data.

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

Who knows how to get a pointer to a bit array of Bitmap? "GetObject" function returns 0 (see following code).

:P

local $tIcon, $tID, $hIcon, $tIconInfo

; Get icon (shell32.dll, 0, 32x32)
$tIcon = DllStructCreate('hwnd')
$tID = DllStructCreate('hwnd')
DllCall('user32.dll', 'int', 'PrivateExtractIcons', 'str', 'shell32.dll', 'int', 0, 'int', 32, 'int', 32, 'ptr', DllStructGetPtr($tIcon), 'ptr', DllStructGetPtr($tID), 'int', 1, 'int', 0)
$hIcon = DllStructGetData($tIcon, 1)

; Get icon info
$tIconInfo = DllStructCreate('byte fIcon;dword xHotspot;dword yHotspot;ptr hbmMask;ptr hbmColor')
DllCall('user32.dll', 'int', 'GetIconInfo', 'hwnd', $hIcon, 'ptr', DllStructGetPtr($tIconInfo))

; Get bitmap info
$tBitmap = DllStructCreate('long bmType;long bmWidth;long bmHeight;long bmWidthBytes;ushort bmPlanes;ushort bmBitsPixel;ptr bmBits')
DllCall('gdi32.dll', 'int', 'GetObject', 'int', DllStructGetData($tIconInfo, 'hbmColor'), 'int', DllStructGetSize($tBitmap), 'ptr', DllStructGetPtr($tBitmap))

; Pointer to the location of the bit values for the bitmap (0x00000000 - ???)
MsgBox(0, '', DllStructGetData($tBitmap, 'bmBits'))

صرح السماء كان هنا

 

Link to comment
Share on other sites

#include <Constants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
#include <WinAPI.au3>


; create gui and pic control
GUICreate("Test GUI", 400, 140, -1, -1, $WS_SIZEBOX)
$hPic1 = GUICtrlCreatePic("", 10, 30, 0, 0)
$hPic2 = GUICtrlCreatePic("", 60, 30, 0, 0)

; Initialize GDI+ library
_GDIPlus_Startup()

; Get icon (shell32.dll, 0, 32x32)
$tIcon = DllStructCreate('hwnd')
$tID = DllStructCreate('hwnd')
DllCall('user32.dll', 'int', 'PrivateExtractIcons', 'str', @SystemDir & "\shell32.dll", 'int', 130, _
'int', 32, 'int', 32, 'ptr', DllStructGetPtr($tIcon), 'ptr', DllStructGetPtr($tID), 'int', 1, 'int', 0)
$hIcon = DllStructGetData($tIcon, 1)


;Two methods
; Get bitmap handle to icon

;1
$tIconInfo = DllStructCreate("int fIcon;int xHotspot;int yHotspot;long hbmMask;long hbmColor")
DllCall('user32.dll', 'int', 'GetIconInfo', 'hwnd', $hIcon, 'ptr', DllStructGetPtr($tIconInfo))
$hBitmap = DllStructGetData($tIconInfo, 'hbmColor')

Local $hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)
_WinAPI_DeleteObject ($hBitmap)
$hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap ($hImage)
_GetBitmapInfo($hBitmap, $hPic1, 10, 30)
_GDIPlus_ImageDispose($hImage)
_WinAPI_DeleteObject ($hBitmap)

;2
$hImage = DllCall($ghGDIPDll, "int", "GdipCreateBitmapFromHICON", "hWnd", $hIcon, "int*", 0)
$hImage = $hImage[2]
$hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap ($hImage)
_GetBitmapInfo($hBitmap, $hPic2, 60, 30)
_GDIPlus_ImageDispose($hImage)
_WinAPI_DeleteObject ($hBitmap)
_WinAPI_DestroyIcon($hIcon)


; Shut down GDI+ library
_GDIPlus_Shutdown()

; show GUI
GUISetState()

While 1
    If GUIGetMsg() = $GUI_EVENT_CLOSE Then Exit
WEnd


Func _GetBitmapInfo($hBitmap, $hPic, $X, $Y)
    ; get desired informations
    Local $iRet = _WinAPI_GetObject($hBitmap, 0, 0)
    ConsoleWrite("! " & $iRet & @CRLF) ; The size of the structure that is to be filled. Should be 24.

    Local $tBitmap = DllStructCreate("int bmType;" & _
            "int bmWidth;" & _
            "int bmHeight;" & _
            "int bmWidthBytes;" & _
            "ushort bmPlanes;" & _
            "ushort bmBitsPixel;" & _
            "ptr bmBits")

    $iRet = _WinAPI_GetObject($hBitmap, DllStructGetSize($tBitmap), DllStructGetPtr($tBitmap))

    ConsoleWrite($iRet & @CRLF) ; Number of bytes stored in $tBitmap structure.
    ConsoleWrite("Type " & DllStructGetData($tBitmap, "bmType") & @CRLF)
    ConsoleWrite("Width: " & DllStructGetData($tBitmap, "bmWidth") & @CRLF)
    ConsoleWrite("Height: " & DllStructGetData($tBitmap, "bmHeight") & @CRLF)
    ConsoleWrite("WidthBytes: " & DllStructGetData($tBitmap, "bmWidthBytes") & @CRLF)
    ConsoleWrite("Planes: " & DllStructGetData($tBitmap, "bmPlanes") & @CRLF)
    ConsoleWrite("BitsPixel: " & DllStructGetData($tBitmap, "bmBitsPixel") & @CRLF)
    ConsoleWrite("Bits: " & DllStructGetData($tBitmap, "bmBits") & @CRLF & @CRLF)

    ; resize pic control
    GUICtrlSetPos($hPic, $X, $Y, DllStructGetData($tBitmap, "bmWidth"), DllStructGetData($tBitmap, "bmHeight"))
    ; draw bitmap
    $STM_SETIMAGE = 370
    $iMsg = GUICtrlSendMsg($hPic, $STM_SETIMAGE, 0, $hBitmap)
    ; clean if necessary
    If $iMsg Then ; this won't be the case since it's done only once
        _WinAPI_DeleteObject($iMsg)
    EndIf
EndFunc

I see fascists...

Link to comment
Share on other sites

Gdip to the rescue.

Any ideas about gdip free version. What makes the difference in those two hBitmaps?

Hi trancexx

What makes the difference in those two hBitmaps?

I'm not a graphics expert.

certainly something going on with the black mask quality of the icon in the second GDI+ example, but don't ask me what.

the second GDI+ example just wraps two functions into one.

if you don't need the other info or mask bitmap from GetIconInfo

Any ideas about gdip free version.

as for a non GDI+ version, I remembered using an API ProgAndy translated to make a GDI compatible hbitmap.

found it: _GDIPlus_ImageCreateGDICompatibleHBITMAP($hImg)

it uses CopyImage API

I'll post it, but it looks like Yashied has moved on.

;non GDI+ method using CopyImage

#include <Constants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>

; create gui and pic control
GUICreate("Test GUI", 400, 140)
$hPic = GUICtrlCreatePic("", 10, 30, 0, 0)

; Get icon (shell32.dll, 0, 32x32)
$tIcon = DllStructCreate('hwnd')
$tID = DllStructCreate('hwnd')
DllCall('user32.dll', 'int', 'PrivateExtractIcons', 'str', @SystemDir & "\shell32.dll", 'int', 130, _
'int', 32, 'int', 32, 'ptr', DllStructGetPtr($tIcon), 'ptr', DllStructGetPtr($tID), 'int', 1, 'int', 0)
$hIcon = DllStructGetData($tIcon, 1)

$tIconInfo = DllStructCreate("int fIcon;int xHotspot;int yHotspot;long hbmMask;long hbmColor")
DllCall('user32.dll', 'int', 'GetIconInfo', 'hwnd', $hIcon, 'ptr', DllStructGetPtr($tIconInfo))
$hBitmap = DllStructGetData($tIconInfo, 'hbmColor')

$hBitmap = _WinAPI_CopyImage($hBitmap, 0, 0, 0, $LR_COPYDELETEORG + $LR_COPYRETURNORG + $LR_CREATEDIBSECTION)
;_WinAPI_DeleteObject ($hBitmap) ; original bitmap deleted because of $LR_COPYDELETEORG flag

_GetBitmapInfo($hBitmap, $hPic, 10, 30)
_WinAPI_DeleteObject ($hBitmap)

; show GUI
GUISetState()

While 1
    If GUIGetMsg() = $GUI_EVENT_CLOSE Then Exit
WEnd


; Description::    Copies an image, also makes GDIPlus-HBITMAP to GDI32-BITMAP
; Parameter(s):    $hImg -> HBITMAP Object, GDI or GDIPlus
; Requirement(s):  WinAPI.au3
; Return Value(s): Succes: Handle to new Bitmap, Error: 0
; Author(s):       Prog@ndy
Func _WinAPI_CopyImage($hImg, $uType = 0, $x = 0, $y = 0, $flags = 0)
    Local $aResult
    $aResult = DllCall("User32.dll", "hwnd", "CopyImage", "hwnd", $hImg, _
            "UINT", $uType, "int", $x, "int", $y, "UINT", $flags)
    _WinAPI_Check("_WinAPI_CopyImage", ($aResult[0] = 0), 0, True)
    Return $aResult[0]
EndFunc   ;==>_WinAPI_CopyImage


Func _GetBitmapInfo($hBitmap, $hPic, $X, $Y)
    ; get desired informations
    Local $iRet = _WinAPI_GetObject($hBitmap, 0, 0)
    ConsoleWrite("! " & $iRet & @CRLF) ; The size of the structure that is to be filled. Should be 24.

    Local $tBitmap = DllStructCreate("int bmType;" & _
            "int bmWidth;" & _
            "int bmHeight;" & _
            "int bmWidthBytes;" & _
            "ushort bmPlanes;" & _
            "ushort bmBitsPixel;" & _
            "ptr bmBits")

    $iRet = _WinAPI_GetObject($hBitmap, DllStructGetSize($tBitmap), DllStructGetPtr($tBitmap))

    ConsoleWrite($iRet & @CRLF) ; Number of bytes stored in $tBitmap structure.
    ConsoleWrite("Type " & DllStructGetData($tBitmap, "bmType") & @CRLF)
    ConsoleWrite("Width: " & DllStructGetData($tBitmap, "bmWidth") & @CRLF)
    ConsoleWrite("Height: " & DllStructGetData($tBitmap, "bmHeight") & @CRLF)
    ConsoleWrite("WidthBytes: " & DllStructGetData($tBitmap, "bmWidthBytes") & @CRLF)
    ConsoleWrite("Planes: " & DllStructGetData($tBitmap, "bmPlanes") & @CRLF)
    ConsoleWrite("BitsPixel: " & DllStructGetData($tBitmap, "bmBitsPixel") & @CRLF)
    ConsoleWrite("Bits: " & DllStructGetData($tBitmap, "bmBits") & @CRLF & @CRLF)

    ; resize pic control
    GUICtrlSetPos($hPic, $X, $Y, DllStructGetData($tBitmap, "bmWidth"), DllStructGetData($tBitmap, "bmHeight"))
    ; draw bitmap
    $STM_SETIMAGE = 370
    $iMsg = GUICtrlSendMsg($hPic, $STM_SETIMAGE, 0, $hBitmap)
    ; clean if necessary
    If $iMsg Then ; this won't be the case since it's done only once
        _WinAPI_DeleteObject($iMsg)
    EndIf

EndFunc

I see fascists...

Link to comment
Share on other sites

as for a non GDI+ version, I remembered using an API ProgAndy translated to make a GDI compatible hbitmap.

found it: _GDIPlus_ImageCreateGDICompatibleHBITMAP($hImg)

it uses CopyImage API

I'll post it, but it looks like Yashied has moved on.

This is exelent example and exelent solve, rover. Many thanks for you.

:D

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