Page 1 of 1

Determine image size

Posted: Wed Jan 19, 2011 7:29 am
by jassing
I'm sure this is an easy one, I"m just lost..

ExtractIcon_(0,cFile,1)

How can I determine the images size and format?
What I want to do is show the file's associated 16x16 icon in a listicon...

Re: Determine image size

Posted: Wed Jan 19, 2011 4:52 pm
by IdeasVacuum
You will need to parse all the icon images in the file (use -1 as the last value of ExtractIcon_ to get the image total).

For each image, LoadImage() followed by ImageHeight(), ImageWidth() and ImageDepth() (if necessary, not sure what you mean by 'format' - it can only be a bitmap).

That's it.

Re: Determine image size

Posted: Wed Jan 19, 2011 8:22 pm
by jassing
Awesome, thanks!

-j

Re: Determine image size

Posted: Thu Jan 20, 2011 5:23 am
by jassing
IdeasVacuum wrote:You will need to parse all the icon images in the file (use -1 as the last value of ExtractIcon_ to get the image total).

For each image, LoadImage() followed by ImageHeight(), ImageWidth() and ImageDepth() (if necessary, not sure what you mean by 'format' - it can only be a bitmap).

That's it.
Hm. I guess I"m confused -- how do I use LoadImage() with the handle from ExtractIcon_()?

Re: Determine image size

Posted: Thu Jan 20, 2011 6:35 am
by IdeasVacuum
owch, seems you can't :oops:

netmaestro posted code that could get you there: http://www.purebasic.fr/english/viewtop ... 17&start=0

....but I still can't figure out how to then collect the sizes.

Re: Determine image size

Posted: Thu Jan 20, 2011 7:34 am
by jassing
Thanks -- that size bit is the important part.

Re: Determine image size

Posted: Thu Jan 20, 2011 4:23 pm
by Trond
You don't have to turn it in to a pb image to use it in the list icon gadget:

Code: Select all

File.s = "shell32.dll" ; Contains a lot of icons

IconCount = ExtractIcon_(0, File, -1)
IconMax = IconCount-1
Dim Icons.i(IconMax)
For I = 0 To IconMax
  Icons(I) = ExtractIcon_(0, File, I)
Next



#W = 512
#H = 384

