Windows file explorer example.

BlitzMax Forums/BlitzMax Programming/Windows file explorer example.

I am working on a project that makes painting like effects on live video,avi's, etc. I needed a listbox that had a directory view with thumbnails and a selected picture list that could be edited.

I am using columns in a listbox so the window is not resizable.

It has a scalable picture preview.
A ComboBox Drive list.
You can select Multi files at once.

It only shows picture files. jpg,bmp,png and Directories.

I thought that other might found this code or bits of it useful.

It also had sorting of the selected pictures but the lastest fix to listboxs has stopped that from working, so I have removed the sorting code.

'Ziltch Explorer example
Strict

Extern "win32"
	Function GetSysColor(index)
	Function UpdateWindow(Hwd)
	Function GetLogicalDriveStringsA(nBufferLength, lpBuffer:Byte Ptr)
	Function SHGetSpecialFolderLocation(hwndOwner, nFolder, pIdl:Byte  Ptr)
	Function SHGetPathFromIDList( pidList ,lpBuffer:Byte  Ptr)
EndExtern

Const WM_USER = $400
Const IDCOMBOBOX           = WM_USER + 102
Const GENERIC_READ     = $80000000
Const GENERIC_WRITE    = $40000000
Const FILE_SHARE_READ  = 1
Const FILE_SHARE_WRITE = 2
Const OPEN_EXISTING       = 3

Const WS_BORDER	 = $800000
Const WS_CAPTION	 = $c00000
Const WS_CHILD	 = $40000000
Const WS_CHILDWINDOW	 = $40000000
Const WS_CLIPCHILDREN  = $2000000
Const WS_CLIPSIBLINGS  = $4000000
Const WS_DISABLED	 = $8000000
Const WS_DLGFRAME	 = $400000
Const WS_GROUP	 = $20000
Const WS_HSCROLL	 = $100000
Const WS_ICONIC	 = $20000000
Const WS_MAXIMIZE	 = $1000000
Const WS_MAXIMIZEBOX	 = $10000
Const WS_MINIMIZE	 = $20000000
Const WS_MINIMIZEBOX	 = $20000
Const WS_OVERLAPPED	= 0
Const WS_OVERLAPPEDWINDOW	 = $cf0000
Const WS_POPUP	 = $80000000
Const WS_POPUPWINDOW	 = $80880000
Const WS_SIZEBOX	 = $40000
Const WS_SYSMENU	 = $80000
Const WS_TABSTOP	 = $10000
Const WS_THICKFRAME	 = $40000
Const WS_TILED	 = 0
Const WS_TILEDWINDOW	 = $cf0000
Const WS_VISIBLE	 = $10000000
Const WS_VSCROLL	 = $200000

Const LBS_DISABLENOSCROLL = 4096
Const LBS_EXTENDEDSEL = $800
Const LBS_HASSTRINGS = 64
Const LBS_MULTICOLUMN = 512
Const LBS_MULTIPLESEL = 8
Const LBS_NODATA	= $2000
Const LBS_NOINTEGRALHEIGHT = 256
Const LBS_NOREDRAW = 4
Const LBS_NOSEL =  $4000
Const LBS_NOTIFY  = 1
Const LBS_OWNERDRAWFIXED = 16
Const LBS_OWNERDRAWVARIABLE = 32
Const LBS_SORT = 2
Const LBS_STANDARD = $a00003
Const LBS_USETABSTOPS = 128
Const LBS_WANTKEYBOARDINPUT = $400

Const LVM_FIRST = $1000
Const LVM_GETCOLUMNA	=(LVM_FIRST+25)
Const LVM_GETCOLUMNW	=(LVM_FIRST+95)
Const LVM_SETCOLUMNA	=(LVM_FIRST+26)
Const LVM_SETCOLUMNW	=(LVM_FIRST+96)
Const LVM_INSERTCOLUMNA	=(LVM_FIRST+27)
Const LVM_INSERTCOLUMNW	=(LVM_FIRST+97)
Const LVM_DELETECOLUMN	=(LVM_FIRST+28)
Const LVM_GETCOLUMNWIDTH	=(LVM_FIRST+29)
Const LVM_GETITEMA	= (LVM_FIRST+5)
Const LVM_GETITEMW	= (LVM_FIRST+75)
Const LVM_SETITEMA	= (LVM_FIRST+6)
Const LVM_SETITEMW	= (LVM_FIRST+76)
Const LVM_INSERTITEMA	= (LVM_FIRST+7)
Const LVM_INSERTITEMW	= (LVM_FIRST+77)
Const LVM_DELETEITEM	= (LVM_FIRST+8)
Const LVM_DELETEALLITEMS	= (LVM_FIRST+9)
Const LVM_GETCALLBACKMASK	= (LVM_FIRST+10)
Const LVM_SETCALLBACKMASK	=(LVM_FIRST+11)
Const LVM_SETCOLUMNWIDTH	=(LVM_FIRST+30)
Const LVM_GETTEXTCOLOR	=(LVM_FIRST+35)
Const LVM_SETTEXTCOLOR	=(LVM_FIRST+36)
Const LVM_GETTEXTBKCOLOR	=(LVM_FIRST+37)
Const LVM_SETTEXTBKCOLOR=	(LVM_FIRST+38)
Const LVM_SORTITEMS =	(LVM_FIRST+48)

