⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cb199910dc_f.asp.htm

📁 C++builder学习资料C++builder
💻 HTM
📖 第 1 页 / 共 5 页
字号:
style='mso-bidi-font-style:normal'>SHGetDesktopFolder</i> method is used to get     

a pointer to this interface. Initially, this pointer is bound to the Desktop     

folder, which is, in fact, the root folder of the shell. All other folders are     

referenced relative to this root folder. Several methods of the <i     

style='mso-bidi-font-style:normal'>IShellFolder</i> interface will be used     

throughout our implementation. (The reader is referred to <i>OLE     

Programmer's Reference</i>, available as online help with C++Builder, for a complete description of each     

of these methods.) The ones used will be described as needed. For now, think of     

the <i>IShellFolder</i> interface as a     

simple class with several member functions used to manipulate shell folders.     

None of these objects are real classes; they're C++ structures, where each     

"method" is a virtual function. </p>     

     

<p class=BodyText> &nbsp; </p>     

     

<p class=BodyText> Other     

interfaces of interest include <i>IEnumIDList</i>,     

<i>IContextMenu</i>, and <i     

style='mso-bidi-font-style:normal'>IContextMenu2</i>. As the name implies, the <i     

style='mso-bidi-font-style:normal'>IEnumIDList</i> interface is used to     

enumerate items in a given folder. The advantage is that this interface can be     

used with virtual folders, as well as standard file folders. Similarly, the <i     

style='mso-bidi-font-style:normal'>IContextMenu</i> and <i>IContextMenu2</i> interfaces are used to handle an object's context     

menu. Each of these interfaces will return a pointer of a specific type. For     

example, the <i>SHGetMalloc</i> function     

returns a long pointer to the <i>IMalloc</i>     

interface (LPMALLOC). Similarly, the LPSHELLFOLDER is a pointer to the <i     

style='mso-bidi-font-style:normal'>IShellFolder</i> interface. </p>     

     

<p class=BodyText> &nbsp; </p>     

     

<p class=BodyText> There     

are several data types that are commonly used when working with the shell     

namespace. The one of primary concern is the ITEMIDLIST (item identifier list)     

and its corresponding pointer, LPITEMIDLIST. This pointer is abbreviated as     

PIDL (pronounced "piddle"). A PIDL is nothing more than a pointer to an item     

identifier list. As you may have guessed, an item identifier list (ID list) is     

nothing more than a list of IDs (of the type SHITEMID). Each SHITEMID uniquely     

identifies an object in that object's parent folder. A list of these IDs     

identifies an object within the shell namespace. </p>     

     

<p class=BodyText> &nbsp; </p>     

     

<p class=BodyText> While     

item identifiers are used by the shell, they are never actually seen by the     

user. It would be quite difficult to identify a list of files based solely on     

their corresponding item ID. Instead, the shell uses display names for each     

file object. Keep in mind that the term <i>file object</i> refers to any item     

in the shell, including printers and Control Panel applications. </p>     

     

<p class=BodyText> &nbsp; </p>     

     

<p class=BodyText> Like     

paths, PIDLs come in two flavors: relative and absolute. Direct descendants of     

the Desktop, such as My Computer and Network Neighborhood, have absolute PIDLs;     

