C ++ How To Get system icons

Source: Internet
Author: User

Original Author: James Brown

Original Author: James Brown

Link: http://www.catch22.net/tuts/sysimg.asp

Original link: http://www.catch22.net/tuts/sysimg.asp

Click here to download the sample program and its source code

Note: The Chinese translation work in this article has been authorized by the original author James Brown. If you need to reprint it, please contact James himself.

The system image list (sometimes called shell Icon cache) is an icon resource maintained by Windows Shell, resource manager, and other applications.ProgramUse this list to display icons of system objects, programs, and file types. It is actually a simple himagelist (a list of standard images that can be accessed using the image list API). Some applications may find that the icons provided by the system are better, instead of storing copies of these icons internally. Therefore, the purpose of this tutorial is to explain how to access the image list of the system and use it in your application.

Simple Method

If you have never spent any time browsing msdn before, you may call the shgetfileinfo API (exported by shell32.dll and available for Win9x, winnt4, 2000, and XP ). This function looks like this:

Dword_ptr shgetfileinfo (
Lpctstr pszpath,
DWORD dwfileattributes,
Shfileinfo * psfi,
Uint cbfileinfo,
Uint uflags
);

This function can be used to obtain the information of a specified file. The uflags parameter specifies the specific information to be obtained. This parameter has two interesting values: shgfi_icon and shgfi_sysiconindex. After the two values are specified, shgetfileinfo returns the handle of the system image list and saves the corresponding icon-type index to the shfileinfo structure.

The following call demonstrates the possible usage:

 
Shfileinfo shfi;
Himagelist hsysimglist;
...
Hsysimglist = (himagelist) shgetfileinfo (
"C:",
0,
& Shfi,
Sizeof(Shfileinfo ),
Shgfi_sysiconindex | shgfi_smallicon | shgfi_icon );

Platform differences

There is a very small but important difference between Windows 9x and Windows NT operating systems. In Windows 9x, shgetfileinfo returns the system image list handle, which is shared by all processes. This image list is the same as the image list used by the resource manager and the image list used by the shell to display system icons. This means that if a process misoperations the image list, all processes (including resource managers) will be affected.

In Windows NT (and 2000/XP), it is slightly different. Because of the different system architecture, shgetfileinfo also maintains a stable operating environment. shgetfileinfo returns a separate copy for each process requesting the image list of the system. As described in detail, shgetfileinfo does not return a complete system image list like Windows 9x-only the icons requested in the shgetfileinfo call will appear in the returned image list. It does not matter in 99% cases, but because we want to create an application that browses the entire image list, this raises a question to us.

Locate the system image list in all Windows Versions

In a casual talk, there is an undisclosed API named shell_getimagelists in shell32.dll. You may have guessed that it will return the handle to the system image list (note the plural form of the function name, there are major icons and minor icons ). This undisclosed API in shell32.dll applies to all Windows versions.

 
Bool winapi shell_getimagelists (himagelist * lphimllarge, himagelist * lphimlsmall );

Another API we need is fileiconinit, which only applies to Windows NT/2000/XP. This is not a problem, because we only need to call it in Windows NT.

Bool winapi fileiconinit (bool bfullinit );

These APIs are not exported using the function name, but only the serial number:

 
//Shell32 undisclosed Functions
Shell_getimagelists @71
Fileiconinit @660

After obtaining this information, we can now write a function to return the handle of the system image list. The first step is to define two typedef to make our work easier.

 
Typedef bool (winapi * sh_gil_proc) (himagelist * phlarge, himagelist * phsmall );
Typedef bool (winapi * fii_proc) (bool ffullinit );

Sh_gil_proc is short for shell_geticonlists_procecedure. Similarly, fii_proc is short for fileiconinit_procedure. Now we can locate the undisclosed functions of shell32.dll for calling.

Hmodule hshell32;
Sh_gil_proc shell_getimagelists;
Fii_proc fileiconinit;

// Load shell32.dll, if it has not been loaded
Hshell32 = loadlibrary ( " Shell32.dll " );

If (Hshell32 = 0 )
Return False;

//
// Obtain undisclosed APIs from shell32.dll
//
Shell_getimagelists = (sh_gil_proc) getprocaddress (hshell32, (lpcstr) 71 );
Fileiconinit = (fii_proc) getprocaddress (hshell32, (lpcstr) 660 );

Please note how we pass the serial number parameter to getprocaddress. OK. Now we have obtained the required function pointer, which can be processed.

//Initialize the image list of this process-the function is unavailable under Win95/98
If(Fileiconinit! =0)
Fileiconinit (true );

//Obtain the system image list handle of large and small icons
Shell_getimagelists (phlarge, phsmall );

//Do not uninstall shell32.dll!

AboveCodeNote that "do not uninstall shell32.dll" is very important. As long as the shell32.dll is uninstalled, the system image list will be destroyed, so that all our previous work will be overwhelmed.

Never modify or delete the system image list!

Before proceeding, you should understand another important piece of information. You should never try to add or delete icons in the system image list, or delete the system image list. This is clearly explained in the shgetfileinfo document, and it is also a good comment. However, there is still a simple method to delete the system image list by mistake.

Now let's talk about this problem. By default, when a list view (listview) control is destroyed, it automatically calls the imagelist_destroy API to delete the associated image list. That is to say, by default, you even require your program to delete the system image list! -- Yes, that was the case at the time. Fortunately, the List View control has an lvs_shareimagelists style that prevents it from deleting its image list. (In this case, make sure you have set this style !)

The Treeview control does not cause this problem. msdn points out that the tree view does not destroy the list of associated images. Therefore, only the List View control requires special attention.
Obviously, if your program runs on Windows NT/2000/XP, accidentally deleting the system image list does not have serious consequences, because you just deleted the copy of the image list in your process. However, in Windows 95/98/Me, deleting this image list will have disastrous consequences. Try it if you don't believe it!

Conclusion

Obtaining a complete list of system images is tricky, especially if we have to extract icons from the cached icon file. Fortunately, this pair of undisclosed API functions can help us with these tasks. Of course, I can't keep my credit for discovering this. I found it on James Holderness's excellent website, where there is more information about the system image list than I mentioned here, there are more undisclosed good things. Now let's take a look!

Have a good time!

If you have any comments and suggestions, please send me an email: james@catch22.net

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.