Const LVCF_FMT	=1
Const LVCF_WIDTH	=2
Const LVCF_TEXT	=4
Const LVCF_SUBITEM	=8
Const LVCF_IMAGE= 16
Const LVCF_ORDER =32
Const LVIF_TEXT = 1
Const LVIF_IMAGE =2
Const LVIF_PARAM =4
Const LVIF_STATE =8
Const LVIF_INDENT =$10 
Const LVIF_GROUPID =$100 
Const LVIF_COLUMNS =$200 
Const LVIF_NORECOMPUTE =$800  
Const LVIF_DI_SETITEM =$1000

Const LVS_ICON             =0
Const LVS_REPORT	        =1
Const LVS_SMALLICON	        =2
Const LVS_LIST	            =3
Const LVS_TYPEMASK         =3
Const LVS_SINGLESEL        =4
Const LVS_SHOWSELALWAYS    =8
Const LVS_SORTASCENDING    =16
Const LVS_SORTDESCENDING   =32
Const LVS_SHAREIMAGELISTS	=64
Const LVS_NOLABELWRAP      =128
Const LVS_AUTOARRANGE      =256
Const LVS_EDITLABELS       =512
Const LVS_NOSCROLL         =$2000
Const LVS_TYPESTYLEMASK    =$fc00
Const LVS_ALIGNTOP	        =0
Const LVS_ALIGNLEFT	       =$800
Const LVS_ALIGNMASK	       =$c00
Const LVS_OWNERDRAWFIXED  =$400
Const LVS_NOCOLUMNHEADER  =$4000
Const LVS_NOSORTHEADER	   =$8000
Const GWL_STYLE      = -16

Const ALPHABITS=$ff000000

Type  LVCOLUMN  
	Field mask
	Field fmt
	Field cx
	Field pszText:Byte Ptr
	Field cchTextMax
	Field iSubItem
EndType

Type LVITEM 
	Field mask
	Field iItem
	Field iSubItem
	Field iState
	Field stateMask
	Field pszText:Byte Ptr
	Field cchTextMax
	Field iImage
	Field lParam:Byte Ptr
	Field iIndent
	Field iGroupId
	Field cColumns
	Field puColumns
EndType


Const BBQID_WIN32HWND = 1
Const BBQID_WIN32CLIENTHWND =2
Const Accessed        = 1
Const Creation        = 2
Const LastWrite       = 3	

Global FileTypes$[]=["","","(Dir)"]
Global PicSize =32 ,NewPicSize=PicSize
Global ExplorerWindow:TGadget,ExplorerDriveListCombo:TGadget,ExplorerThumbnailSizeCombo:TGadget,Explorer:TGadget, ExplorerSelectedListBox:TGadget
Global ExplorerBackButton:TGadget,ExplorerHightLightAllButton:TGadget,ExplorerHightLightToggleButton:TGadget,ExplorerSelectButton:TGadget
Global ExplorerSelectedListUpButton:TGadget,ExplorerSelectedListDownButton:TGadget,ExplorerPreviewButton:TGadget,ExplorerSelectedListDeleteButton:TGadget
Global ExplorerPanel:TGadget,ExplorerSelectedPanel:TGadget ,ExplorerSelectedOrderButton:TGadget
Global ExplorerCancelButton:TGadget,ExplorerOkButton:TGadget
Global ExplorerPreviewWindow:TGadget,ExplorerPreviewPanel:TGadget

Local FilType ,FileExt$,PicCnt=0,LoadedImage:TPixmap
Local LoadedImageWidth,LoadedImageWidthStep:Float
Local LoadedImageHeight,LoadedImageHeightStep:Float
Global CurrentDirectory$ =  CurrentDir$() ,DirCount
Global PreviewPixmap:TPixmap,PreviewMode,PreviewFileName$,LastPreviewFileName$
Global Thumbs:TIconStrip, SelThumbs:TIconStrip ,SelThumbsPixmap:TPixmap
Global SelCount ,SelectedMax = 255 ,TotalPicsSelected 
SelThumbsPixmap=CreatePixmap(PicSize*SelectedMax ,PicSize,PF_RGB888)
SelThumbs:TIconStrip =LoadIconStrip(SelThumbsPixmap)
Global NoDriveUpdate
Local tt,col,Gadget:TGadget ,SortOrder=1

Function PeekString:String(Bank:TBank,Offset=0,MaxLen=1024)
	Local PeekChr
	Local OffsetCount
	Local NewString:String
	Repeat
		PeekChr = PeekByte(Bank,Offset + OffsetCount)
		'	DebugLog OffsetCount +"PeekChr ="+PeekChr + "  "+Chr(PeekChr)
		If PeekChr Then NewString:+Chr(PeekChr)
		OffsetCount:+1
	Until (PeekChr =0)  Or (OffsetCount > MaxLen)
	Return NewString
EndFunction
Function GetFileModTime$(Filename$)

	Local ftime : Int = FileTime(Filename)
	Local pointer : Int Ptr = Int Ptr(localtime_(Varptr(ftime)))
	Local wSec=pointer[0]
	Local wMin=pointer[1]
	Local wHour=pointer[2]
	Local wDay=pointer[3]
	Local wMonth=pointer[4]+1
	Local wYear=(pointer[5]+1900)
	Local res$=( wYear+ "/" +Right("0"+wMonth,2)+ "/" +Right("0"+wDay,2)+ " " +wHour+ ":" +wMin+ ":" +wSec)'  + " :" +wMilliseconds)
	'DebugLog "Date is "+res$
	Return  res$
End Function

Function GetFileCreatedTime$(Filename$)
	Local mode,size,mtime,ctime
	FixPath Filename
	If stat_( Filename,mode,size,mtime,ctime ) Then 
		Return
	EndIf
	Local pointer : Int Ptr = Int Ptr(localtime_(Varptr(ctime)))
	Local wSec=pointer[0]
	Local wMin=pointer[1]
	Local wHour=pointer[2]
	Local wDay=pointer[3]
	Local wMonth=pointer[4]+1
	Local wYear=(pointer[5]+1900)	
	Local res$=( wYear+ "/"+Right("0"+wMonth,2)+ "/" +Right("0"+wDay,2)+  " " +wHour+ ":" +wMin+ ":" +wSec)'  + " :" +wMilliseconds)
	'DebugLog "Date is "+res$
	Return  res$
End Function

Function AddListBoxColumn(ListBox:TGadget,Column,HeadingText$,Width,Style=0)
	Local ListboxHwnd=QueryGadget(ListBox,BBQID_WIN32HWND)
	Local col:LVCOLUMN = New LVCOLUMN	
	Col.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_FMT
	Col.fmt = Style
	Col.cx = Width
	col.pszText = HeadingText$.ToCString()
	Local ListBoxstyle = GetWindowLongA(ListboxHwnd , GWL_STYLE)
	If (ListBoxstyle &  LBS_MULTICOLUMN ) <> ( LBS_MULTICOLUMN ) Then
		ListBoxstyle  = ListBoxstyle  | LBS_MULTICOLUMN
		SetWindowLongA(ListboxHwnd , GWL_STYLE,  ListBoxstyle  ~ LVS_SINGLESEL) 'change the style so that we have headings
	EndIf
	SendMessageA(ListboxHwnd,LVM_INSERTCOLUMNA,Column,Int(Byte Ptr Col))
End Function

Function AddListBoxItem(ListBox:TGadget,Text$,Row,Column)
	Local ListboxHwnd=QueryGadget(ListBox,BBQID_WIN32HWND)
	Local ColItem:LVITEM  = New LVITEM
	ColItem.mask = LVIF_TEXT
	ColItem.iSubItem = Column
	ColItem.iItem = Row
	ColItem.pszText = Text$.ToCString()
	ColItem.cchTextMax =  Text$.Length + 1
	SendMessageA( ListboxHwnd,LVM_SETITEMA,0,Int(Byte Ptr ColItem))
	ColItem=Null
End Function


Function GetListBoxItem:String(ListBox:TGadget,Row,Column)
	Local ListboxHwnd=QueryGadget(ListBox,BBQID_WIN32HWND)
	If ListboxHwnd Then
		Local Ans$
		Local TextBank:TBank=CreateBank(1024)
		'Local Text:Byte[256]
		Local ColItem:LVITEM  = New LVITEM
		ColItem.mask = LVIF_TEXT
		ColItem.iSubItem = Column
		ColItem.iItem = Row
		ColItem.pszText = BankBuf(TextBank)
		ColItem.cchTextMax =  255 
		SendMessageA( ListboxHwnd,LVM_GETITEMA,0,Int(Byte Ptr ColItem))
		If ColItem.pszText <> Null
			Ans$=Ans$.fromcstring(ColItem.pszText)
			ColItem=Null
		EndIf
		Return Ans$
	EndIf
End Function


Function SetListBoxSort(ListBox:TGadget,Row,SortText:String)
	Local ListboxHwnd=QueryGadget(ListBox,BBQID_WIN32HWND)
	If ListboxHwnd Then
		Local ColItem:LVITEM  = New LVITEM
		ColItem.mask = LVIF_PARAM '| LVIF_STATE
		ColItem.iItem = Row
		ColItem.lParam = SortText.tocstring()
		'ColItem.iState = Row
		SendMessageA( ListboxHwnd,LVM_SETITEMA,0,Int(Byte Ptr ColItem))
	EndIf
End Function

Function GetListBoxSort:String(ListBox:TGadget,Row)
	Local ListboxHwnd=QueryGadget(ListBox,BBQID_WIN32HWND)
	If ListboxHwnd Then
		Local Ans$
		'Local TextBank:TBank=CreateBank(1024)
		'Local Text:Byte[256]
		Local ColItem:LVITEM  = New LVITEM
		ColItem.mask = LVIF_PARAM '| LVIF_STATE
		ColItem.iItem = Row
		SendMessageA( ListboxHwnd,LVM_GETITEMA,0,Int(Byte Ptr ColItem))
		If ColItem.lParam <> Null
			Ans$=Ans$.fromcstring(ColItem.lParam)
		EndIf
		'DebugLog "row "+row '+" STATE = "+ColItem.iState

		Return Ans$
		
	EndIf
End Function

Function ListBoxGadgetMultiSelect(ListBox:TGadget)
	Local ListboxHwnd = QueryGadget(ListBox,BBQID_WIN32HWND)
	Local ListBoxstyle = GetWindowLongA(ListboxHwnd , GWL_STYLE)
	
	Return SetWindowLongA(ListboxHwnd , GWL_STYLE,  ListBoxstyle ~LVS_SINGLESEL )  'change the style 		
End Function

