Autor Tema: Extract PNG and ICO from resource DLL  (Leído 10612 veces)

0 Usuarios y 1 Visitante están viendo este tema.

cliv

  • Kilobyte
  • **
  • Mensajes: 69
  • Reputación: +1/-2
    • Ver Perfil
Extract PNG and ICO from resource DLL
« en: Febrero 15, 2011, 04:15:34 am »
I want to display PNG or ICO extracted from a resouce dll file...but i don't know how
Can someone post a sample how to do that..????

I made a DLL witch contain PNG an ICO in various format and i load here:
http://www.mediafire.com/?a13wcw41sczqexy

How can i extract image ..
Please help

bebekbdg

  • Bytes
  • *
  • Mensajes: 15
  • Reputación: +0/-0
    • Ver Perfil
Re:Extract PNG and ICO from resource DLL
« Respuesta #1 en: Febrero 15, 2011, 07:28:27 am »

cliv

  • Kilobyte
  • **
  • Mensajes: 69
  • Reputación: +1/-2
    • Ver Perfil
Re:Extract PNG and ICO from resource DLL
« Respuesta #2 en: Febrero 15, 2011, 09:15:54 am »
Thank you for reply
I use Cobein program Extract Icons from resource dll atached on first post but i can see all "icon-PNG" ...
Only one display..????


raul338

  • Terabyte
  • *****
  • Mensajes: 894
  • Reputación: +62/-8
  • xD fan!!!!! xD
    • Ver Perfil
    • Raul's Weblog
Re:Extract PNG and ICO from resource DLL
« Respuesta #3 en: Febrero 15, 2011, 09:33:16 am »
Maybe you can use the back code of
AlphaIcon32
and
ucImage & ucImageList

cliv

  • Kilobyte
  • **
  • Mensajes: 69
  • Reputación: +1/-2
    • Ver Perfil
Re:Extract PNG and ICO from resource DLL
« Respuesta #4 en: Febrero 15, 2011, 10:56:25 am »
It's too complicate for me... :(
« última modificación: Febrero 15, 2011, 04:43:43 pm por xkiz ™ »

raul338

  • Terabyte
  • *****
  • Mensajes: 894
  • Reputación: +62/-8
  • xD fan!!!!! xD
    • Ver Perfil
    • Raul's Weblog
Re:Extract PNG and ICO from resource DLL
« Respuesta #5 en: Febrero 15, 2011, 12:38:31 pm »
It never be just too simple xD, just check the code, make a mutant project by copy and paste, look for MSDN to get certain info. And it will be ready  :o

LeandroA

  • Administrador
  • Petabyte
  • *****
  • Mensajes: 1128
  • Reputación: +151/-8
    • Ver Perfil
Re:Extract PNG and ICO from resource DLL
« Respuesta #6 en: Febrero 15, 2011, 10:47:47 pm »
hello, the dll resource is bad constructed, you should place an icon in each resource, not to put all the icons in the same icon

me cuesta explicarlo en ingles pero lo que esta haciendo es poner un grupo de iconos con diferentes imagenes no varios iconos.

then you can use the api ExtractIcon

Código: [Seleccionar]
Option Explicit
Private Declare Function DrawIcon Lib "user32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal hIcon As Long) As Long
Private Declare Function ExtractIcon Lib "shell32.dll" Alias "ExtractIconA" (ByVal hInst As Long, ByVal lpszExeFileName As String, ByVal nIconIndex As Long) As Long
Private Declare Function DestroyIcon Lib "user32.dll" (ByVal hIcon As Long) As Long


Private Sub Form_Load()
    Dim hIcon As Long
    Dim sPath As String
   
    Me.AutoRedraw = True

    sPath = "C:\Documents and Settings\Administrador\Escritorio\ResourceDLL\ResourceDLL.dll"
    hIcon = ExtractIcon(0&, sPath, 0) 'First Icon
    Call DrawIcon(Me.hdc, 0, 0, hIcon)
    DestroyIcon hIcon
   
    hIcon = ExtractIcon(0&, sPath, 1) 'Second Icon
    Call DrawIcon(Me.hdc, 0, 0, hIcon)
    DestroyIcon hIcon
   
End Sub

Related apis
LoadLibrary
LoadIcon
LoadImage
GdipLoadImageFromStream  <--- png Resource (advanced)
EnumResourceNames
LoadResource



cliv

  • Kilobyte
  • **
  • Mensajes: 69
  • Reputación: +1/-2
    • Ver Perfil
