🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.cppbuilder.nativeapi
15 messages
15 total messages Started by Jeff Wed, 07 Jun 2006 18:11
System Icons
#3519
Author: Jeff
Date: Wed, 07 Jun 2006 18:11
2 lines
1038 bytes
I've got a TListView component and would like to assign icons to its items 
from the shell32.dll.  Any way to get the icons from system libraries? 
Re: System Icons
#3520
Author: Remy Lebeau (TeamB)
Date: Wed, 07 Jun 2006 18:45
14 lines
1350 bytes
"Jeff" <Jeff@nospam.com> wrote in message
news:448716d6$1@newsgroups.borland.com...

> I've got a TListView component and would like to assign icons
> to its items from the shell32.dll.  Any way to get the icons from
> system libraries?

Use the Win32 API SHGetFileInfo() function to retreive a handle to the
Shell's Image List.  You can then assign that handle to a TImageList.  Make
sure the TImageList's SharedImages property to set to true.


Gambit
Re: System Icons
#3521
Author: Jeff
Date: Wed, 07 Jun 2006 19:53
26 lines
1690 bytes
I only got 5 icons out of it when it contians 238?

Is this right?
SHFILEINFO fInfo;
imlMain->Handle = SHGetFileInfo("c:\\windows\\system32\\shell32.dll", NULL, 
&fInfo, sizeof(fInfo), SHGFI_SYSICONINDEX);

"Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message 
news:448720b8$1@newsgroups.borland.com...
>
> "Jeff" <Jeff@nospam.com> wrote in message
> news:448716d6$1@newsgroups.borland.com...
>
>> I've got a TListView component and would like to assign icons
>> to its items from the shell32.dll.  Any way to get the icons from
>> system libraries?
>
> Use the Win32 API SHGetFileInfo() function to retreive a handle to the
> Shell's Image List.  You can then assign that handle to a TImageList. 
> Make
> sure the TImageList's SharedImages property to set to true.
>
>
> Gambit
>
> 
Re: System Icons
#3522
Author: Remy Lebeau (TeamB)
Date: Wed, 07 Jun 2006 19:55
15 lines
1181 bytes
"Jeff" <Jeff@nospam.com> wrote in message
news:44872e9b$1@newsgroups.borland.com...

> Is this right?