Function ListBoxHeading(ListBox:TGadget,Column,Text$,Width=0)
	Local ListboxHwnd=QueryGadget(ListBox,BBQID_WIN32HWND)
	Local col:LVCOLUMN = New LVCOLUMN	
	If Width = 0 Then
		Col.mask = LVCF_TEXT| LVCF_FMT 
	Else
		Col.mask = LVCF_TEXT| LVCF_FMT | LVCF_WIDTH
		col.cx   = Width
	EndIf
	col.pszText = Text$.ToCString()
	Local ListBoxstyle = GetWindowLongA(ListboxHwnd , GWL_STYLE)
	If (ListBoxstyle &  LVS_NOCOLUMNHEADER ) Then
		ListBoxstyle  = ListBoxstyle  ~LVS_NOCOLUMNHEADER 
		SetWindowLongA(ListboxHwnd , GWL_STYLE,  ListBoxstyle )  'change the style so that we have headings
	EndIf
	SendMessageA(ListboxHwnd,LVM_SETCOLUMNA,Column,Int(Byte Ptr Col))
	
End Function

Function ListBoxColumnWidth(ListBox:TGadget,Column,width)
	Local ListboxHwnd=QueryGadget(ListBox,BBQID_WIN32HWND)
	Local col:LVCOLUMN = New LVCOLUMN	
	Col.mask = LVCF_WIDTH
	col.cx   = width
	SendMessageA(ListboxHwnd,LVM_SETCOLUMNA,Column,Int(Byte Ptr Col))
End Function

Function RGB(Rcolor,Gcolor,Bcolor)
	Return((Rcolor Shl 16) | (Gcolor Shl 8) | Bcolor)
EndFunction

Function Red(RGBcolor)
	Return  ((RGBcolor Shr 16) & 255)
EndFunction

Function Green(RGBcolor)
	Return (RGBcolor Shr 8) & 255
EndFunction

Function Alpha(RGBcolor)
	Return (RGBcolor Shr 24) & 255
EndFunction

Function Blue(RGBcolor)
	Return RGBcolor & 255
EndFunction

Function RGB2BGR(RGBcolor)
	Local Bcolor = Red(RGBcolor)
	Local Gcolor = Green(RGBcolor)
	Local Rcolor =  Blue(RGBcolor)
	Return ((Rcolor Shl 16) | (Gcolor Shl 8) | Bcolor)
EndFunction

Const WM_SETTEXT  = 12
Const WM_GETTEXT = 13
Const WM_GETTEXTLENGTH = 14
Function ComboBoxText:String(Gadget:TGadget)
	Local StrLen= SendMessageA( QueryGadget(Gadget,QUERY_HWND),WM_GETTEXTLENGTH,0,0 )+1
	Local char_buff:TBank=CreateBank(StrLen)
	
	SendMessageA( QueryGadget(Gadget,QUERY_HWND),WM_GETTEXT,StrLen,Int(BankBuf(Char_buff )));
	
	Local Res$
	For Local index = 0 To StrLen-2
		Res$:+Chr(PeekByte(Char_buff,index))
	Next
	Return Res$
EndFunction

Function SetComboBoxText:String(Gadget:TGadget,Text:String)
	Local StrLen= Text.Length
	Return SendMessageA( QueryGadget(Gadget,QUERY_HWND),WM_SETTEXT,Text.Length,Int(Text.ToCstring()));
EndFunction


Function FormatFileSize:String(Size)
	Local SizeString:String = String(size)
	Local SizeLen = Len(SizeString)
	Local FormatedSize:String
	Local AfterDecimalPoint:String
	Local Scale:String
	' DebugStop
	If SizeLen  > 6 Then
		SizeString = String(size/1048576)'1024*1024
		SizeLen = Len(SizeString)
		AfterDecimalPoint=String(Abs(size/1048576)-(size/1048576.0))[2..5]
		Scale = " Mb"
	ElseIf SizeLen  > 3 Then
		SizeString = String(size/1024)
		SizeLen = Len(SizeString)
		AfterDecimalPoint=String(Abs(Int(size/1024.0))-(size/1024.0))[2..5]
		Scale = " Kb"
	Else
	
		Scale = " b"
	EndIf
	If SizeLen  > 3 Then
		For Local count = Sizelen -1 To 0 Step -1
			FormatedSize:+ SizeString[count]
			If count/3.0 = Int(count/3.0) Then FormatedSize:+","
		Next
	Else
		FormatedSize = SizeString
	EndIf
	FormatedSize:+AfterDecimalPoint
	FormatedSize:+Scale
	Return FormatedSize
	
EndFunction

Function SetComboGadgetDriveList(Gadget:TGadget)
	Local DriveStringBank:TBank = CreateBank(2048)
	Local DriveStringLen = GetLogicalDriveStringsA(2048,BankBuf(DriveStringBank))
	Local DriveString:String 
	Local PeekChr
	Local OffsetCount

	Repeat
		PeekChr = PeekByte(DriveStringBank,OffsetCount)
		If PeekChr Then 
			DriveString:+Chr(PeekChr)
		ElseIf PeekChr =0
			AddGadgetItem(Gadget,Left(DriveString,2))
			DriveString=""
		EndIf
		OffsetCount:+1
	Until  (OffsetCount > DriveStringLen )
EndFunction