Re:Extract PNG and ICO from resource DLL
« Respuesta #7 en: Febrero 16, 2011, 06:22:26 am »
hello, the dll resource is bad constructed, you should place an icon in each resource, not to put all the icons in the same icon

Thank you Leandro...I rebuild resource.dll here is sample and resource:
http://www.mediafire.com/?c5gm08b11unr0t7
...now contain 32x32,48x48,64x64 icon( 256 and True Color) and PNG file.

BUT HOW CAN I DISPLAY 48x48,64x64 ICON WITH TRUE COLOR ... AND PNG ...??
« última modificación: Febrero 16, 2011, 09:14:42 am por cliv »

TheWatcher

  • Bytes
  • *
  • Mensajes: 16
  • Reputación: +2/-0
    • Ver Perfil
Re:Extract PNG and ICO from resource DLL
« Respuesta #8 en: Febrero 16, 2011, 02:28:51 pm »
Hi cliv,

1. The problem with your dll still persists. You are evidently using the VB6 resource compiler or some simple analog to compile your icons under string names rather than under ordinal number identifiers. This is why the Windows API functions fail to load them correctly when the usual "#X" (X is the icon's ordinal number) string is passed as the resource identifier. You must use the resources' explicit string names for the functions to behave correctly with your dll.

2. The ExtractIcon and DrawIcon APIs are bound to the system's SM_CXICON and SM_CYICON metric values for icons and will not let you draw the icon's image to an arbitrary size including its original size without distortion if it (I mean "size") does not correspond to the system metric settings. To bypass this limitation, you'll have to use a couple of slightly more advanced API functions:
Código: [Seleccionar]
Option Explicit
Private Declare Function LoadLibrary Lib "kernel32.dll" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
Private Declare Function LoadImage Lib "user32" Alias "LoadImageA" (ByVal hinst As Long, ByVal lpszName As String, ByVal uType As Long, ByVal cxDesired As Long, ByVal cyDesired As Long, ByVal fuLoad As Long) As Long
Private Declare Function DrawIconEx Lib "user32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal hIcon As Long, ByVal cxWidth As Long, ByVal cyWidth As Long, ByVal istepIfAniCur As Long, ByVal hbrFlickerFreeDraw As Long, ByVal diFlags As Long) As Long
Private Declare Function DestroyIcon Lib "user32.dll" (ByVal hIcon As Long) As Long

Private Const IMAGE_ICON = 1
Private Const DI_NORMAL = &H3

Private Sub Form_Load()
    Dim hIcon As Long
    Dim hLib As Long
   
    Me.AutoRedraw = True

    hLib = LoadLibrary("Resurse.dll")
   
    hIcon = LoadImage(hLib, "ICON_0", IMAGE_ICON, 0, 0, 0)
    Call DrawIconEx(Me.hdc, 0, 0, hIcon, 32, 32, 0, 0, DI_NORMAL)
    DestroyIcon hIcon
   
    hIcon = LoadImage(hLib, "ICON_1", IMAGE_ICON, 0, 0, 0)
    Call DrawIconEx(Me.hdc, 34, 0, hIcon, 32, 32, 0, 0, DI_NORMAL)
    DestroyIcon hIcon
   
    hIcon = LoadImage(hLib, "ICON_2", IMAGE_ICON, 0, 0, 0)
    Call DrawIconEx(Me.hdc, 68, 0, hIcon, 32, 32, 0, 0, DI_NORMAL)
    DestroyIcon hIcon

    hIcon = LoadImage(hLib, "ICON_7", IMAGE_ICON, 0, 0, 0)
    Call DrawIconEx(Me.hdc, 102, 0, hIcon, 48, 48, 0, 0, DI_NORMAL)
    DestroyIcon hIcon

    hIcon = LoadImage(hLib, "ICON_8", IMAGE_ICON, 0, 0, 0)
    Call DrawIconEx(Me.hdc, 152, 0, hIcon, 48, 48, 0, 0, DI_NORMAL)
    DestroyIcon hIcon

    hIcon = LoadImage(hLib, "ICON_9", IMAGE_ICON, 0, 0, 0)
    Call DrawIconEx(Me.hdc, 202, 0, hIcon, 64, 64, 0, 0, DI_NORMAL)
    DestroyIcon hIcon

    hIcon = LoadImage(hLib, "ICON_10", IMAGE_ICON, 0, 0, 0)
    Call DrawIconEx(Me.hdc, 0, 64, hIcon, 64, 64, 0, 0, DI_NORMAL)
    DestroyIcon hIcon

End Sub

3. The above code enumerates all the images in your dll that can be drawn without distortion to their native sizes using simple Windows APIs. If you want to display Vista and 7 icons which are not true icons but rather transparent PNG images, you will have to use GDI+ APIs instead. But I think that can be left for you as your home exercise... :)

