1 include 
  2 {
  3    "grey.g"
  4    "..\\olecom\\olecom.g"
  5 }
  6 type ICONDIRENTRY
  7 {
  8    byte   bWidth
  9    byte   bHeight
 10    byte   bColorCount
 11    byte   bReserved
 12    ushort wPlanes
 13    ushort wBitCount
 14    uint   dwBytesInRes
 15    uint   dwImageOffset
 16 }
 17 
 18 type RESICONDIRENTRY
 19 {
 20    byte   bWidth
 21    byte   bHeight
 22    byte   bColorCount
 23    byte   bReserved
 24    ushort wPlanes
 25    ushort wBitCount
 26    uint   dwBytesInRes
 27    ushort nID
 28 }
 29 
 30 type ICONDIR
 31 {
 32    ushort idReserved//0 всегда 
 33    ushort idType   //1 для иконки, 2 для курсора
 34    ushort idCount  
 35    ICONDIRENTRY idEntries
 36 }
 37 
 38 type icsize
 39 {
 40    uint Width
 41    uint Height
 42 }
 43 
 44 type Image
 45 {
 46    uint hImage   
 47    uint hDisImage
 48    uint Width
 49    uint Height
 50    int  NumIml  
 51    int  PosInIml
 52    int  DisPosInIml
 53 }
 54 
 55 type ImageListIml
 56 {
 57    uint hIml
 58    uint Width
 59    uint Height  
 60    uint pImageList 
 61 }
 62 
 63 type ImageList <inherit=hash> //index=Image
 64 {
 65    arr arrIml of ImageListIml  
 66 }
 67 
 68 type ImageManager <inherit=hash index=ImageList>
 69 {
 70    str  pMainDir
 71    str  pCurName      
 72    hash FileIcons of uint 
 73    uint FileIconsIdx   
 74 }
 75 
 76 
 77 define {
 78 //   MAX_PATH = 260
 79    
 80    SHGFI_ICON              = 0x00000100
 81    SHGFI_SYSICONINDEX      = 0x00004000
 82    SHGFI_LARGEICON         = 0x00000000
 83    SHGFI_SMALLICON         = 0x00000001
 84    SHGFI_USEFILEATTRIBUTES = 0x00000010
 85 }
 86 
 87 type SHFILEINFO { 
 88     uint     hIcon
 89     int      iIcon 
 90     uint     dwAttributes
 91     reserved szDisplayName[ $MAX_PATH ]
 92     reserved szTypeName[ 80 ]
 93 }
 94 
 95 import "shell32.dll" {
 96    uint  SHGetFileInfoA( uint, uint, SHFILEINFO, uint, uint ) -> SHGetFileInfo
 97 }
 98 
 99 //-------------------------------------------------