Function CreateExplorerWindow()

	ExplorerWindow                   = CreateWindow("window",100,100,700,470,Null,WINDOW_TITLEBAR|WINDOW_CLIENTCOORDS|WINDOW_STATUS)
	
	CreateLabel("Drives",15,9,35,22,ExplorerWindow)
	ExplorerDriveListCombo           = CreateComboBox(50,5,50,22,ExplorerWindow,COMBOBOX_EDITABLE)
	CreateLabel("Thumbnail Size",105,9,80,22,ExplorerWindow)
	ExplorerThumbnailSizeCombo       = CreateComboBox(185,5,50,22,ExplorerWindow,COMBOBOX_EDITABLE)
	ExplorerPanel                    = CreatePanel(5,35,545,430,ExplorerWindow,PANEL_ACTIVE|PANEL_BORDER)
	Explorer                         = CreateListBox(2,2,537,394,ExplorerPanel)
	ExplorerBackButton               = CreateButton("Back",5,400,45,22,ExplorerPanel)
	ExplorerHightLightAllButton      = CreateButton("All",55,400,45,22,ExplorerPanel)
	ExplorerHightLightToggleButton   = CreateButton("Toggle",105,400,45,22,ExplorerPanel)
	ExplorerPreviewButton            = CreateButton("Preview",155,400,45,22,ExplorerPanel)		
	ExplorerSelectButton             = CreateButton("Select",205,400,45,22,ExplorerPanel)	
	ExplorerSelectedPanel            = CreatePanel(555,35,140,398,ExplorerWindow,PANEL_ACTIVE|PANEL_BORDER)
	ExplorerSelectedOrderButton      = CreateButton("Selected Pics",2,4,132,16,ExplorerSelectedPanel,LABEL_CENTER | LABEL_FRAME)
	ExplorerSelectedListBox          = CreateListBox(2,24,132,342,ExplorerSelectedPanel)
	ExplorerSelectedListUpButton     = CreateButton("Up",2,370,40,22,ExplorerSelectedPanel)
	ExplorerSelectedListDownButton   = CreateButton("Down",46,370,40,22,ExplorerSelectedPanel)
	ExplorerSelectedListDeleteButton = CreateButton("Delete",90,370,45,22,ExplorerSelectedPanel)
	ExplorerCancelButton             = CreateButton("Cancel",600,440,45,22,ExplorerWindow )
	ExplorerOkButton                 = CreateButton("Ok",650,440,45,22,ExplorerWindow )
	
	ListBoxHeading(Explorer,0,"Name")
	AddListBoxColumn(Explorer,1,"Type",40,0)
	AddListBoxColumn(Explorer,2,"Modified",110,0)
	AddListBoxColumn(Explorer,3,"Created",110,0)
	AddListBoxColumn(Explorer,4,"Size",89,0)

	ListBoxGadgetMultiSelect(ExplorerSelectedListBox)
	RedrawGadget(ExplorerSelectedListBox)
	
	AddGadgetItem(ExplorerThumbnailSizeCombo,"8")
	AddGadgetItem(ExplorerThumbnailSizeCombo,"16")
	AddGadgetItem(ExplorerThumbnailSizeCombo,"32")
	AddGadgetItem(ExplorerThumbnailSizeCombo,"64")
	AddGadgetItem(ExplorerThumbnailSizeCombo,"128")	
	SetGadgetText(ExplorerThumbnailSizeCombo,PicSize)
	
	SetComboGadgetDriveList(ExplorerDriveListCombo)
	
	ExplorerPreviewWindow:TGadget = CreateWindow("Preview",100+155,100+35,400,400,ExplorerWindow,WINDOW_TITLEBAR | WINDOW_HIDDEN|WINDOW_RESIZABLE)'|WINDOW_STATUS
	ExplorerPreviewPanel:TGadget  = CreatePanel(5,5,385,365,ExplorerPreviewWindow,PANEL_BORDER)
	SetGadgetLayout( ExplorerPreviewPanel,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED)
	
EndFunction

Function UpdateIconStrip(IconIndex,SelIndex)
	If Thumbs.Pixmap.width-PicSize < SelIndex*PicSize Then
		DebugLog "ERROR: UpdateIconStrip  is out of range"
	Else
		Local SelIcon:TPixmap = PixmapWindow:TPixmap( Thumbs.Pixmap, SelIndex*PicSize,0,PicSize,PicSize)
		If SelIcon Then
			SelThumbsPixmap.Paste(SelIcon,IconIndex*PicSize,0 )	
			SelThumbs = LoadIconStrip(SelThumbsPixmap)
			SetGadgetIconStrip(ExplorerSelectedListBox,SelThumbs)
		EndIf
	EndIf
EndFunction


Const CSIDL_FONTS = $14
Function GetSpecialFolder:String(FolderId) 
	Local  FolderIdBank:TBank = CreateBank(8) 
	Local  PathBank:TBank = CreateBank(1024) 
	If SHGetSpecialFolderLocation(0,FolderId,BankBuf(FolderIdBank)) = 0		
		SHGetPathFromIDList( PeekInt( FolderIdBank,0), BankBuf(PathBank))
		Return (PeekString(PathBank) + "")
	EndIf
End Function