Mike Lobanovsky
« última modificación: Febrero 16, 2011, 02:46:35 pm por TheWatcher »

cliv

  • Kilobyte
  • **
  • Mensajes: 69
  • Reputación: +1/-2
    • Ver Perfil
Re:Extract PNG and ICO from resource DLL
« Respuesta #9 en: Febrero 17, 2011, 03:00:24 am »
I use Resource builder ...

Thank you for clarification....
It seem like LaVolpe Icon Organizer/Extractor from here:
http://www.vbforums.com/showthread.php?t=596560
is exactly what i want ( I need to display PNG file extracted from external resource dll on a form in WinXP,Vista,Win7)...But code is complex for me...I need a small sample code to do this (extract PNG or ICO and display)
« última modificación: Febrero 17, 2011, 04:58:51 am por cliv »

TheWatcher

  • Bytes
  • *
  • Mensajes: 16
  • Reputación: +2/-0
    • Ver Perfil
Re:Extract PNG and ICO from resource DLL
« Respuesta #10 en: Febrero 17, 2011, 09:42:22 am »
Cliv,

La Volpe's code is excellent, and this man has spent countless years fiddling with images of all sorts, and his product is the essence of his rich experience in this area. Two thirds of his Icon Resource Organizer are dedicated exactly to what you are asking here for -- to just load the icon and display it, however simple it may sound -- and only one third of it concerns ways to convert the icon to another format, which is not what you intend to do, at least at this stage of your progress.

Do you think that if loading and displaying icons correctly were a simple matter of two or three lines of code, La Volpe would have masochistically bloated it up to 200KB on some evil purpose of making things harder for you, me, or anybody else? Definitely no. His code is the absolute minimum required to resolve the tasks which he has formulated when starting to develop his project.

So, now you know how to load and display simpler icon formats using simple Windows API's provided that you know the exact icon names and/or ordinal identifiers and their original sizes, and IMHO this is already a great leap forward compared to what you knew when you launched this thread. Your next step should be to study ways of how to extract this data from a 3rd-party executable whose contents is Pandora's box, especially if it is as crooked as the dll which you use in your example. This data resides in the group icon structure of your dll. Google for smaller bits of knowledge over the net, study simple icon formats, file and image headers, etc. and develop this simple example above so that it can handle these simple tasks automatically.

No sooner than you can do it with simple icon formats within any executables you can get hold of, should you proceed to more advanced topics like PNG-based Vista "icons".

Forums are meant for helping you resolve lesser issues in your existing projects and not for someone developing your projects for youself instead of your own self. There's another great thing by La Volpe besides his great VB code that is very relevant in this case: HitchHiker's Guide to Getting Help on the Forums. Please make it your everyday reference too... :)

LeandroA

  • Administrador
  • Petabyte
  • *****
  • Mensajes: 1128
  • Reputación: +151/-8
    • Ver Perfil
Re:Extract PNG and ICO from resource DLL
« Respuesta #11 en: Febrero 17, 2011, 08:45:08 pm »
Hi, I have the same thought as TheWatcher, first of all you to read a PNG from a dll need to extract the resource to that dll

First, I assume you are referring to images .PNG and not a Vista-like icons which have a png image in the same icon

