Visual Basic Foro
Programación => Visual Basic 6 => Mensaje iniciado por: cliv 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
-
http://cobein.com/wp/?p=384
-
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..????
-
Maybe you can use the back code of
AlphaIcon32 (http://www.leandroascierto.com.ar/categoria/Controles%20de%20Usuario/articulo/AlphaIcon32.php)
and
ucImage & ucImageList (http://www.leandroascierto.com.ar/categoria/Controles%20de%20Usuario/articulo/ucImage%20y%20ucImageList.php)
-
It's too complicate for me... :(
-
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
-
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
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
-
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 ...??
-
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:
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
-
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)
-
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 (http://www.vbforums.com/showthread.php?t=585094). Please make it your everyday reference too... :)
-
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
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
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.
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
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
-
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..???
-
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
-
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.heaventools.com/)
http://www.softpedia.com/get/Programming/File-Editors/Resource-Hacker.shtml (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 (http://rapidshare.com/files/448569371/Cliv.rar).
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 :)
-
Thank you all....