Function CreateIconDirectory$(PicDirectory$)
	Local LastDir$=CurrentDir()
	ChangeDir(PicDirectory$)
	Local files$[]=LoadDir(PicDirectory$,False)
	Local DirSize=1,PicCnt,TotalPics,FilType
	DirCount=0

	For Local file$=EachIn files
		FilType = FileType( file$)
		Local FileExt$=Lower(ExtractExt(file$))
		If (FileExt="jpg" Or FileExt="bmp" Or FileExt="png" ) Then
			DirSize:+1
		ElseIf FilType =2 And  file$ <> "." 'directory
			DirSize:+1
			DirCount:+1
		EndIf
	Next
	If (Dirsize*PicSize*PicSize*4)>16777216 Then
		Confirm("Thumbnail size is too large for "+DirSize+" files.~n Please decrease the thumbnail size and try again. ")
		ChangeDir(LastDir$)				
		Return LastDir$
	EndIf
	NoDriveUpdate = True
	SetGadgetText(ExplorerDriveListCombo,Upper(PicDirectory[0..2]))
	ClearGadgetItems(Explorer)

	If DirSize => 1 Or DirCount => 1

		Local tt = 5
		Local Pixmap:TPixmap=CreatePixmap(Dirsize*PicSize,PicSize,PF_RGB888)
		Local col = RGB2BGR(GetSysColor(tt))

		' Make Directory Icon based off PicSize (Thumbnail)
		Local TempCanvas:TGadget = CreateCanvas:TGadget(2048,2048,PicSize,PicSize,ExplorerWindow:TGadget)
		SetGraphics CanvasGraphics(TempCanvas)
		SetViewport 0,0,GraphicsWidth(),GraphicsHeight()
		SetBlend SOLIDBLEND
		SetClsColor Red(col ),Green(col ),Blue(col )
		Cls
		SetBlend ALPHABLEND
		Local DirFont:TImageFont = LoadImageFont:TImageFont(GetSpecialFolder(CSIDL_FONTS)+"ariblk.ttf",PicSize/2-1,BOLDFONT | SMOOTHFONT )
		SetImageFont( DirFont)
		Local FontX = PicSize/2-TextWidth("DIR")/2
		Local FontY = PicSize/2-TextHeight("DIR")/2-1
		SetColor 10,10,10	
		DrawText("DIR",FontX+1 ,FontY+1)
		SetColor 130,130,160	
		DrawText("DIR",FontX ,FontY)

		Local DirPixmap:TPixmap=GrabPixmap(0,0,PicSize,PicSize)
		Pixmap.Paste( DirPixmap,0,0 )
		FreeGadget(TempCanvas)

		Local file$,FileExt$,LoadedImage:TPixmap ,StartTime ,TimeTaken
		StartTime= MilliSecs()
		For  file$=EachIn files
			file$=RealPath$(file$)
			FilType = FileType( file$)
			FileExt$=Lower(ExtractExt(file$))
			If file$ <> "." Then
				If  (FileExt="jpg" Or FileExt="bmp" Or FileExt="png" )Then
					LoadedImage=LoadPixmap(file$)
					PicCnt:+1
					If LoadedImage Then 
						Local LoadedImageWidth = PixmapWidth(LoadedImage)
						Local LoadedImageWidthStep#= LoadedImageWidth/Float(PicSize)
						Local LoadedImageHeight = PixmapHeight(LoadedImage)
						Local LoadedImageHeightStep#= LoadedImageHeight/Float(PicSize)
						'LoadedImage = ResizePixmap(LoadedImage ,PicSize,PicSize)
						'Pixmap.Paste( LoadedImage ,PicCnt*PicSize,0 )
						For Local PosX = 0 To PicSize-1 ' Copy pixels from each picture into smaller strip of pictures
							For Local PosY = 0 To PicSize-1
								WritePixel(Pixmap,Posx+(PicCnt*PicSize),PosY,ReadPixel(LoadedImage,PosX*LoadedImageWidthStep,PosY*LoadedImageHeightStep))
							Next
						Next
					EndIf
					SetStatusText( ExplorerWindow,"File "+PicCnt+"/"+DirSize)	
				EndIf
			EndIf
		Next
		
		TimeTaken = MilliSecs() - StartTime
		DirSize:-1
		Thumbs:TIconStrip =  LoadIconStrip(Pixmap)
		SetGadgetIconStrip(Explorer,Thumbs)
		PicCnt=1
		DirCount=0
		Local FileCnt = 0
		For  file$=EachIn files
			FilType = FileType( file$)
			FileExt$=Lower(ExtractExt(file$))
			If file$ <> "." Then
				If  (FileExt="jpg"  Or FileExt="bmp" Or FileExt="png" ) Then
					AddGadgetItem (Explorer, file$+"    " ,0,PicCnt,RealPath$(file$))  
					AddListBoxItem(Explorer,FileTypes$[FilType],DirCount+PicCnt-1,1)
					AddListBoxItem(Explorer,GetFileModTime( file$),DirCount+PicCnt-1,2)
					AddListBoxItem(Explorer,GetFileCreatedTime( file$),DirCount+PicCnt-1,3)
					AddListBoxItem(Explorer,FormatFileSize(FileSize( file$)),DirCount+PicCnt-1,4)
					PicCnt:+1	
				ElseIf FilType =2 'directory
					InsertGadgetItem(Explorer,DirCount,file$,0,-1,RealPath$(file$))
					AddListBoxItem(Explorer,FileTypes$[FilType],DirCount,1)
					DirCount:+1
				EndIf
			EndIf
			SetStatusText( ExplorerWindow,"File "+PicCnt+"/"+DirSize)	
		Next
		ListBoxColumnWidth(Explorer,0,180)
		SetStatusText( ExplorerWindow,(PicCnt-1)+" Picture Files  TimeTaken "+Int(TimeTaken/1000 )+String(Abs(Int(TimeTaken/1000.0))-(TimeTaken/1000.0))[2..5]+ " seconds." )
		Return PicDirectory$
	EndIf
