(C #) Windows Shell shell programming Series 2-introduction, starting from "desktop"

Source: Internet
Author: User

(This seriesArticleOriginal by lemon (lc_mtt), reprinted please indicate the source, thank you ~)

Let's explain in detail some of the most basic functions, struct, and enumeration in shell programming.
Shgetasktopfolder
Get the ishellfolder interface of the desktop

[Dllimport ("shell32.dll")]
Public static extern int32 shgetdesktopfolder (Out intptr ppshf );

To use this function, you must first define an intptr pointer. Then, use the pointer to use getobjectforiunknown to return the pointer instance through the ishellfolder interface pointing to the COM object. Therefore, you need to write the following functions:

Public static ishellfolder getjavastopfolder (Out intptr ppshf)
{
Shgetasktopfolder (Out ppshf );
Object OBJ = marshal. getobjectforiunknown (ppshf );
Return (ishellfolder) OBJ;
}

Parsedisplayname
Obtain the pidl of an object, even if the object is in the bottom or more layers of the current directory in the directory tree. For example, for a file object, its resolution name is its path. We use the full path name of the file system object to call the parsedisplayname method of the ishellfolder interface on the desktop, it returns the complete pidl of this object. Definition:

Void parsedisplayname (
Intptr hwnd,
Intptr PBC,
[Financialas (unmanagedtype. lpwstr)] string pszdisplayname,
Out uint pcheaten,
Out intptr ppidl,
Ref uint pdwattributes );

The most important parameter is out intptr ppidl, which returns pidl corresponding to the specified path of pszdisplayname. However, pidl alone does not allow you to do more things. At this time, you also need to call bindtoobject to return the ishellfolder interface.
Bindtoobject
Create and initialize an ishellfolder object based on pidl. Definition:

Void bindtoobject (
Intptr pidl,
Intptr PBC,
[IN ()] ref guid riid,
Out ishellfolder GMM );

There is a [IN ()] ref guid riid parameter, indicating the interface identifier (IID ). GUID is actually a unique identifier. No two computers in the world will generate duplicate guid values. GUID is used to assign a unique identifier to a network or system with multiple nodes and computers. Here we use iid_ishellfolder to indicate that it obtains an ishellfolder interface.

Public static guid iid_ishellfolder = new GUID ("{000214e6-0000-0000-c000-000000000046 }");

In addition, the ienumidlist interface is introduced. The ienumidlist interface allows the resource manager to obtain the pidl of all objects contained in the folder. pidl can then be used to obtain information about these objects.
Therefore, we use the enumobjects function to return a pointer to the ienumidlist:

Int enumobjects (intptr hwnd, shcontf flags, out intptr enumidlist );

Among them, flags is the shcontf Enumeration type, which determines the enumerated content:

Shcontf
Public Enum shcontf
{
Folders = 0x20,
Nonfolders = 0x40,
Includehidden = 0x80,
Init_on_first_next = 0x100,
Netprintersrch = 0x200,
Retriable = 0x400,
Storage = 0x800
}

Therefore, we can use different flags to list sub-files and sub-directories. Here we will encounter a problem. How can we get the pidl Object Name. Two functions are written here. You can use pidl or ishellfolder to return the Object Name (For details, refer to the following section ):

Get name
/** // <Summary>
/// Obtain the display name
/// </Summary>
Public static string getnamebyishell (ishellfolder root, intptr pidlsub)
{
Intptr strr = marshal. alloccotaskmem (max_path * 2 + 4 );
Marshal. writeint32 (strr, 0, 0 );
Stringbuilder Buf = new stringbuilder (max_path );
Root. getdisplaynameof (pidlsub, shgno. infolder, strr );
Api. strrettobuf (strr, pidlsub, Buf, max_path );
Return Buf. tostring ();
}

/** // <Summary>
/// Obtain the display name based on pidl
/// </Summary>
Public static string getnamebypidl (intptr pidl)
{
Shfileinfo info = new shfileinfo ();
Api. shgetfileinfo (pidl, 0, ref info, Marshal. sizeof (typeof (shfileinfo )),
Shgfi. pidl | shgfi. displayname | shgfi. typename );
Return info. szdisplayname;
}

Example 2: Start with "desktop"
This example will give you an in-depth understanding of the previous content. This is an example that allows you to expand from the desktop to the deepest object.

Example 2
Public partial class sample2: Form
{
Private ishellfolder desktop;

Public sample2 ()
{
Initializecomponent ();
}

Private void form1_load (Object sender, eventargs E)
{
// Obtain the desktop pidl
Intptr implements topptr;
Desktop = API. getdesktopfolder (out of logs topptr );

// Add a desktop Node
Treenode tndesktop = new treenode ("desktop ");
Tndesktop. Tag = desktop;
Tndesktop. nodes. Add ("");

// Add the node to the tree
Tree1.nodes. Add (tndesktop );
Tndesktop. Expand ();
}

Private void treeappsbeforeexpand (Object sender, treeviewcanceleventargs E)
{
Determine whether the node has been expanded # region determine whether the node has been expanded
If (E. node. nodes. Count! = 1)
{
Return;
}
Else
{
If (E. node. firstnode. Text! = "")
{
Return;
}
}

E. node. nodes. Clear ();
# Endregion

Ishellfolder root = (ishellfolder) E. node. Tag;

// Search for Subitems cyclically
Ienumidlist Enum = NULL;
Intptr enumptr = intptr. zero;
Intptr pidlsub;
Int celtfetched;

If (root. enumobjects (this. Handle, shcontf. folders, out enumptr) = API. s_ OK)
{
Enum = (ienumidlist) Marshal. getobjectforiunknown (enumptr );
While (enum. Next (1, out pidlsub, out celtfetched) = 0 & celtfetched = API. s_false)
{
String name = API. getnamebyishell (root, pidlsub );
Ishellfolder isub;
Root. bindtoobject (pidlsub, intptr. Zero, ref guids. iid_ishellfolder, out isub );

Treenode nodesub = new treenode (name );
Nodesub. Tag = isub;
Nodesub. nodes. Add ("");
E. node. nodes. Add (nodesub );
}
}
}

Private void sample2_formclosing (Object sender, formclosingeventargs E)
{
// Release resources
Marshal. releasecomobject (desktop );
}

}

As shown in the following example:Source code:

Source code:/files/lemony/winshell2.rar

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.