Here are two functions for extracting resources from a dll, the first is the name of the resource (this may have the name a word or a number if a number you should call for #101 for example

The second function reads the resource sequence, Example (0 is the first imagen.png, 1 is the second imagen.png), but note that this function is slower than the first
Código: [Seleccionar]
Option Explicit

Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
Private Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long
Private Declare Function LoadResource Lib "kernel32" (ByVal hInstance As Long, ByVal hResInfo As Long) As Long
Private Declare Function LockResource Lib "kernel32" (ByVal hResData As Long) As Long
Private Declare Function SizeofResource Lib "kernel32" (ByVal hInstance As Long, ByVal hResInfo As Long) As Long
Private Declare Function EnumResourceNames Lib "kernel32" Alias "EnumResourceNamesA" (ByVal hModule As Long, ByVal lpType As String, ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Private Declare Function FreeResource Lib "kernel32" (ByVal hResData As Long) As Long
Private Declare Function FindResource Lib "kernel32" Alias "FindResourceA" (ByVal hInstance As Long, ByVal lpName As String, ByVal lpType As String) As Long
Private Declare Function FindResourceByNum Lib "kernel32" Alias "FindResourceA" (ByVal hInstance As Long, ByVal lpName As String, ByVal lpType As Long) As Long
Private Declare Function StrLen Lib "kernel32" Alias "lstrlenA" (ByVal lpString As Long) As Long
Private Declare Function StrCpy Lib "kernel32" Alias "lstrcpyA" (ByVal lpString1 As String, ByVal lpString2 As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

Dim ArrResource() As String

'Quick Function
Public Function LoadResourceByName(ByVal sLibName As String, ByVal ResType As String, ByVal ResName As Variant, btBuff() As Byte) As Boolean
    Dim hRsrc As Long
    Dim hGlobal As Long
    Dim arrData() As Byte
    Dim lpData As Long
    Dim arrSize As Long
    Dim hLibrary As Long
   
    hLibrary = LoadLibrary(sLibName)
   
    If hLibrary <> 0 Then
   
        If IsNumeric(ResType) Then
             hRsrc = FindResourceByNum(hLibrary, ResName, CLng(ResType))
        Else
             hRsrc = FindResource(hLibrary, ResName, ResType)
        End If

        If hRsrc <> 0 Then

            hGlobal = LoadResource(hLibrary, hRsrc)
           
            If hGlobal <> 0 Then
                lpData = LockResource(hGlobal)
               
                If lpData <> 0 Then
                    arrSize = SizeofResource(hLibrary, hRsrc)
       
                    If arrSize > 0 Then
                         ReDim btBuff(arrSize - 1)
                         Call CopyMemory(btBuff(0), ByVal lpData, arrSize)
                         LoadResourceByName = True
                    End If
                End If
       
                Call FreeResource(hGlobal)
            End If

        End If
       
        Call FreeLibrary(hLibrary)
       
    End If
End Function

'Slow Function
Public Function LoadResourceByOrdinal(ByVal sLibName As String, ByVal ResType As String, ByVal Ordinal As Long, btBuff() As Byte) As Boolean
    Dim lCount As Long
    Dim hLibrary As Long
    ReDim ArrResource(0)
   
    hLibrary = LoadLibrary(sLibName)
    If hLibrary <> 0 Then
        Call EnumResourceNames(hLibrary, ResType, AddressOf ResNamesCallBack, 0)
        lCount = UBound(ArrResource)
        If lCount > 0 Then
            If Ordinal >= 0 And Ordinal < lCount Then
                LoadResourceByOrdinal = LoadResourceByName(sLibName, ResType, ArrResource(Ordinal), btBuff)
            End If
        End If
    End If
    Erase ArrResource
   
End Function

Private Function PtrToVBString(ByVal lpszBuffer As Long) As String
    Dim Buffer As String, LenBuffer As Long
    LenBuffer = StrLen(lpszBuffer)
    Buffer = String(LenBuffer + 1, 0)
    StrCpy Buffer, lpszBuffer
    PtrToVBString = Left(Buffer, LenBuffer)
End Function


Private Function ResNamesCallBack(ByVal hMod As Long, ByVal ResType As Long, ByVal ResId As Long, ByVal lParam As Long) As Long

    If (ResId > &HFFFF&) Or (ResId < 0) Then
        ArrResource(UBound(ArrResource)) = PtrToVBString(ResId)
    Else
        ArrResource(UBound(ArrResource)) = "#" & ResId
    End If

    ReDim Preserve ArrResource(UBound(ArrResource) + 1)
    ResNamesCallBack = True
   
End Function

then add an image. png in the dll with the name "IMAGEN_PNG1"and another named "100"

Test
Código: [Seleccionar]
Option Explicit

Private Sub Command1_Click()
    Dim BitArray() As Byte
    Debug.Print LoadResourceByName(App.Path & "\Resurse.dll", "PNG", "IMAGEN_PNG1", BitArray) 'String Name
    Debug.Print LoadResourceByName(App.Path & "\Resurse.dll", "PNG", "#100", BitArray) 'Numeric Name
   
    '-----------
   
    Debug.Print LoadResourceByOrdinal(App.Path & "\Resurse.dll", "PNG", 0, BitArray) 'First PNG
    Debug.Print LoadResourceByOrdinal(App.Path & "\Resurse.dll", "PNG", 1, BitArray) 'Second PNG
End Sub


these functions we get the array of bits of the image, so you just have to replace some lines in your function.

Código: [Seleccionar]
Public Function DrawDllPNG(ByVal lHDC As Long, ByVal sFilePath As String, ByVal sResType As String, ByVal sResName As String, _
                      Optional ByVal X As Long, Optional ByVal Y As Long, _
                      Optional ByVal lWidth As Long, Optional ByVal lHeight As Long) As Boolean


    Dim uInput As GdiplusStartupInput
    Dim hToken As Long
    Dim hGraphics As Long
    Dim buff() As Byte
    Dim Stream As Object
    Dim hImg As Long
 
 
    uInput.GdiplusVersion = 1
    If GdiplusStartup(hToken, uInput) = ok Then

        'I'm Elected this function
        If LoadResourceByName(sFilePath, sResType, sResName, buff) Then
         
            CreateStreamOnHGlobal buff(0), False, Stream
           
            If Not Stream Is Nothing Then
                If GdipLoadImageFromStream(Stream, hImg) = ok Then
       
                    If (lWidth = 0) Or (lHeight = 0) Then
                        GdipGetImageHeight hImg, lHeight
                        GdipGetImageWidth hImg, lWidth
                    End If
       
                    If GdipCreateFromHDC(lHDC, hGraphics) = ok Then
                        If GdipDrawImageRect(hGraphics, hImg, X, Y, lWidth, lHeight) = ok Then
                            DrawDllPNG = True
                        End If
                        GdipDeleteGraphics hGraphics
                    End If
                       
                    GdipDisposeImage hImg
                End If
            End If
        End If
       
        GdiplusShutdown hToken
    End If

End Function

Código: [Seleccionar]
    Me.Cls
    Call DrawDllPNG(Me.HDC, App.Path & "\Resurse.dll", "PNG", "IMAGEN_PNG1", 350, 150, 96, 96)
    Me.Refresh

for the icons you can use the LoadImage api or you can adapt this method
http://www.leandroascierto.com.ar/foro/index.php?topic=37.0
« última modificación: Febrero 17, 2011, 09:18:18 pm por LeandroA »

cliv

  • Kilobyte
  • **
  • Mensajes: 69
  • Reputación: +1/-2
    • Ver Perfil
Re:Extract PNG and ICO from resource DLL
« Respuesta #12 en: Febrero 18, 2011, 03:53:13 am »
Thank you TheWatcher .... but I never intention to someone develop my application for me...


Thank you Leandro you have allways a solution...
...but your code not work for me...see here:
http://www.mediafire.com/?o05l5u3zhu13diw
I do something wrong....but what..???
« última modificación: Febrero 18, 2011, 04:32:32 am por cliv »

TheWatcher

  • Bytes
  • *
  • Mensajes: 16
  • Reputación: +2/-0
    • Ver Perfil
Re:Extract PNG and ICO from resource DLL
« Respuesta #13 en: Febrero 18, 2011, 04:32:20 am »
He-he, thanks for your help Leandro, :)

Seems like Cliv won't need to search the net for the missing pieces of knowledge this time because they are all already here, cleaned, parceled and posted at no extra charge! :D

Respect and cheers, :)

Mike Lobanovsky

TheWatcher

  • Bytes
  • *
  • Mensajes: 16
  • Reputación: +2/-0
    • Ver Perfil
Re:Extract PNG and ICO from resource DLL
« Respuesta #14 en: Febrero 18, 2011, 07:15:07 am »
Hi again cliv,

Exactly what you are doing wrong is that Leandro's code is for separate PNG image resources and not for Vista icons in PNG format:
... I assume you are referring to images .PNG and not a Vista-like icons which have a png image in the same icon ...

But ignoring this, you've again added your two new PNG images like two extra icons into your Resurse.dll. Please do not misinterpret these two distinctly different resource types next time you compile your dynamic link libraries. In case you don't know how to exploit resources in 3rd-party executables, here's a couple of useful links to the software that can help:

http://www.heaventools.com/
http://www.softpedia.com/get/Programming/File-Editors/Resource-Hacker.shtml

In the meantime, please have your project and your dll corrected to use Leandro's code to load your PNG images from a dll both by name and by ordinal identifiers HERE.

By the way, what prevents you now from also adding code to display true icons with sizes larger than 32x32? You already have all the code explained in the above examples. It will never be a simple copy-and-paste matter but rather a trial-and-error one. Otherwise I am afraid it is exactly what I call developing projects for someone instead of his own self for free. ;)

Mike Lobanovsky :)
« última modificación: Febrero 18, 2011, 07:24:06 am por TheWatcher »