EndFunction

Function PreviewFile(PreviewFileName$)	
	If PreviewFileName$ Then
		PreviewPixmap = LoadPixmap(CurrentDirectory+"/"+PreviewFileName$)
		PreviewMode = PANELPIXMAP_FIT
		If PreviewPixmap Then 				 
			ShowGadget ExplorerPreviewWindow
 			LastPreviewFileName$=PreviewFileName$
			SetPanelColor( ExplorerPreviewPanel,0,0,0 )
			SetPanelPixmap(ExplorerPreviewPanel,PreviewPixmap,PreviewMode)
			SetGadgetText( ExplorerPreviewWindow,CurrentDirectory+"/"+PreviewFileName)
		EndIf
	EndIf
EndFunction



'
'------------------------------------------------------------------------
'


CreateExplorerWindow()


SetGadgetIconStrip(ExplorerSelectedListBox,SelThumbs)
CreateIconDirectory(CurrentDirectory)
SetGadgetText(ExplorerWindow,CurrentDirectory)


'Main Loop

Repeat
	WaitEvent()
	
	Gadget= TGadget(EventSource())
	
	Select EventID()
	
		Case EVENT_GADGETACTION	
		
			Select Gadget 
				Case Explorer
					Local index[]= SelectedGadgetItems(Explorer)

					For Local SelIndex =EachIn Index
					
						If Selindex > -1
						

							Local SelFileType$ = GetListBoxItem(Explorer,Selindex,1)
							
							If SelFileType$ Then ' it is a dir=FileTypes$[2]
								Local NewDir$=GadgetItemText(Explorer,Selindex)
								If NewDir = ".." Then
									Local SlashPos =CurrentDirectory$.FindLast( "/" )
									CurrentDirectory$=CurrentDirectory$[..(SlashPos)]
								Else
									CurrentDirectory$=CurrentDirectory$+"/"+NewDir
								EndIf								
								CurrentDirectory = CreateIconDirectory(CurrentDirectory)
								SetGadgetText(ExplorerWindow,CurrentDirectory)
								SetGadgetText(ExplorerDriveListCombo,CurrentDirectory[..Instr(CurrentDirectory,":")])
								NoDriveUpdate = True
								Exit
							EndIf						
						EndIf						
					Next
					
				Case ExplorerDriveListCombo
					If NoDriveUpdate Then
						NoDriveUpdate = False
					Else
						CurrentDirectory$=ComboBoxText(ExplorerDriveListCombo)
						CreateIconDirectory(CurrentDirectory)
						SetGadgetText(ExplorerWindow,CurrentDirectory)
					EndIf

				Case ExplorerThumbnailSizeCombo
				
					NewPicSize = Int(ComboBoxText(ExplorerThumbnailSizeCombo))

					If NewPicSize => 8 Then 
						If NewPicSize <> PicSize Then
							Local Ok = 1
							If  SelCount > 0 Then OK= Confirm("This will clear your current selection.",True)
							If OK Then
								PicSize = NewPicSize 
								CreateIconDirectory(CurrentDirectory)
								ClearGadgetItems(ExplorerSelectedListBox)
								SelCount = 0
