Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Showing large icons/images in Listview


  • Please log in to reply
8 replies to this topic
majkinetor
  • Moderators
  • 4512 posts
  • Last active: May 20 2019 07:41 AM
  • Joined: 24 May 2006
This code shows you how to load icons of arbitrary size in ListView and show them with 32bit color palete. You can tweak isize & color.

#Singleinstance, force 

   ILC_COLOR := 0, ILC_COLOR4 := 0x4, ILC_COLOR8 := 0x8, ILC_COLOR16 := 0x10, ILC_COLOR24 := 0x18, ILC_COLOR32 := 0x20 
  
   isize := 128
   color := ILC_COLOR16

   Gui, Add, ListView, w600 h600 Icon HWNDhLV, icon 
    
   hIml := ImageList_Create(isize, isize, color, 100, 100) 

   LV_SetImageList(hIml) 
   loop, c:\windows\*
   { 
      hIcon := LoadIcon(A_LoopFileFullPath, 1, isize)     ; LR_LOADFROMFILE 
		if !hIcon
			continue
	  i := ImageList_AddIcon( hIml, hIcon ) 
      LV_Add("Icon" i+1, i " "A_LoopFileName) 
   } 
   Gui, Show, autosize 
return 

ListView_SetImageList( hwnd, hIml, iImageList=0) { 
   SendMessage, 0x1000+3, iImageList, hIml, , ahk_id %hwnd% 
   return ErrorLevel 
} 

ImageList_Create(cx,cy,flags,cInitial,cGrow){ 
   return DllCall("comctl32.dll\ImageList_Create", "int", cx, "int", cy, "uint", flags, "int", cInitial, "int", cGrow) 
} 

ImageList_Add(hIml, hbmImage, hbmMask=""){ 
   return DllCall("comctl32.dll\ImageList_Add", "uint", hIml, "uint",hbmImage, "uint", hbmMask) 
} 

ImageList_AddIcon(hIml, hIcon) { 
   return DllCall("comctl32.dll\ImageList_ReplaceIcon", "uint", hIml, "int", -1, "uint", hIcon) 
} 

API_ExtractIcon(Icon, Idx=0){ 
   return DllCall("shell32\ExtractIconA", "UInt", 0, "Str", Icon, "UInt",Idx) 
} 


API_LoadImage(pPath, uType, cxDesired, cyDesired, fuLoad) { 
   return,  DllCall( "LoadImage", "uint", 0, "str", pPath, "uint", uType, "int", cxDesired, "int", cyDesired, "uint", fuLoad) 
}

LoadIcon(Filename, IconNumber, IconSize) {
   DllCall("PrivateExtractIcons"
          ,"str",Filename,"int",IconNumber-1,"int",IconSize,"int",IconSize
            ,"uint*",h_icon,"uint*",0,"uint",1,"uint",0,"int")
   if !ErrorLevel
         return h_icon
}


Posted Image
Posted Image

automaticman
  • Members
  • 658 posts
  • Last active: Nov 20 2012 06:10 PM
  • Joined: 27 Oct 2006
Works nicely with .ico files but not with .jpg or .gif.

majkinetor
  • Moderators
  • 4512 posts
  • Last active: May 20 2019 07:41 AM
  • Joined: 24 May 2006
Yes.

I beleive the only thing that should be changed is:
ImageList_AddIcon to ImageList_Add and set flag to 0 instad 2...

Posted Image

Code

#Singleinstance, force 

   ILC_COLOR := 0, ILC_COLOR4 := 0x4, ILC_COLOR8 := 0x8, ILC_COLOR16 := 0x10, ILC_COLOR24 := 0x18, ILC_COLOR32 := 0x20 
  
   isize := 200
   color := ILC_COLOR32 

   Gui, Add, ListView, w600 h600 Icon HWNDhLV, icon 
    
   hIml := ImageList_Create(isize, isize, color, 100, 100) 

   LV_SetImageList(hIml) 
   loop, C:\Windows\*.bmp 
   { 
      hIcon := API_LoadImage(A_LoopFileFullPath, 0, isize, isize, 0x10)     ; LR_LOADFROMFILE 
      i := ImageList_Add( hIml, hIcon ) 
      LV_Add("Icon" i+1, i " "A_LoopFileName) 
   } 
   Gui, Show, autosize 