OpenWindow(0, 0, 0, #W, #H, "", #PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
ListIconGadget(0, 10, 10, 400, 300, "Small icons", 96)
SetGadgetAttribute(0, #PB_ListIcon_DisplayMode, #PB_ListIcon_LargeIcon)
For I = 0 To IconMax
  AddGadgetItem(0, 0, "", Icons(I))
Next

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
  EndSelect
ForEver

PS. ExtractIcon_() always returns a "large" icon (it scales it if necessary).

Re: Determine image size

Posted: Fri Jan 21, 2011 3:53 am
by IdeasVacuum
Trond wrote:You don't have to turn it in to a pb image to use it in the list icon gadget:
True, but when it's an exe that has several sizes of the same icon, you want to be able to choose just the one that suits your needs - to do that, you need the size.

So, perhaps the solution is to draw each icon on an invisible Window, get each Image ID of each drawing, verify each size.

Re: Determine image size

Posted: Fri Jan 21, 2011 11:44 am
by Trond
True, but when it's an exe that has several sizes of the same icon, you want to be able to choose just the one that suits your needs - to do that, you need the size.
I know how to get the size of an api HICON easily, that's not the problem. The problem is that ExtractIcon_() returns a 32x32 icon no matter what format the icon has in the file.

To get other icon sizes, I think ExtractIconEx_() would work.

Re: Determine image size

Posted: Fri Jan 21, 2011 4:26 pm
by IdeasVacuum
.....ExtractIconEx() ala Netmaestro's code, but he is using DrawIconEx_(hdc, 10,20,small(0),0,0,0,0,#DI_NORMAL), so we still can't grab the dimensions.

Re: Determine image size

Posted: Sat Jan 22, 2011 10:40 pm
by jassing
What I wanted to do, and am having little success, is this

Show a combobox with some selections in it:
With all but the 1st, the icon associated with the files are shown.

All files(*.*)
MS SQL Data files (*.ldf;*.mdf)
FoxPro data files (*.dbf;*.fpt)
MS Access files (etc)

This routine needs to be somewhat generic, as the user can change what files are listed at runtime via configuration screen.

What I have no is a static list -ie: I have the icons already pulled & saved.
But if hte user enters something like:
MYDatafile (*.xyz)

I want the program to fetch the associated viewer for .xyz (not a problem) and the extract the icon & use it in the combobox next to "MyDatafile"

That's the issue -- since the api's return a handle, but the combobox wants an image#; I can't seemt o figure out how to convert them.... or load hte image as an image #.

Re: Determine image size

Posted: Mon Jan 24, 2011 4:38 pm
by Trond
but the combobox wants an image#
The combobox, just like the listicon takes a handle.

Code: Select all

#SHGFI_ADDOVERLAYS = $20
; #SHGFI_SHELLICONSIZE
; #SHGFI_SMALLICON 
; #SHGFI_LARGEICON
File.s = "c:\lorem.txt"
SHGetFileInfo_(File, 0, @info.SHFILEINFO, SizeOf(SHFILEINFO), #SHGFI_ADDOVERLAYS | #SHGFI_ICON | #SHGFI_SMALLICON)
Debug info\hIcon



#W = 512
#H = 384

OpenWindow(0, 0, 0, #W, #H, "", #PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
ListIconGadget(0, 10, 10, 400, 300, "Small icons", 96)
ComboBoxGadget(0, 10, 10, 200, 22, #PB_ComboBox_Image)
AddGadgetItem(0, 0, "", info\hIcon)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
  EndSelect
ForEver

Re: Determine file's "icon"

Posted: Mon Jan 24, 2011 6:19 pm
by jassing
wow; thank you. I will get the hang of this .. (at least that's what I keep telling myself)
Here's the function I ended up with to make it generic.

Code: Select all

#SHGFI_ADDOVERLAYS = $20
; #SHGFI_SHELLICONSIZE
; #SHGFI_SMALLICON 
; #SHGFI_LARGEICON

Procedure GetHandlerIcon( cExtension.s )
	Protected *memBuffer
	Protected fileInfo.SHFILEINFO
	Protected cTempFile.s, i.i=0
	Protected hndIcon = #NUL
	
	*memBuffer = AllocateMemory(1024)
	If *memBuffer 
		; Just check that we have a dot in the extension.
		If Left(cExtension,1)<>"." : cExtension = "."+cExtension : EndIf
		
		; find a unique temporary file
		Repeat
			cTempFile = "~tmp"+RSet(Str(i),5,"0")
			i+1
		Until FileSize( GetTemporaryDirectory() + cTempFile+cExtension ) = -1
		cTempFile = cTempFile+cExtension
		
		; Create a blank file -- the file's existance is required for FindExecutable()
		CloseFile(OpenFile(#PB_Any, GetTemporaryDirectory()+cTempFile ))
		
		; get the executable releated to the extension
		If FindExecutable_(cTempFile,GetTemporaryDirectory(),*memBuffer) > 32
			; fetch the information about that executable.
			SHGetFileInfo_(PeekS(*memBuffer), 0, @fileInfo, SizeOf(SHFILEINFO), #SHGFI_ADDOVERLAYS | #SHGFI_ICON | #SHGFI_SMALLICON)
			; now grab the icon's handle
		  hndIcon = fileInfo\hIcon
		EndIf
		
		; Clean up our mess
		DeleteFile(GetTemporaryDirectory()+cTempFile )
		FreeMemory(*memBuffer)
	EndIf
	ProcedureReturn hndIcon
EndProcedure



#W = 512
#H = 384

OpenWindow(0, 0, 0, #W, #H, "", #PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
ListIconGadget(0, 10, 10, 400, 300, "Small icons", 96)
ComboBoxGadget(0, 10, 10, 200, 22, #PB_ComboBox_Image)
AddGadgetItem(0, 0, "*.txt", GetHandlerIcon(".txt"))

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
  EndSelect
ForEver

Re: Determine image size

Posted: Sun Jan 30, 2011 8:02 pm
by Trond
Your approach is wrong. You should get the icon directly from the file of the relevant type, not from the executable. An executable may contain multiple different icons. With your approach you'll always get the first. But the icon of a filetype may be one of the other icons in the executable.

Re: Determine image size

Posted: Tue Feb 01, 2011 3:09 pm
by jassing
Trond wrote:Your approach is wrong. You should get the icon directly from the file of the relevant type, not from the executable. An executable may contain multiple different icons. With your approach you'll always get the first. But the icon of a filetype may be one of the other icons in the executable.
Good point. Some things, for instance, .mdb (an MSSQL file) doesn't show a default icon -- but I know what it is; so I grab the exe -- I was focused on that specific issue and overlooked the broader view. I modified it to get the file's icon 1st, if that fails, then go to the exe, if that fails, just show a generic one...
thanks
-j