(This seriesArticleOriginal by lemon (lc_mtt), reprinted please indicate the source, thank you ~)
Windows shell programming, that is, Windows shell programming. The resource manager and the entire desktop are a shell.
For more information about the basic concepts of Windows Shell, see the Windows Shell namespace browsing by Jiang Weihua.
Well, now let's start from the basics and make a powerful Resource Manager software as soon as possible. (I am also a beginner. Please advise me more)
1-Basic: browse a folder
We know thatWin32Is the shell namespaceTo organize the file system, every object in the shell namespace (Note) implementsIshellfolderThrough this interface, we can directly query or indirectly obtain other related interfaces.
(Note: the object here refers to a node in the shell namespace. The object may be a folder, a file, or a virtual folder. For example: my computer, network neighbors, control panel, etc)
In C #, we define the ishellfolder interface as follows:
Ishellfolder. CS
Using System;
Using System. Collections. Generic;
Using System. text;
Using System. runtime. interopservices;
Namespace Winshell
{
[Comimport]
[Interfacetype (cominterfacetype. interfaceisiunknown)]
[GUID ( " 000214e6-0000-0000-c000-000000000046 " )]
Public Interface Ishellfolder
{
}
}
Of course, this interface does not list detail functions. All we have to do is start with the basics.
First, we must understand that in shell programming, we should use pidl paths instead of normal paths (if you are not familiar with pidl, please refer to the Windows Shell namespace browsing ).
"Desktop" is the top-level folder, and other items in the shell namespace can be represented by pidl starting from "desktop.
To obtain the pidl and its ishellfolder interfaces of "desktop", you can use the shgetjavastopfolder API:
[Dllimport ( " Shell32.dll " )]
Public Static Extern Int32 shgetasktopfolder ( Out Intptr ppshf );
/**/ /// <Summary>
///Obtain the desktop Shell
/// </Summary>
Public Static Ishellfolder getasktopfolder ( Out Intptr ppshf)
{< br> shget1_topfolder ( out ppshf);
Object OBJ = marshal. getobjectforiunknown (ppshf);
return (ishellfolder) OBJ;
}
//Obtain desktop pidl
Intptr implements topptr;
Ishellfolder Desktop=Api. getmediatopfolder (OutDesktopptr );
All right, we get the ishellfolder interface of "desktop", and it's half done. Now I need to use "desktop" to obtain the pidl and ishellfolder interfaces of the path "C: \", which can be implemented through the parsedisplayname and bindtoobject functions of ishellfolder:
Void Parsedisplayname (
Intptr hwnd,
Intptr PBC,
[Financialas (unmanagedtype. lpwstr)] String Pszdisplayname,
Out Uint Pcheaten,
Out Intptr ppidl,
Ref Uint Pdwattributes );
Void Bindtoobject (
Intptr pidl,
Intptr PBC,
[IN ()] Ref Guid riid,
Out Ishellfolder GMM ); // Obtain pidl of drive C
String Folderpath = @" C :\ " ;
Intptr pidl = Intptr. zero;
Ishellfolder root;
Uint I, j = 0 ;
Desktop. parsedisplayname (handle, intptr. Zero, folderpath, Out I, Out Pidl, Ref J );
Desktop. bindtoobject (pidl, intptr. Zero, Ref Guids. iid_ishellfolder, Out Root );
The premise is that you should ensure that the path exists because I have not made any error control. In this way, we get a root, which indicates the C disk. With this root, we can use enumobjects to cyclically obtain its sub-items (subfolders and subfolders ):
[Preservesig]
Int Enumobjects (intptr hwnd, shcontf flags, Out Intptr enumidlist );
// Search pidl of files/folders under drive C cyclically
Ienumidlist fileenum = Null ;
Ienumidlist folderenum = Null ;
Intptr fileenumptr = Intptr. zero;
Intptr folderenumptr = Intptr. zero;
Intptr pidlsub;
Int Celtfetched;
// Obtain subfolders
If (Root. enumobjects ( This . Handle, shcontf. Folders | Shcontf. includehidden, Out Fileenumptr) = Api. s_ OK)
{
Fileenum = (Ienumidlist) Marshal. getobjectforiunknown (fileenumptr );
While (Fileenum. Next ( 1 , Out Pidlsub, Out Celtfetched) = 0 && Celtfetched = Api. s_false)
{
// Get display name
String Name = Api. getnamebypidl (pidlsub );
Lvfile. Items. Add (name, 1 );
}
}
// Obtain sub-Files
If (Root. enumobjects ( This . Handle, shcontf. nonfolders | Shcontf. includehidden, Out Folderenumptr) = Api. s_ OK)
{
Folderenum = (Ienumidlist) Marshal. getobjectforiunknown (folderenumptr );
While (Folderenum. Next ( 1 , Out Pidlsub, Out Celtfetched) = 0 && Celtfetched = Api. s_false)
{
StringName=Api. getnamebypidl (pidlsub );
Lvfile. Items. Add (name,0);
}
}
In fact,CodeThis ends. However, I found that too many struct and enumeration types are not introduced (more will be available in the future). If you are interested, you can check msdn by yourself. Otherwise, I will wait for the next section to introduce them.
At last, paste the graph and code. Next, we will introduce it in detail.
Source code:/Files/lemony/winshell.rar