they only contain one SHITEMID (see the <i>EnumDeskVB</i>     

example project at <a href="javascript:if(confirm('http://www.mvps.org/btmtz/  \n\nThis file was not retrieved by Teleport Pro, because it is addressed on a domain or path outside the boundaries set for its Starting Address.  \n\nDo you want to open it from the server?'))window.location='http://www.mvps.org/btmtz/'" tppabs="http://www.mvps.org/btmtz/">http://www.mvps.org/btmtz/</a>).     

Although in reality they're relative to the Desktop folder, they're called     

absolute because the Desktop folder is the root folder, and their parent folder     

is the Desktop. The Control Panel's PIDL, on the other hand, is not absolute because     

its parent folder is My Computer. Similarly, a file object in the Control Panel     

has a PIDL relative to the Control Panel. Because the Desktop folder is also     

the root folder, its PIDL only contains one SHITEMID of size zero. </p>     

     

<p class=BodyText> &nbsp; </p>     

     

<p class=BodyText> Working     

with PIDLs isn't always straightforward. Although there are several standard     

functions and methods that can be used to parse or concatenate strings, there     

are none for working with PIDLs. (That statement isn't entirely correct; there     

are many undocumented functions exported from shell32.dll that are designed to     

work with PIDLs. We'll discuss the undocumented features in a later section.)     

For now, we need to construct some functions that will make working with PIDLs     

easier. <a href="#ListingOne">Listing One</a>     

shows helper functions that make it easier to use PIDLs. </p>     

     

<p class=BodyText> &nbsp; </p>     

     

<p class=Subheads>Using the     

Shell Namespace to Fill the ListView</p>     

     

<p class=BodyText> Now that     

we have the necessary tools for manipulating PIDLs, let's proceed with the     

actual enumeration. At this point, we have yet to write any component-specific     

code. As before, we start with a blank form containing a single <i     

style='mso-bidi-font-style:normal'>TListView</i>. The code in <a     

href="#ListingTwo">Listing Two</a>     

demonstrates the use of the shell namespace to fill the ListView. Note that if     

successful, it's very easy to adapt this code into a component by simply     

cutting and pasting the entire function. Furthermore, it's much easier to test     

the function before placing it into a component. </p>     

     

<p class=BodyText> &nbsp; </p>     

     

<p class=BodyText> Note how     

we used each of the described interfaces to perform a specific task. This is     

one of the features of COM: Each interface is designed to accomplish a set of     

tasks pertaining to the scope of objects that the particular interface     

supports. </p>     

     

<p class=BodyText> &nbsp; </p>     

     

<p class=BodyText> Let's     

briefly examine how the <i>FillListEx</i>     

method works. The function takes two parameters: a pointer to the shell folder,     

and a PIDL for the folder to enumerate. Within the function, we first use the <i     

style='mso-bidi-font-style:normal'>SHGetMalloc</i> function to get a pointer to     

the <i>IMalloc</i> interface. The only role     

of this interface is to free the memory allocated by the various shell     

functions. Next, we call the <i>IShellFolder::EnumObjects</i>     

method to perform the actual enumeration. This function returns a pointer to     

the <i>IEnumIDList</i> interface, which is     

then used to perform the actual enumeration. The <i>IEnumIDList::Next</i>     

method iterates through all IDs in the folder. This method returns a PIDL to     

each object, which is then passed into the <i>SHGetFileInfo</i>     

function to retrieve useful information, such as its display name and system     

image list icon index. Passing the SHGFI_PIDL flag to the <i>SHGetFileInfo</i> function, we can pass a PIDL as the <i     

style='mso-bidi-font-style:normal'>pszPath</i> parameter where a path is     

usually specified. Because this PIDL must be absolute, we use the <i     

style='mso-bidi-font-style:normal'>MergeIDLists</i> helper function. </p>     

     

<p class=BodyText> &nbsp; </p>     

     

<p class=BodyText> We'll     

eventually implement the Details (vsReport) view, so now is a good time to add     

this functionality. Although this feature isn't high on our priority list, it's     

a good idea to implement it now while the process is fresh in our minds.     

Explorer's Details view adds three additional columns to the list: Size, Type,     

and Modified. The Type field is simple to add because this information can be     

returned by the <i>SHGetItemInfo</i> call by     

including the SHGFI_TYPENAME flag. The other two fields, Size and Modified, are     

usually returned by a call to <i>FindFirstFile</i>/<i     

style='mso-bidi-font-style:normal'>FindNextFile</i> in the WIN32_FIND_DATA     

structure. However, using the <i>SHGetDataFromIDList</i>     

function, we can retrieve the same information from a PIDL. </p>     

     

<p class=BodyText> &nbsp; </p>     

     

<p class=Subheads>Conclusion</p>     

     

<p class=BodyText> This     

article demonstrated the first part of creating an Explorer-style ListView component,     

starting with the tedious design stages. Several COM interfaces and use of the     

shell namespace to fill in the ListView control of our component were also     

discussed. </p>     

     

<p class=BodyText> &nbsp; </p>     

     

<p class=BodyText> In the     

next installation of this two-part series, we'll do some coding and implementation     

of the Explorer-style component. We'll discuss various issues, including     

relieving the bottleneck mentioned in this article, sorting the list of files,     

adding extra functionality, adding the context menu, automatic launching,     

getting notification, and other design-time considerations. </p>     

     

<p class=BodyText> &nbsp; </p>     

     

<p class=BodyText> <i>The code referenced in this article is<b>     

</b>available for <a href="download/cb199910dc_f.zip" tppabs="http://www.cbuilderzine.com/features/1999/10/cb199910dc_f/cb199910dc_d.asp">download</a>. </i></p>   

   

<p class=BodyText> &nbsp; </p>   

   

<p class=Biotext>Damon     

Chandler has been programming for over 15 years, and enjoys every facet of the     

art. Mostly self-taught, Damon followed a common path to C++ programming -     

GW-BASIC, Pascal, then C++. It was the combination of the VCL and C++ that got     

him hooked on C++Builder. An engineer by trade and a programmer at heart, Damon     

is very pleased to see the two technologies finally merge. Damon is currently     

working in the Visual Communications Lab at Cornell University, where his     

research primarily centers around wavelet image compression. C++Builder is the     

tool of choice, and the RAD theme has helped create new interfaces for often     

obscure tasks. </p>     

     

<p class=BodyText> &nbsp; </p>     

     

<p class=Subheads><a name=ListingOne></a>Begin Listing One - Helper functions</p>     

     

<p class=Code><span class=Code><i><span Class=CodeBlue>/**********************************************************************</span></i></span></p>     

     

<p class=Code><span class=Code><i><span Class=CodeBlue>*&nbsp;&nbsp;Shell     

Namespace Helper Functions:&nbsp;&nbsp; Working     

with PIDLS</span></i></span></p>     

     

<p class=Code><span class=Code><i><span Class=CodeBlue>&nbsp;**********************************************************************/</span></i></span></p>     

     

<p class=Code><span class=Code>&nbsp; </span></p>     

     

<p class=Code><span class=Code><i><span Class=CodeBlue>// =====================================================================</span></i></span></p>     

     

<p class=Code><span class=Code><i><span Class=CodeBlue>// Function:&nbsp;&nbsp;&nbsp; GetItemCount()</span></i></span></p>     

     

<p class=Code><span class=Code><i><span Class=CodeBlue>// Synopsis:&nbsp;&nbsp;&nbsp; Returns the number of item identifiers in a PIDL</span></i></span></p>     

     

<p class=Code><span class=Code><i><span Class=CodeBlue>// Parameters: LPITEMIDLIST pidl -- PIDL to enumerate</span></i></span></p>     

     

<p class=Code><span class=Code><i><span Class=CodeBlue>//     

=====================================================================</span></i></span></p>     

     

<p class=Code><span class=Code>&nbsp; </span></p>     

     

<p class=Code><span class=Code><b>unsigned</b>     

<b>int</b> GetItemCount(LPITEMIDLIST pidl) </span></p>     

     

<p class=Code><span class=Code>{</span></p>     

     

<p class=Code><span class=Code><b>&nbsp;&nbsp;unsigned</b> <b>int</b> nCount = 0; </span></p>     

     

<p class=Code><span class=Code>&nbsp; </span></p>     

     

<p class=Code><span class=Code>&nbsp;&nbsp;<b> unsigned</b>     

<b>short</b> nLen = pidl-&gt;mkid.cb; </span></p>     

     

<p class=Code><span class=Code>&nbsp;&nbsp;<b> while</b>     

(nLen != 0) </span></p>     

     

<p class=Code><span class=Code>&nbsp;&nbsp;{ </span></p>     

     

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;pidl = GetNextItem(pidl); </span></p>     

     

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;nLen = pidl-&gt;mkid.cb; </span></p>     

     

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;nCount++;</span></p>     

     

<p class=Code><span class=Code>&nbsp;&nbsp;} </span></p>     

     

<p class=Code><span class=Code>&nbsp;&nbsp;<b> return</b>     

nCount; </span></p>     

     

<p class=Code><span class=Code>}</span></p>     

     

<p class=Code><span class=Code><i><span Class=CodeBlue>// ---------------------------------------------------------------------------</span></i></span></p>     

     

<p class=Code><span class=Code>&nbsp; </span></p>     

     

<p class=Code><span class=Code><i><span Class=CodeBlue>//     

=====================================================================</span></i></span></p>     

     

<p class=Code><span class=Code><i><span Class=CodeBlue>// Function:&nbsp;&nbsp;&nbsp; GetNextItem()</span></i></span></p>     

     

<p class=Code><span class=Code><i><span Class=CodeBlue>// Synopsis:&nbsp;&nbsp;&nbsp; Returns a pointer to the next item identifier in a PIDL</span></i></span></p>     

     

<p class=Code><span class=Code><i><span Class=CodeBlue>// Parameters: LPITEMIDLIST pidl -- PIDL containing     

item to point to</span></i></span></p>     

     

<p class=Code><span class=Code><i><span Class=CodeBlue>//     

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -