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

📄 cb200006dc_f.asp.htm

📁 C++builder学习资料C++builder
💻 HTM
📖 第 1 页 / 共 5 页
字号:
for each item. Many folders expose this interface to allow applications (namely       

Windows Explorer) to extract the information that appears in the supplementary       

columns of the Explorer's folder view. For file-system folders, these fields       

typically indicate the size, type, modification date, and attributes of each       

object. For virtual folders, this data usually indicates folder-specific       

attributes. For example, the Control Panel folder presents the "Description"       

column, where each field yields information about the purpose of the associated       

applet. </p>       

       

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

       

<p class=BodyText> The <i       

style='mso-bidi-font-style:normal'>IShellDetails</i> interface can be used to       

retrieve the supplementary information for each shell object, including the       

captions of each column header. A pointer to this interface is retrieved via       

the <i>IShellFolder::CreateViewObject</i> member function (specifying the <i       

style='mso-bidi-font-style:normal'>IID_IShellDetails</i> interface identifier).       

Supplementary information is then retrieved via the <i>IShellDetails::GetDetailsOf</i>       

member function: </p>       

       

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

       

<p class=Code><span class=Code>HRESULT       

GetDetailsOf(LPCITEMIDLIST pidl, UINT iColumn, </span></p>       

       

<p class=Code><span class=Code>&nbsp;&nbsp;LPSHELLDETAILS pDetails); </span></p>       

       

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

       

<p class=BodyText> The       

first parameter to this function is the relative PIDL of the object whose       

information we are interested in. For column headers, this parameter is set to       

NULL. The <i>iColumn</i> parameter specifies       

the zero-based index of the target column. The retrieved information is returned       

via the <i>pDetails</i> parameter, a pointer       

to a SHELLDETAILS structure: </p>       

       

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

       

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

<b>struct</b> _SHELLDETAILS</span></p>       

       

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

       

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

fmt; </span></p>       

       

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

cxChar; </span></p>       

       

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

       

<p class=Code><span class=Code>} SHELLDETAILS,       

*LPSHELLDETAILS; </span></p>       

       

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

       

<p class=BodyText> The <i       

style='mso-bidi-font-style:normal'>fmt</i> data member indicates the text       

alignment of the column header and its entries, while the <i>cxChar</i> data member indicates the number of characters in the column       

header. The caption (field entry) for the particular column (shell object) is       

stored in the <i>str</i> data member. This       

STRRET-type member can be converted to a character array via the <i       

style='mso-bidi-font-style:normal'>BufferFromSTRRET</i> utility function (from       

the "pidlhelp" library). <a href="#ListingFour">Listing Four</a>       

provides the implementation of our <i>DoHandleShellDetails</i>       

member function, which uses the <i>IShellDetails</i>       

interface to prepare the column headers. </p>       

       

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

       

<p class=BodyText> For       

those folders that do not expose the <i>IShellDetails</i>       

interface, we have no choice but to hard-code the column headers. To retrieve       

the field entries for the objects within the folder, we use the <i       

style='mso-bidi-font-style:normal'>SHGetDataFromIDList</i> API function. This       

function simply fills a WIN32_FIND_DATA structure with information contained in       

the PIDL itself. If such information is not available, we default to the more       

conventional <i>FindFirstFile</i> API       

function. These tasks are handled via our <i>DoFillShellExtraInfo</i>       

member function, whose implementation is shown in <a href="#ListingFive">Listing Five</a>.</p>       

       

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

       

<p class=BodyText> Finally,       

it should be mentioned that for Windows 2000 and later systems, the <i       

style='mso-bidi-font-style:normal'>IShellDetails</i> interface has been       

superceded by the <i>IShellFolder2</i>       

interface. This latter interface also presents the <i>GetDetailsOf</i> member function with an identical signature (and       

identical functionality) as that of its <i>IShellDetails</i>       

counterpart. </p>       

       

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

       

<p class=BodyText> To help       

fortify the techniques of using the <i>IShellDetails</i>       

interface, refer to the DemoShellDetails sample project (included with the       

downloadable source code; see end of article for details). In this project, the       

task of retrieving the "details information" for a particular shell folder is       

isolated from the rest of the <i>TExpListView</i>       

implementation. </p>       

       

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

       

<p class=Subheads>Providing       

Sorting Capabilities</p>       

       

<p class=BodyText> Fortunately,       

since we're working with the <i>IShellFolder</i>       

interface, we can use the <i>IShellFolder::CompareIDs</i> member function to       

provide support for sorting the items. The function takes an integer value as       

its first parameter, and a pair of relative PIDLs as its second and third       

parameters: </p>       

       

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

       

<p class=Code><span class=Code>HRESULT       

CompareIDs(LPARAM lParam, LPCITEMIDLIST pidl1, </span></p>       

       

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LPCITEMIDLIST pidl2); </span></p>       

       

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

       

<p class=BodyText> The       

value specified by the <i>lParam</i>       

argument determines the criterion by which to sort the objects indicated by the       

<i>pidl1</i> and <i>pidl2</i> parameters. For example, to sort by display name, we pass 0       

as the <i>lParam</i> parameter. To sort by       

file size, file type, or modification date, we set <i>lParam</i> to 1, 2, or 3, respectively. We support this functionality       