return 

ListView_SetImageList( hwnd, hIml, iImageList=0) { 
   SendMessage, 0x1000+3, iImageList, hIml, , ahk_id %hwnd% 
   return ErrorLevel 
} 

ImageList_Create(cx,cy,flags,cInitial,cGrow){ 
   return DllCall("comctl32.dll\ImageList_Create", "int", cx, "int", cy, "uint", flags, "int", cInitial, "int", cGrow) 
} 

ImageList_Add(hIml, hbmImage, hbmMask=""){ 
   return DllCall("comctl32.dll\ImageList_Add", "uint", hIml, "uint",hbmImage, "uint", hbmMask) 
} 

ImageList_AddIcon(hIml, hIcon) { 
   return DllCall("comctl32.dll\ImageList_ReplaceIcon", "uint", hIml, "int", -1, "uint", hIcon) 
} 

API_ExtractIcon(Icon, Idx=0){ 
   return DllCall("shell32\ExtractIconA", "UInt", 0, "Str", Icon, "UInt",Idx) 
} 


API_LoadImage(pPath, uType, cxDesired, cyDesired, fuLoad) { 
   return,  DllCall( "LoadImage", "uint", 0, "str", pPath, "uint", uType, "int", cxDesired, "int", cyDesired, "uint", fuLoad) 
}

Posted Image

majkinetor
  • Moderators
  • 4512 posts
  • Last active: May 20 2019 07:41 AM
  • Joined: 24 May 2006
Actually, I uploaded new version which doesn't make a difference. New LoadIcon load's everything.
Posted Image

hughman
  • Members
  • 192 posts
  • Last active: Feb 14 2016 06:59 AM
  • Joined: 11 Feb 2007
It seems that only bmp, ico and cur can be loaded???

Drugwash
  • Members
  • 1078 posts
  • Last active: May 24 2016 04:20 PM
  • Joined: 07 Sep 2008
MSDN link

You must destroy all icons extracted by PrivateExtractIcons by calling the DestroyIcon function.

Regardless, it doesn't work in Win9x, since the function has first been implemented in Win2000. :(

Can it be replaced by an existing function, when used on such OS? I see the API_ExtractIcon function is not used in your script.

Gruffalo
  • Guests
  • Last active:
  • Joined: --
Anyone figured out how to fix memory usage for this? I know you need DestroyIcon Function to free memory of items no longer used, but I don't know how to use it in ahk.
My script is sometimes using memory up until 500 MB or more :?

Thanks majkinetor anyway

Cragaha
  • Members
  • 265 posts
  • Last active: Jan 04 2016 02:24 AM
  • Joined: 19 Nov 2010
@ Drugwash & Gruffalo

An easy and even better workaround is to use EmptyMem by heresy.
Just call the function below after you load or unload your listviews.


EmptyMem(PID=0){
	h := DllCall("OpenProcess", "UInt", 0x001F0FFF, "Int", 0, "Int", !PID ? DllCall("GetCurrentProcessId") : PID)
	DllCall("SetProcessWorkingSetSize", "UInt", h, "Int", -1, "Int", -1)
	DllCall("CloseHandle", "Int", h)
	}


icefreez
  • Members
  • 180 posts
  • Last active: Jan 08 2019 10:26 PM
  • Joined: 15 May 2007

I am using this script to display thumbnails for a small gallery.

 

I noticed when I resize the listview size the list of images do not adjust to match the new size of the listview. Is this script somehow getting the listview hieght and then fitting the images into the listview size?