100 
101 func uint shell_iconfile( str filename, uint large )
102 {
103    uint       reticon flag
104    SHFILEINFO shfi
105    str        ext
106       
107    flag = ?( large, $SHGFI_LARGEICON, $SHGFI_SMALLICON )
108    if SHGetFileInfo( filename.ptr(), 0 , shfi, sizeof( SHFILEINFO ),
109                      /*$SHGFI_SYSICONINDEX |*/ $SHGFI_ICON | flag )
110    {
111       return shfi.hIcon
112    } 
113    reticon = SHGetFileInfo( filename.ptr(), $FILE_ATTRIBUTE_NORMAL, shfi, sizeof( SHFILEINFO ), $SHGFI_SYSICONINDEX | $SHGFI_USEFILEATTRIBUTES | $SHGFI_ICON | flag )
114    return shfi.hIcon
115 }
116 
117 
118 
119 method ImageManager.init()
120 {
121    this->hash.oftype( ImageList )
122 }
123 
124 
125 method ImageList ImageList.init
126 {   
127    return this
128 }
129 
130 method Image.ReadFromFile( str filename )
131 {
132    /*uint hbmp 
133    hbmp = LoadImage( 0, filename.ptr(), $IMAGE_BITMAP, 0, 0, $LR_LOADFROMFILE | $LR_LOADTRANSPARENT )
134    if hbmp 
135    {
136       .hbmp = hbmp
137    }  */
138 }
139 
140 method Image.Clear()
141 {
142  //  if .hbmp : DeleteObject( .hbmp )
143 }
144 
145 method Image.delete()
146 {
147    DestroyIcon( .hImage )
148    DestroyIcon( .hDisImage )   
149 }
150 
151 
152 
153 method ImageListIml.delete()
154 {  
155    ImageList_Destroy( .hIml )
156 }
157 
158 method ImageList.delete()
159 {
160    //print( "ImageList \(&this) .Delete 1\n" )
161    foreach arrim, this
162    {      
163      //arrim as arr of Image
164      //print( "ImgList destroy \(arrim->uint)\n" )
165      if arrim->uint : destroy( arrim->uint )     
166      //getch() 
167    }
168    //print( "ImageList.Delete 2\n" )
169 }
170 
171 method ImageManager.delete
172 {
173    //print( "ImageManager.Delete \(&this)\n" )
174   // destroy( ImageList
175 }
176 
177 /*method ImageManager.LoadDir( str dir, str listname, uint flgclear )
178 {
179    uint il as this[listname]//->ImageList
180    
181       ffind fdi
182       fdi.init( "\( dir )\\*.ico", $FIND_FILE )      
183       foreach finfo ico, fdi
184       {         
185          uint arrim as ( il[ico.name]->arr of Image )
186          if !&arrim 
187          {
188             str name
189             ico.fullname.fgetparts( 0->str, name, 0->str )
190             arrim as new( arr, Image, 0 )->arr of Image
191             //print( "NEW ARRIM \(&il) \( &arrim ) )\n" )
192             //arrim.itype = Image
193             //arrim.isize = sizeof( Image )
194             arr arrim2 of Image
195             il[name] = &arrim
196          }
197          elif flgclear
198          {            
199             arrim.clear()
200          }         
201          buf bicon
202          bicon.read( ico.fullname )
203          uint header as bicon.data->ICONDIR
204          if !header.idReserved && header.idType == 1 
205          {
206             uint count = header.idCount
207             uint entry as header.idEntries
208             uint i, j
209             arr sizes of icsize                                    
210             fornum i=0, count 
211             {  //                
212                fornum j=0, *sizes
213                {
214                   if sizes[j].Width > entry.bWidth &&
215                      sizes[j].Height > entry.bHeight : break                     
216                }
217                sizes.insert( j )
218                sizes[j].Width = entry.bWidth
219                sizes[j].Height = entry.bHeight
220                entry as uint
221                entry += sizeof(ICONDIRENTRY)    
222             }            
223             
224             if !*il.arrIml
225             {
226                il.arrIml.expand(*sizes)               
227                fornum i=0, *sizes
228                {
229                   il.arrIml[i].hIml = ImageList_Create (
230                      sizes[i].Width, sizes[i].Height, 0x000000FF, 10, 10 )
231                   il.arrIml[i].Width = sizes[i].Width
232                   il.arrIml[i].Height = sizes[i].Height
233                   il.arrIml[i].pImageList = &il   
234                }
235             }
236             if *sizes > *arrim
237             {  
238                arrim.expand( *sizes - *arrim )
239             }            
240             fornum i=0, *sizes
241             {
242                if arrim[i].hImage : DestroyIcon( arrim[i].hImage )
243                
244                arrim[i].Width = sizes[i].Width
245                arrim[i].Height = sizes[i].Height                           
246                arrim[i].hImage = LoadImage( 0, ico.fullname.ustr().ptr(), $IMAGE_ICON, 
247                   sizes[i].Width, sizes[i].Height, $LR_LOADFROMFILE | $LR_DEFAULTCOLOR )
248                
249                ICONINFO II
250                GetIconInfo( arrim[i].hImage, II )                  
251                BitmapColorsToGrey( II.hbmColor, II.hbmMask, arrim[i].Width,arrim[i].Height)                  
252                arrim[i].hDisImage = CreateIconIndirect( II )                    
253                
254 //               print( "load image \(arrim.itype) \(arrim.isize) \(arrim[i].hImage) \( ico.fullname ) \(  arrim[i].Width ), \( arrim[i].Height)\n" )
255                arrim[i].PosInIml = -1                  
256                fornum j=0, *il.arrIml
257                {
258                   if il.arrIml[j].Width == sizes[i].Width &&
259                      il.arrIml[j].Height == sizes[i].Height 
260                   {                     
261                      arrim[i].PosInIml = 
262                         ImageList_ReplaceIcon( il.arrIml[j].hIml, -1, arrim[i].hImage )
263                      arrim[i].DisPosInIml = 
264                         ImageList_ReplaceIcon( il.arrIml[j].hIml, -1, arrim[i].hDisImage )                        
265                      arrim[i].NumIml = j                      
266                   }                       
267                }                                                                                       
268             }
269          }
270       }
271 }*/
272 method ImageList.SetIco( Image img, uint himage width height )
273 {
274    if img.hImage 
275    {      
276       DestroyIcon( img.hImage )
277       DestroyIcon( img.hDisImage )
278    }
279    img.Width = width
280    img.Height = height                           
281    img.hImage = himage
282    ICONINFO II
283    GetIconInfo( img.hImage, II )   
284    //print( "gi \(img.hImage) \(II.hbmColor), \(II.hbmMask)\n")
285    //if img.Width <= 100 || img.Height <= 100     
286    BitmapColorsToGrey( II.hbmColor, II.hbmMask, img.Width,img.Height)   
287    img.hDisImage = CreateIconIndirect( II )
288    //print( "li \(img.hImage) \(img.hDisImage)\n" )
289    //if !img.hDisImage : print( "Xerror \(GetLastError())\n" )                    
290    //               print( "load image \(arrim.itype) \(arrim.isize) \(img.hImage) \( ico.fullname ) \(  img.Width ), \( img.Height)\n" )
291    
292    DeleteObject( II.hbmColor )
293    DeleteObject( II.hbmMask )
294    img.PosInIml = -1   
295    uint j               
296    fornum j=0, *this.arrIml
297    {
298       if this.arrIml[j].Width == width &&
299          this.arrIml[j].Height == height 
300       {                     
301          img.PosInIml = 
302             ImageList_ReplaceIcon( this.arrIml[j].hIml, -1, img.hImage )
303          img.DisPosInIml = 
304             ImageList_ReplaceIcon( this.arrIml[j].hIml, -1, img.hDisImage )                        
305          img.NumIml = j
306                  
307       }                       
308    }
309 }
310 
311 method ImageList.LoadIco( str path, uint flgres, uint hmod, uint flgclear, str setname )
312 {
313    str name
314    if flgres : name = path
315    else 
316    {
317       if &setname : name = setname
318       else :  path.fgetparts( 0->str, name, 0->str )
319    }
320    uint arrim as ( this[name]->arr of Image )
321    if !&arrim 
322    {  
323       arrim as new( arr, Image, 0 )->arr of Image
324       arr arrim2 of Image
325       this[name] = &arrim
326    }
327    elif flgclear
328    {            
329       arrim.clear()
330    }         
331    buf bicon
332    if flgres 
333    {
334       uint handle = FindResource( hmod, path.ustr().ptr(), 14 )      
335       uint mem = LockResource( LoadResource( hmod, handle ))      
336       bicon.copy( mem, SizeofResource( hmod, handle ))
337    }
338    else : bicon.read( path )
339    if !*bicon: return 
340    uint header as bicon.data->ICONDIR
341    //print( "zzzzzzzz \(header.idReserved) \( header.idType ) \(header.idCount) \((&header.idCount+2)->uint)\n" )
342    if !header.idReserved && header.idType == 1 
343    {      
344       uint count = header.idCount
345       uint entry as header.idEntries
346       uint i, j
347       arr sizes of icsize                                    
348       fornum i=0, count 
349       {  //                
350          fornum j=0, *sizes
351          {
352             if sizes[j].Width > entry.bWidth &&
353                sizes[j].Height > entry.bHeight : break                     
354          }
355          sizes.insert( j )
356          sizes[j].Width = entry.bWidth
357          sizes[j].Height = entry.bHeight         
358          entry as uint          
359          if flgres : entry += sizeof(RESICONDIRENTRY)
360          else : entry += sizeof(ICONDIRENTRY)  
361       }            
362       if !*this.arrIml
363       {
364          this.arrIml.expand(*sizes)               
365          fornum i=0, *sizes
366          {
367             this.arrIml[i].hIml = ImageList_Create (
368                sizes[i].Width, sizes[i].Height, 0x000000FF, 10, 10 )
369             this.arrIml[i].Width = sizes[i].Width
370             this.arrIml[i].Height = sizes[i].Height
371             this.arrIml[i].pImageList = &this  
372          }
373       }
374       if *sizes > *arrim
375       {  
376          arrim.expand( *sizes - *arrim )
377       }
378       fornum i=0, *sizes
379       {
380          .SetIco( arrim[i], LoadImage( ?( hmod, hmod, GetModuleHandle( 0 )), path.ustr().ptr(), $IMAGE_ICON, 
381             sizes[i].Width, sizes[i].Height, ?( flgres, 0, $LR_LOADFROMFILE ) | $LR_DEFAULTCOLOR ), sizes[i].Width, sizes[i].Height )
382       }
383    }     
384 }
385 
386 method ImageManager.LoadDir( str dir, str listname, uint flgclear )
387 {
388    uint il as this[listname]//->ImageList
389    
390    ffind fdi
391    fdi.init( "\( dir )\\*.ico", $FIND_FILE )      
392    foreach finfo ico, fdi
393    {         
394       il.LoadIco( ico.fullname, 0, 0, flgclear, 0->str )
395    }
396 }
397 
398 import "Oleaut32.dll"
399 {   
400    uint OleLoadPicturePath( uint, uint, uint, uint, uint, uint )
401 }
402 global {
403 buf IID_IPicture = '\h4 7BF80980 \h2 BF32 101A \h 8B BB 00 AA 00 30 0C AB'
404 }
405 
406 //global { uint ppv }
407 method uint ImageList.LoadPicture( str path, str name, uint flgclear, uint flgaddimagelist )
408 {
409    uint ppv
410    uint res
411    buf  un
412       
413    if ole.flginit 
414    {           
415       res = OleLoadPicturePath( un.unicode( path ).ptr(), 0, 0, 0, IID_IPicture.ptr(), &ppv )      
416       if !(res & 0x80000000) && ppv
417       {      
418          uint handle
419          BITMAP bmpinfo         
420          handle = 0
421          ((ppv->uint + 12)->uint)->stdcall(ppv, &handle)
422          
423          GetObject(handle,sizeof(BITMAP),&bmpinfo)
424          
425          uint width = bmpinfo.bmWidth
426          uint height = bmpinfo.bmHeight         
427          uint arrim as ( this[name]->arr of Image )
428          if !&arrim 
429          {  
430             arrim as new( arr, Image, 0 )->arr of Image            
431             this[name] = &arrim
432          }
433          elif flgclear
434          {            
435             arrim.clear()
436          }
437          if !*this.arrIml
438          {         
439             this.arrIml.expand(1)
440             this.arrIml[0].hIml = ImageList_Create (
441                   width, height, 0x000000FF, 10, 10 )
442             this.arrIml[0].Width = width
443             this.arrIml[0].Height = height
444             this.arrIml[0].pImageList = &this
445          }
446          /*fornum i = 0, *arrim
447          {
448             if arrim[i].Width == width &&
449                arrim[i].Height == height
450             {
451                break
452             }
453             if arrim[i].Width >= width &&
454                arrim[i].Height > height
455          }*/
456          /*if *sizes > *arrim
457          {  
458             arrim.expand( *sizes - *arrim )
459          }*/
460          if !*arrim : arrim.expand(1) 
461          ICONINFO II
462          II.fIcon = 1
463          II.hbmColor = handle
464          
465          buf bits
466          uint w
467          bits.reserve( w = (( width +15 / 16 ) * height * 2))//*( width / 8 + ?(( width % 8 ),1,0 )) * height * 2*/ )
468          mzero( bits.data, w )
469          /*uint i
470          fornum i = 0, w
471          {
472             //bits[i] = 0//0xAA
473             if bits[i] : print("\(i) XXX\n" )
474          }*/
475          II.hbmMask = CreateBitmap( width, height, 1, 1, bits.ptr() )         
476          handle=CreateIconIndirect( II )
477          DeleteObject( II.hbmMask )
478          DeleteObject( II.hbmColor )
479          ((ppv->uint + 8)->uint)->stdcall(ppv)         
480          //arrim[0].hImage = handle
481          .SetIco( arrim[0], handle , width, height )
482          return handle                                                   
483       }
484    }
485    return 0
486 }
487 
488 
489 method uint ImageManager.LoadImg( str filename, str listname, str imgname )
490 {
491    uint il as this[listname]
492    
493    str ext
494    filename.fgetparts( 0->str, 0->str, ext )
495    if ext == "ico"
496    {      
497       il.LoadIco( filename, 0, 0, 1, imgname )
498       return 1
499    }
500    else
501    {
502       return il.LoadPicture( filename, imgname, 1, 0 )
503    }
504       
505 }
506 
507 
508 type EnumResInfo
509 {
510    uint imagelist
511    uint flgclear
512 }
513 
514 func uint EnumResNameProc( uint hModule, uint lpszType, uint lpszName, uint lParam )
515 {
516    uint il as lParam->EnumResInfo.imagelist->ImageList
517    ustr  s   
518    if lpszName > 0xFFFF 
519    {
520       s.copy( lpszName )
521    }
522    else : s = "#" + str( lpszName ) 
523    il.LoadIco( s.str(), 1, hModule, lParam->EnumResInfo.flgclear, 0->str )      
524    return 1
525 }
526 
527 
528 method ImageManager.LoadRes( str filename, str listname, uint flgclear )
529 {
530    uint hres
531    EnumResInfo eri
532    eri.imagelist = &this[listname]
533    eri.flgclear = flgclear 
534    
535    if *filename 
536    {       
537       hres = LoadLibraryEx( filename.ptr(), 0, 0x00000002/*$LOAD_LIBRARY_AS_DATAFILE*/ )
538       if !hres : return	
539    }   
540    EnumResourceNames( hres, 14, callback(&EnumResNameProc,4), &eri )      
541    if hres : FreeLibrary( hres )
542 }
543 
544 
545 method ImageManager.LoadFileIcons( str listname )
546 {
547    uint imagelist as this[listname]
548    .FileIcons.ignorecase()
549    .FileIcons[ "exe" ]   = 0xFFFFFFFF
550    .FileIcons[ "pif" ]   = 0xFFFFFFFF
551    .FileIcons[ "lnk" ]   = 0xFFFFFFFF
552    .FileIcons[ "ico" ]   = 0xFFFFFFFF
553    .FileIcons[ "drive" ] = 0xFFFFFFFE
554       
555    if !*imagelist.arrIml
556    {
557       imagelist.arrIml.expand(2)
558       uint size = 16     
559       uint i          
560       fornum i=0, 2
561       {         
562          imagelist.arrIml[i].hIml = ImageList_Create (
563             size, size, 0x000000FF, 10, 10 )
564          imagelist.arrIml[i].Width = size 
565          imagelist.arrIml[i].Height = size
566          imagelist.arrIml[i].pImageList = &this
567          size *= 2  
568       }
569    }
570 }
571 
572 method ImageManager.Load( str name, uint flgclear )
573 {
574    ffind fd
575    fd.init( "\(.pMainDir)\\\(name)\\*", $FIND_DIR )
576    foreach finfo cur, fd
577    {
578       .LoadDir( cur.fullname, cur.name, flgclear )
579       /*if !&il 
580       {         
581          il as new( ImageList )->ImageList    
582          this[cur.name] = &il
583       }
584       el*/      
585       /*if flgclear
586       {      
587          
588          il.arrIml.clear()
589       }  */    
590       
591       /*foreach arrim, il
592       {         
593         //arrim as arr of Image
594         uint x = arrim->uint
595         print( "ImgList Check \(arrim->uint) \(x)\n" )
596         //destroy( &arrim )     
597         getch() 
598       }*/
599    }   
600    //.LoadRes( $"C:\Delphi7\Bin\delphi32.exe", "resources", flgclear )
601    //.LoadRes( $"K:\Gentee\Open Source\gentee\exe\gentee2.exe", "resources", flgclear )
602    //.LoadRes( $"K:\main.exe", "resources", flgclear )
603    .LoadRes( "", "resources", flgclear )
604    .LoadFileIcons( "files" )
605    //.LoadRes( $"C:\Program Files\7-Zip\7zFM.exe", "resouces", flgclear )
606    
607 }
608 
609 property str ImageManager.CurName <result>
610 {
611    result = .pCurName
612 }
613 
614 property ImageManager.CurName( str value )
615 {
616    if value != .pCurName
617    {
618       //this.Clear()
619       .Load( "default", 1 )
620       //.Load( value, 0 )
621    }
622 }
623 
624 property str ImageManager.MainDir <result>
625 {
626    result = .pMainDir
627 }
628 
629 property ImageManager.MainDir( str value )
630 {
631    if value != .pMainDir
632    {
633       //this.Clear()
634       .pMainDir = value
635    }
636 }
637 
638 method Image ImageManager.GetImage( ustr name )
639 {
640 //   print( "GetImage\n" )
641    arrstr path 
642    str sname = name
643    sname.split( path, '\', 0 )   
644    if *path == 2
645    {  
646 //   print( "b \(path[0])\n" )
647       uint il as this.find(path[0])->ImageList      
648       if &il
649       {  
650          sname = path[1]
651          sname.split( path, '[', 0 ) 
652          uint im as il[path[0]]->arr of Image
653          if &im
654          {     
655             uint idx  
656             if *path == 2
657             {                 
658                idx = min( max( 0, int( path[1] ) ), *im )
659             }  
660             return im[idx]
661          }
662       }      
663    }
664    return 0->Image
665 }
666 
667 method uint ImageManager.GetImageNum( ustr name, uint width, uint height )
668 {
669    arrstr path 
670    str sname = name
671    sname.split( path, '\', 0 )   
672    if *path == 2
673    {
674       uint il as this.find(path[0])->ImageList      
675       if &il
676       { 
677          uint im as il[path[1]]->arr of Image
678          uint i
679          fornum i, *im
680          {            
681             if im[i].Width == width && im[i].Height == height
682             {
683                return i
684             } 
685          }         
686       }      
687    }
688    return -1
689 }
690 
691 method int ImageList.GetImageIdx( uint numiml, ustr name, uint disabled )
692 {
693 //print( "GetImageIdx\n" )
694    if &this && *name
695    {        
696       uint arrim as this[name.str()]->arr of Image      
697       if &arrim 
698       {  
699          if numiml < *arrim
700          { 
701             uint i
702             fornum i = 0, *arrim
703             {
704                if arrim[i].NumIml == numiml
705                {           
706                   if disabled : return arrim[i].DisPosInIml
707                   else : return arrim[i].PosInIml
708                }
709             }
710          }         
711       }
712    }
713    return -1
714 }
715 
716 method ImageList ImageManager.GetImageList( ustr name, uint pnumiml )
717 {
718 //print( "GetImageList\n" )
719    arrstr path
720    str sname = name   
721    sname.split( path, '\', 0 )
722    if *path == 1
723    {      
724       sname = path[0]
725       sname.split( path, '[', 0 )      
726       uint il as this.find(path[0])->ImageList      
727       if &il
728       {   
729          uint num 
730          if *path > 1 : num= min( uint( path[1] ), *il.arrIml - 1 )
731          if pnumiml: pnumiml->uint = num
732          return il
733       }
734    }
735    return 0->ImageList
736 }
737 
738 
739 method str ImageManager.GetFileIcon<result>( str filename )
740 {
741    uint  hicon 
742    str   ext fname
743    uint  ret i// x y
744       
745    filename.fgetparts( 0->str, 0->str, ext )
746    
747    ret = .FileIcons[ ext ]
748 
749    if ret && ret < 0xFFFFFFF0 : goto end
750 
751    if ret == 0xFFFFFFFF
752    {
753       if .FileIcons.find( filename ) 
754       {
755          ret = .FileIcons[ filename ]
756          goto end
757       }
758    }
759    elif ret == 0xFFFFFFFE
760    {
761       filename = filename.fsetext( filename, 0->str )
762       if .FileIcons.find( filename ) 
763       {
764          ret = .FileIcons[ filename ]
765          goto end
766       }
767    }
768    result = .FileIconsIdx.str()
769    uint imagelist as this[ "files"]
770    uint arrim as ( imagelist[.FileIconsIdx.str()]->arr of Image )
771    if !&arrim 
772    {  
773       arrim as new( arr, Image, 0 )->arr of Image
774       imagelist[result] = &arrim
775    }
776    /*elif flgclear
777    {            
778       arrim.clear()
779    }*/
780    uint size = 16
781    if 2 > *arrim
782    {  
783       arrim.expand( 2 - *arrim )
784    }
785    fornum i=0, 2
786    {
787       uint hicon
788       imagelist.SetIco( arrim[i], hicon = shell_iconfile( filename, i ), size, size )
789       //DestroyIcon( hicon )
790       size *= 2      
791    }
792    
793    if !ret : .FileIcons[ ext ] = .FileIconsIdx
794    else : .FileIcons[ filename ] = .FileIconsIdx
795    .FileIconsIdx++
796 
797    return 
798 label end    
799    result = ret.str()  
800 }