in our component via the public <i>DoCustomSort</i>       

member function, as shown in <a href="#ListingSix">Listing Six</a>.</p>       

       

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

       

<p class=BodyText> Our <i       

style='mso-bidi-font-style:normal'>DoCustomSort</i> member function uses the <i       

style='mso-bidi-font-style:normal'>TCustomListView::CustomSort</i> member function, and our <i>ExpCustomSortProc</i> callback function. We make this latter function a       

friend of our class, so it can access the private <i>m_FInitialSort</i> member. Access to this member is crucial, because       

the contents of the folder need to initially be sorted in ascending order. This       

is accomplished by reversing the sign of the return value of the <i       

style='mso-bidi-font-style:normal'>CompareIDs</i> function call. Once initially       

sorted, the direction of the sort can be toggled by calling the <i       

style='mso-bidi-font-style:normal'>CustomSort</i> member function successively.       

Moreover, this initialization needs to be performed when the <i       

style='mso-bidi-font-style:normal'>lParam</i> argument of the <i       

style='mso-bidi-font-style:normal'>CompareIDs</i> member function is changed.       

That is, even if the contents have been initially sorted according to name, we       

are still required to initially reverse the sign of the return value, if we       

need to sort by any other criterion. </p>       

       

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

       

<p class=Subheads>Displaying       

the Context Menu</p>       

       

<p class=BodyText> The       

context menu of a shell object (see Figure 3) is handled via the <i       

style='mso-bidi-font-style:normal'>IContextMenu</i> and <i>IContextMenu2</i> interfaces. </p>       

       

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

       

<p class=Captions><img width=333 height=275       

src="images/cb200006dc_f_image004.jpg" tppabs="http://www.cbuilderzine.com/features/2000/06/cb200006dc_f/cb200006dc_f_image004.jpg" align=left hspace=12><b>Figure 3:</b> A shell object's context menu. </p>       

       

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

       

<p class=BodyText> A       

pointer to the former is retrieved via the <i>IShellFolder::GetUIObjectOf</i> member function,       

which takes six parameters: </p>       

       

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

       

<p class=Code><span class=Code>HRESULT       

GetUIObjectOf(</span></p>       

       

<p class=Code><span class=Code>&nbsp;&nbsp;HWND hwndOwner, </span></p>       

       

<p class=Code><span class=Code>&nbsp;&nbsp;UINT cidl, </span></p>       

       

<p class=Code><span class=Code>&nbsp;&nbsp;LPCITEMIDLIST *apidl, </span></p>       

       

<p class=Code><span class=Code>&nbsp;&nbsp;REFIID riid, </span></p>       

       

<p class=Code><span class=Code>&nbsp;&nbsp;UINT *prgfInOut, </span></p>       

       

<p class=Code><span class=Code>&nbsp;&nbsp;LPVOID *ppvOut</span></p>       

       

<p class=Code><span class=Code>);</span></p>       

       

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

       

<p class=BodyText> The <i       

style='mso-bidi-font-style:normal'>hwndOwner</i> parameter indicates the handle       

of the window that is to own any dialog boxes that may be displayed. The <i       

style='mso-bidi-font-style:normal'>cidl</i> parameter indicates the number of       

PIDLs present in the PIDL array passed as the <i>apild</i> parameter. This array specifies the shell objects for which       

the context menu should apply. The <i>riid</i>       

parameter is used to specify the interface whose pointer we are interested in       

retrieving. Here, we pass the <i>IID_IContextMenu</i>       

identifier, indicating that we want a pointer to the <i>IContextMenu</i> interface. This pointer is returned via the <i       

style='mso-bidi-font-style:normal'>ppvOut</i> parameter. The <i       

style='mso-bidi-font-style:normal'>prgfInOut</i> is reserved, and is set to       

NULL. </p>       

       

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

       

<p class=BodyText> With a       

pointer to the <i>IContextMenu</i>       

interface, we grab a pointer to the <i>IContextMenu2</i>       

interface via the <i>IContextMenu::QueryInterface</i> member function.       

Strictly speaking, the <i>IContextMenu2</i>       

interface isn't necessary. The interface is simply an extension of the <i       

style='mso-bidi-font-style:normal'>IContextMenu</i> interface that provides       

support for owner-drawn menu items. In this case, we use the <i       

style='mso-bidi-font-style:normal'>IContextMenu2</i> interface to allow for       

display of items in the Send To sub-menu. </p>       

       

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

       

<p class=BodyText> Once we       

have a pointer to the <i>IContextMenu2</i>       

interface, we create a popup menu, then use the <i>QueryContextMenu</i> member function to fill this menu with relevant       

items. The amount and type of menu items that are added are determined by the       

array of PIDLs initially passed to the <i>GetUIObjectOf</i>       

member function. Once the menu has been successfully filled, we display the       

popup menu via the <i>TrackPopupMenu</i> API       

function. When used with the TPM_RETURNCMD flag, this latter function returns a       

DWORD value indicating the command of the menu item that was selected. We use       

this value with the <i>IContextMenu::InvokeCommand</i> member function       

to instruct the shell to invoke the selected command. </p>       

⌨️ 快捷键说明

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