SetGadgetText(ExplorerSelectedOrderButton,"Selected Pics")							
								
								SelThumbsPixmap=CreatePixmap(PicSize*SelectedMax,PicSize,PF_RGB888)
								SelThumbs:TIconStrip =LoadIconStrip(SelThumbsPixmap)' New TIconStrip 
							Else
								NewPicSize = PicSize
								SetGadgetText(ExplorerThumbnailSizeCombo,PicSize)
							EndIf
						EndIf	
					EndIf
					
				Case ExplorerSelectButton					
				
					Local index[]= SelectedGadgetItems(Explorer)
					
					For Local SelIndex =EachIn Index						
						If Selindex > -1 Then
							If  Selindex < SelectedMax Then
							Local SelFile$=GadgetItemText(Explorer,Selindex)
							'DebugLog SelIndex+" SelFile = "+SelFile + " SelCount = "+SelCount
							UpdateIconStrip(SelCount,SelIndex-DirCount+1)							
							AddGadgetItem(ExplorerSelectedListBox,Selfile,0,SelCount,CurrentDirectory$+"/"+SelFile$) 
							SetListBoxSort(ExplorerSelectedListBox,SelCount,Upper(SelFile$))
							SelCount:+1
							SetGadgetText(ExplorerSelectedOrderButton,"Selected Pics "+SelCount)
							Else
								Notify("Selection list full")
								Exit
							EndIf
							
						EndIf
					Next				
				Case ExplorerBackButton
					Local SlashPos =CurrentDirectory$.FindLast( "/" )
					CurrentDirectory$=CurrentDirectory$[..(SlashPos)]
					CreateIconDirectory(CurrentDirectory)
					SetGadgetText(ExplorerWindow,CurrentDirectory)
						
				Case ExplorerHightLightAllButton
					Local TotalItems = CountGadgetItems(Explorer)-1
					If TotalItems Then
						For Local count = 1  To TotalItems
							If GetListBoxItem(Explorer,count ,1) <>FileTypes$[2] Then  Explorer.SelectItem(count ,1 )
						Next
					EndIf
					
				Case ExplorerHightLightToggleButton
					Local TotalItems = CountGadgetItems(Explorer)-1
					If TotalItems Then
						For Local count = 1  To TotalItems
							Explorer.SelectItem(count ,2 )
						Next
					EndIf
					
				Case ExplorerSelectedListUpButton
				
					Local index[]= SelectedGadgetItems(ExplorerSelectedListBox)
					If index[0] > 0
						Local Item:TGadgetItem 
						For Local SelIndex =EachIn Index						
							If Selindex > 0 Then								
								Item = ExplorerSelectedListBox.items[SelIndex-1]
								ExplorerSelectedListBox.items[SelIndex-1] = ExplorerSelectedListBox.items[SelIndex]
								ExplorerSelectedListBox.SetListItem(Selindex-1,ExplorerSelectedListBox.items[SelIndex].text,ExplorerSelectedListBox.items[SelIndex].tip,ExplorerSelectedListBox.items[SelIndex].icon,ExplorerSelectedListBox.items[SelIndex].extra)
								ExplorerSelectedListBox.items[SelIndex] = Item
								ExplorerSelectedListBox.SetListItem(Selindex,item.text,item.tip,item.icon,item.extra)
								ExplorerSelectedListBox.SelectItem(Selindex ,0)					
								ExplorerSelectedListBox.SelectItem(Selindex-1 ,1)	
							EndIf
						Next		
						
					EndIf
					
				Case ExplorerSelectedListDownButton
				
					Local index[]= SelectedGadgetItems(ExplorerSelectedListBox)
					If index
						Local Item:TGadgetItem 
						Local MaxSelIndex = index.length-1
						If Index[MaxSelIndex] < CountGadgetItems(ExplorerSelectedListBox)-1 Then
							For Local SelIndex2 = MaxSelIndex  To 0 Step -1
								Local SelIndex = Index[SelIndex2]
								Item = ExplorerSelectedListBox.items[SelIndex+1]

								ExplorerSelectedListBox.items[SelIndex+1] = ExplorerSelectedListBox.items[SelIndex]
								ExplorerSelectedListBox.items[SelIndex] = Item
								
								ExplorerSelectedListBox.SetListItem(Selindex,item.text,item.tip,item.icon,item.extra)
								ExplorerSelectedListBox.SetListItem(Selindex+1,ExplorerSelectedListBox.items[SelIndex+1].text,ExplorerSelectedListBox.items[SelIndex+1].tip,ExplorerSelectedListBox.items[SelIndex+1].icon,ExplorerSelectedListBox.items[SelIndex+1].extra)

								ExplorerSelectedListBox.SelectItem(Selindex ,0)		
								ExplorerSelectedListBox.SelectItem(Selindex+1 ,1)

							Next	
							
						EndIf
						
					EndIf
					
				Case ExplorerSelectedListDeleteButton
					Local index[]= SelectedGadgetItems(ExplorerSelectedListBox)
					 Local SelIndex,DelCount
					If index
						Local Item:TGadgetItem ,DelCount
						For  SelIndex =EachIn Index	
							RemoveGadgetItem(ExplorerSelectedListBox,SelIndex- DelCount)
							DelCount:+1
						Next		
					EndIf
					SetGadgetText(ExplorerSelectedOrderButton,"Selected Pics "+(SelIndex- DelCount+1))				
				Case ExplorerSelectedOrderButton

					
				Case ExplorerPreviewButton
					PreviewFileName$=GadgetItemText(Explorer,SelectedGadgetItem(Explorer))
					If LastPreviewFileName$ <> PreviewFileName$ Then
						PreviewFile(PreviewFileName$)						
					Else
						HideGadget ExplorerPreviewWindow
						LastPreviewFileName$=""						
					EndIf
					
				Case ExplorerCancelButton 
					Exit
					
				Case ExplorerOkButton
					TotalPicsSelected = CountGadgetItems(ExplorerSelectedListBox)
					' The tip contains the full path
					For Local count = 0  To TotalPicsSelected -1
						Print count +". "+ExplorerSelectedListBox.items[count].text
						Print "   Path = "+ ExplorerSelectedListBox.items[count].tip
					Next
					
			EndSelect
			
			
		Case EVENT_GADGETMENU
			Select Gadget 
				Case Explorer
					PreviewFileName$=GadgetItemText(Explorer,SelectedGadgetItem(Explorer))
					If LastPreviewFileName$ <> PreviewFileName$ Then
						PreviewFile(PreviewFileName$)						
					Else
						HideGadget ExplorerPreviewWindow
						LastPreviewFileName$=""						
					EndIf
			EndSelect
			
				
		Case EVENT_WINDOWCLOSE
			Select gadget
				Case ExplorerPreviewWindow
					HideGadget ExplorerPreviewWindow
					LastPreviewFileName$=""
				Case ExplorerWindow
					Exit
			EndSelect
	End Select
Forever

EDIT:Updated code.

Cool! But there is a bug in the line:
					SetGadgetText(ExplorerSelectedOrderButton,"Selected Pics "+(SelIndex- DelCount+1))
Commenting it out, makes it work.

Thanks fredborg.
The code now is updated. I had declared variables in wrong pos.

Ziltch, how did you make the name of the file editable? I can't figure it out from the code.