Try this instead:

    SHFILEINFO fInfo = {0};
    imlMain->Handle = SHGetFileInfo("", 0, &fInfo, sizeof(fInfo),
SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
    imlMain->SharedImages = true;


Gambit
Re: System Icons
#3523
Author: Jeff
Date: Wed, 07 Jun 2006 21:54
21 lines
1525 bytes
Now I seem to still get 5 icons, but some are different than before?

"Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message 
news:44872fa9@newsgroups.borland.com...
>
> "Jeff" <Jeff@nospam.com> wrote in message
> news:44872e9b$1@newsgroups.borland.com...
>
>> Is this right?
>
> Try this instead:
>
>    SHFILEINFO fInfo = {0};
>    imlMain->Handle = SHGetFileInfo("", 0, &fInfo, sizeof(fInfo),
> SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
>    imlMain->SharedImages = true;
>
>
> Gambit
>
> 
Re: System Icons
#3524
Author: Remy Lebeau (TeamB)
Date: Wed, 07 Jun 2006 22:15
14 lines
1572 bytes
"Jeff" <Jeff@nospam.com> wrote in message
news:44874af9$1@newsgroups.borland.com...

> Now I seem to still get 5 icons, but some are different than before?

The code I have given you retrieves the entire System Image List.  It is
certainly not limited to 5 icons.  When I just tested the code, the image
list had 404 icons in it, as reported by the TImageList::Count property.
Please show your actual code for how you are using the ImageList.  What does
the Count report for you?


Gambit
Re: System Icons
#3525
Author: Jeff
Date: Wed, 07 Jun 2006 22:25
38 lines
2338 bytes
Code for image list (called in FormCreate):
SHFILEINFO fInfo = {0};

imlMainSmall->Handle = SHGetFileInfo("", 0, &fInfo, 
sizeof(fInfo),SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
imlMainSmall->ShareImages = true;

Test code for image display (called in FormShow):
for (int intIndex = 0; intIndex < imlMainSmall->Count; intIndex++)
 {
  lsiItem = lsvDrives->Items->Add();
  lsiItem->Caption = IntToStr(intIndex);
  lsiItem->ImageIndex = intIndex;
 }

Are there any properties to the TImageList, other than ShareImages, that I 
should be concerned with?


"Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message 
news:44875092$1@newsgroups.borland.com...
>
> "Jeff" <Jeff@nospam.com> wrote in message
> news:44874af9$1@newsgroups.borland.com...
>
>> Now I seem to still get 5 icons, but some are different than before?
>
> The code I have given you retrieves the entire System Image List.  It is
> certainly not limited to 5 icons.  When I just tested the code, the image
> list had 404 icons in it, as reported by the TImageList::Count property.
> Please show your actual code for how you are using the ImageList.  What 
> does
> the Count report for you?
>
>
> Gambit
>
> 
Re: System Icons
#3526
Author: Remy Lebeau (TeamB)
Date: Wed, 07 Jun 2006 22:49
22 lines
1893 bytes
"Jeff" <Jeff@nospam.com> wrote in message
news:44875268$1@newsgroups.borland.com...

> Code for image list (called in FormCreate):

DO NOT use the OnCreate event in C++!  It is a Delphi idiom that does not
work reliably in C++ as it can be triggered before the constructor, which is
illegal.  Use the actual constructor instead, or else delay the code until
after the form is fully created.

The same goes for the OnDestroy event - is can be triggered after the
destructor, which is illegal, so never use the OnDestroy event in C++
either.

> Are there any properties to the TImageList, other than ShareImages,
> that I should be concerned with?

No.


Gambit
Re: System Icons
#3527
Author: Jeff
Date: Wed, 07 Jun 2006 23:19
34 lines
2215 bytes
Thanks for letting me know about FormCreate, I'll be sure to use the 
constructor/destructor from now on.

Unfortunately I'm still only getting 5 icons in the list, is there some 
other method to retrieve these system icons that I can use?


"Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message 
news:4487589c$1@newsgroups.borland.com...
>
> "Jeff" <Jeff@nospam.com> wrote in message
> news:44875268$1@newsgroups.borland.com...
>
>> Code for image list (called in FormCreate):
>
> DO NOT use the OnCreate event in C++!  It is a Delphi idiom that does not
> work reliably in C++ as it can be triggered before the constructor, which 
> is
> illegal.  Use the actual constructor instead, or else delay the code until
> after the form is fully created.
>
> The same goes for the OnDestroy event - is can be triggered after the
> destructor, which is illegal, so never use the OnDestroy event in C++
> either.
>
>> Are there any properties to the TImageList, other than ShareImages,
>> that I should be concerned with?
>
> No.
>
>
> Gambit
>
> 
Re: System Icons
#3528
Author: Remy Lebeau (TeamB)
Date: Thu, 08 Jun 2006 00:20
21 lines
1877 bytes
"Jeff" <Jeff@nospam.com> wrote in message
news:44875ef3$1@newsgroups.borland.com...

> Unfortunately I'm still only getting 5 icons in the list

That should not be possible.  The System Image List contains hundreds of
icons used all over the OS.  If your Image List really only had 5 icons
available, your machine's UI would look very empty.

> is there some other method to retrieve these system icons that I can use?

The only other way is to pull them out of the DLL's resources directly.  But
I would not recommend that.

Which version of BCB are you actually using?  I can send you
TImageList-descendant component that I wrote awhile back for accessing the
System Image List.


Gambit
Re: System Icons
#3533
Author: Mike Collins
Date: Thu, 08 Jun 2006 09:59
9 lines
1667 bytes
Hi Remy, very strange this - I tried exactly the same code that you posted 
above and I only get 5 icons returned....  Using BCB 6 enterprise on Win2k3.

Just out of interest, is the positioning of each icons in the image list 
constant or may it change from version to version, machine to machine?


"Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message 
news:44876da8@newsgroups.borland.com... 
Re: System Icons
#3435
Author: Jeff
Date: Thu, 08 Jun 2006 13:59
7 lines
1534 bytes
> Which version of BCB are you actually using?  I can send you
> TImageList-descendant component that I wrote awhile back for accessing the
> System Image List.

I'm using BDS 2006 Update 2 on a Windows XP SP2 machine.  I also have BCB6 
update 4 on this machine, I used the exact same code and BCB6 retrieved only 
5 icons as well. 
Re: System Icons
#3437
Author: Remy Lebeau (TeamB)
Date: Thu, 08 Jun 2006 17:20
49 lines
3451 bytes
"Mike Collins" <its@TheBottomOfThePost.com> wrote in message
news:4487f50f@newsgroups.borland.com...

> Hi Remy, very strange this - I tried exactly the same code that you
> posted above and I only get 5 icons returned....  Using BCB 6
> enterprise on Win2k3.

Interesting.  The latest OS I have access to is XP SP2.  Sure enough, it
does only return 5 icons.

Further investigation reveils that each process gets its own copy of the
system image list, not the original.  Once created, newer OS versions lazily
add icons to the list on an as-needed basis.  It would appear that the image
list is initialized with a few icons by default.  If you don't request a
specific icon afterwards, it is not added to the list.  So, as a test, using
the code I showed earlier, I added a second call to SHGetFileInfo() to get
the icon for a specific file type after the TImageList Handle was
initialized:

    SHFILEINFO fi = {0};
    DWORD flags = SHGFI_SYSICONINDEX | SHGFI_SMALLICON;
    ImageList1->Handle = SHGetFileInfo("", 0, &fi, sizeof(fi), flags);
    ImageList1->ShareImages = true;
    SHGetFileInfo("test.xml", 0, &fi, sizeof(fi), flags |
SHGFI_USEFILEATTRIBUTES | SHGFI_TYPENAME);

Sure enough, the ImageList::Count property grew to 6 to include the icon for
.xml files.  So the solution is to request specific icons in order to
populate the system image list with them.

Which, when you thik about it, makes sense.  If you are populating a
TListBox or TListView or any other icon-enabled component, you should know
the type of items that you are adding to the list.  In order to set the
ImageIndex for each item, you have to call SHGetFileInfo() to get each
item's index in the image list.  Different item types may be sharing common
icons.  So, when you call SHGetFileInfo() for each item to get its proper
index, SHGetFileInfo() will ensure that the icon actually exists in the
image list before returning its index.

> Just out of interest, is the positioning of each icons in the image
> list constant or may it change from version to version, machine
> to machine?

It is not constant.  That is why the SHFILEINFO structure has an iIcon
member, so that you can retreive the current index of an item.


Gambit
Re: System Icons
#3436
Author: Remy Lebeau (TeamB)
Date: Thu, 08 Jun 2006 17:20
12 lines
1467 bytes
"Jeff" <Jeff@nospam.com> wrote in message
news:44882d49$1@newsgroups.borland.com...

> I'm using BDS 2006 Update 2 on a Windows XP SP2 machine.  I also
> have BCB6 update 4 on this machine, I used the exact same code and
> BCB6 retrieved only 5 icons as well.

See my reply to Mike.


Gambit
Re: System Icons
#3440
Author: Mike Collins
Date: Fri, 09 Jun 2006 09:10
54 lines
2861 bytes
So in reply to your orginal posting, and based on what seems to have 
transpired using SHGetFileInfo(), it would seem that access the icons 
directly from the dll.  You will have to use LoadLibrary on the shell32.dll 
and then use the HINSTANCE that is returned as the handle in any calls to 
image loading api's or vcl functions.  This will also require you to know 
the resource ID for the icons in question but this seems to have remained 
pretty much constant from one shell32 version to another.  These ID's can be 
determined using some sort of resource hacker to such as ExeScope or 
ResHacker.

Code would look something like this:

    HINSTANCE hShell = LoadLibrary("shel32.dll");
    if (hShell)
    {
        Graphics::TIcon   *icoContainer = NULL;
        try
        {
            try
            {
                icoContainer = new Graphics::TIcon();
                istImageList->Height = 32;
                istImageList->Width = istImageList->Height

                icoContainer->Handle = LoadImage(hShell , 
MAKEINTRESOURCE(ICON_RES_ID), IMAGE_ICON, 32, 32, LR_DEFAULTSIZE);
                istImageList->AddIcon(icoContainer);
                ...
                ...
                // repeat for each icon the you need, adjusting the 
ICON_RES_ID accordingly
            }
            catch (...)
            {
            }
        }
        __finally
        {
            if (icoContainer)
            {
                delete icoContainer;
                icoContainer = NULL;
            }
            FreeLibrary(hShell);
        }

HTH, Mike C


"Jeff" <Jeff@nospam.com> wrote in message 
news:448716d6$1@newsgroups.borland.com...
> I've got a TListView component and would like to assign icons to its items 
> from the shell32.dll.  Any way to get the icons from system libraries?
> 
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads