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

📄 cb199910dc_f.asp.htm

📁 C++builder学习资料C++builder
💻 HTM
📖 第 1 页 / 共 5 页
字号:
view (file size, description, and modification time): This feature may not be     

necessary for all situations; however, some applications may require such information.     

Further, many users require items to be sorted by these criteria. (Priority     

rank = 50 percent)      

     

<li>Directional     

sorting: As mentioned, many users use a sorted view to quickly access certain     

items. If the Details view is to be supported, it's essential to implement     

directional sorting. (Priority rank = 50 percent)      

     

<li>Header     

dragging and dropping (column rearrangement): There are few instances where     

column rearrangement increases the usability of the Explorer interface. Its     

chances of being used are further lowered because it only applies to the     

Details view. (Priority rank = 30 percent)      

     

<li>Hot     

tracking and variable-click selection: While the former is more for visual     

effect and adds little functionality to the control, the latter has been     

adopted by many users, especially those who've adapted to the single-click, or     

have difficulty otherwise. Indeed, this feature applies to all view styles.     

(Priority rank = 75 percent)      

     

<li>Automatic     

program launch: Like the context menu, this feature may have inherited a loyal     

following. Consider this case: A user wants to quickly view the contents of a     

document or compressed file before performing an action on it. If the user     

activates and selects the item expecting the corresponding application to open     

the indicated file and nothing happens, he or she may become irritated or     

suspicious of system lock. (Priority rank = 75 percent)      

     

     

</ul>     

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

     

<p class=BodyText> Keep in     

mind that this list and each item's corresponding priority number is not set in     

stone. In fact, we may find some of these features nearly impossible to     

implement without a complete re-write of the underlying control. While these     

priority ranks serve as a good indication of what needs to be accomplished, and     

in what order, the implementation stages may prove otherwise. There's nothing     

wrong with changing a design during implementation; it is, in fact, necessary     

for most developers to reconsider design issues several times after much coding     

has been completed. </p>     

     

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

     

<p class=Subheads>Choosing an     

Implementation Scheme</p>     

     

<p class=BodyText> Now that     

we've prioritized the necessity of each of the key features, we need to choose     

a method to perform the most fundamental goal: filling the ListView with items     

from any given folder. The first solution that comes to mind involves the <i     

style='mso-bidi-font-style:normal'>FindFirst</i> and <i>FindNext</i> methods. These are simply VCL wrappers of the API <i     

style='mso-bidi-font-style:normal'>FindFirstFile</i> and <i>FindNextFile</i> functions. A typical implementation to fill a <i     

style='mso-bidi-font-style:normal'>TListView</i> using the <i>FindFirst</i> and <i>FindNext</i>     

functions is shown in Figure 2. </p>     

     

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

     

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

style='mso-bidi-font-weight:normal'>__fastcall</b> TForm1::FillListEx()</span></p>     

     

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

     

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

     

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

path[MAX_PATH]; </span></p>     

     

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

     

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

     

<p class=Code><span class=Code>&nbsp;&nbsp;<i> <span Class=CodeBlue>// Bind ImageList1 to the system image list. </span></i></span></p>     

     

<p class=Code><span class=Code>&nbsp;&nbsp;ImageList1-&gt;ShareImages = <b     

style='mso-bidi-font-weight:normal'>true</b>;</span></p>     

     

<p class=Code><span class=Code>&nbsp;&nbsp;ImageList1-&gt;Handle = SHGetFileInfo(</span></p>     

     

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&quot;&quot;, 0, &amp;IconInfo, <b     

style='mso-bidi-font-weight:normal'>sizeof</b>(IconInfo), </span></p>     

     

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;SHGFI_ICON | SHGFI_SMALLICON |     

SHGFI_SYSICONINDEX); </span></p>     

     

<p class=Code><span class=Code>&nbsp;&nbsp;ListView1-&gt;SmallImages = ImageList1; </span></p>     

     

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

     

<p class=Code><span class=Code>&nbsp;&nbsp;<i> <span Class=CodeBlue>// Prevent screen updating. </span></i></span></p>     

     

<p class=Code><span class=Code>&nbsp;&nbsp;ListView1-&gt;Items-&gt;BeginUpdate();</span></p>     

     

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

     

<p class=Code><span class=Code>&nbsp;&nbsp;<i> <span Class=CodeBlue>// Locate the first file in the desktop directory. </span></i></span></p>     

     

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

(FindFirst(&quot;C:\\Windows\\Desktop\\*.*&quot;, </span></p>     

     

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;faAnyFile, SearchRecord) == 0) </span></p>     

     

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

     

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;<i> <span Class=CodeBlue>// Add a new item, then assign the located</span></i></span></p>     

     

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;<i> <span Class=CodeBlue>// filename to its Caption property. </span></i></span></p>     

     

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;TListItem *Item =     

ListView1-&gt;Items-&gt;Add();</span></p>     

     

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;Item-&gt;Caption = SearchRecord.Name; </span></p>     

     

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

     

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;<i> <span Class=CodeBlue>// Retrieve the index in the imagelist corresponding</span></i></span></p>     

     

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;<i> <span Class=CodeBlue>// to the Explorer-type icon of a given filename, then</span></i></span></p>     

     

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;<i> <span Class=CodeBlue>// assign it the ImageIndex property of the new item. </span></i></span></p>     

     

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;AnsiString Path =     

&quot;C:\\Windows\\Desktop\\&quot; + Item-&gt;Caption; </span></p>     

     

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;strcpy(path, Path.c_str());&nbsp;&nbsp; </span></p>     

     

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;SHGetFileInfo(path, 0, &amp;IconInfo, <b     

style='mso-bidi-font-weight:normal'>sizeof</b>(IconInfo), </span></p>     

     

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SHGFI_ICON | SHGFI_SHELLICONSIZE | SHGFI_SYSICONINDEX); </span></p>     

     

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;Item-&gt;ImageIndex = IconInfo.iIcon; </span></p>     

     

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

     

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;<i> <span Class=CodeBlue>// Repeat this process for the rest of the files. </span></i></span></p>     

     

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

(FindNext(SearchRecord) == 0) </span></p>     

     

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

     

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Item = ListView1-&gt;Items-&gt;Add();</span></p>     

     

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Item-&gt;Caption = SearchRecord.Name; </span></p>     

     

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

     

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Path = &quot;C:\\Windows\\Desktop\\&quot;     

+ Item-&gt;Caption; </span></p>     

     

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strcpy(path, Path.c_str());</span></p>     

     

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SHGetFileInfo(path, 0, &amp;IconInfo, <b     

style='mso-bidi-font-weight:normal'>sizeof</b>(IconInfo), </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;SHGFI_ICON |     

SHGFI_SHELLICONSIZE |</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;SHGFI_SYSICONINDEX); </span></p>     

     

<p class=Code><span class=Code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Item-&gt;ImageIndex = IconInfo.iIcon; </span></p>     

     

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

     

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

     

<p class=Code><span class=Code>&nbsp;&nbsp;<i> <span Class=CodeBlue>// Close the search handle. </span></i></span></p>     

     

<p class=Code><span class=Code>&nbsp;&nbsp;FindClose(SearchRecord); </span></p>     

     

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

     

<p class=Code><span class=Code>&nbsp;&nbsp;<i> <span Class=CodeBlue>// Restore screen updating. </span></i></span></p>     

     

<p class=Code><span class=Code>&nbsp;&nbsp;ListView1-&gt;Items-&gt;EndUpdate();</span></p>     

     

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

     

<p class=Captions><b>Figure     

2:</b> Code     

demonstrating the use of <i>FindFirst</i> and <i>FindNext</i>.</p>     

     

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

     

<p class=BodyText> Before     

putting this code into a component, let's test it in a simple project     

containing a blank form and a single <i>TListView</i>.     

After adding the necessary functions, we find that the approach is relatively     

quick, although not nearly as fast as Explorer. Testing this code on different     

directories containing various amounts of files, we notice that the bottleneck     

in this procedure is caused by the <i>TListItems::Add</i>     

method. In fact, by commenting out this single line, we find the enumeration     

code to be nearly instantaneous. In Part II of this series, we'll discuss some     

techniques to overcome this bottleneck. </p>     

     

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

     

<p class=BodyText> At this     

point, we notice what seems to be a minor issue; namely, that certain objects     

and their corresponding icons fail to appear in our ListView. For example, when     

enumerating the Desktop folder, we find that objects such as My Computer,     

Network Neighborhood, and Recycle Bin fail to appear. Upon examination of the     

documentation for the <i>FindFirstFile</i>     

function, we see there is no flag to set to make these objects appear. As a     

test, we execute a <i>TOpenDialog</i> and     

choose the Desktop folder. Indeed, in this common dialog wrapper, these icons     

appear as expected. However, we also notice that these objects don't appear to     

be physical file objects. That is, they cannot be dragged into a separate     

folder or simply deleted. Why then, don't they appear in our ListView, as we     

are using two of the most common API file-manipulation functions? </p>     

     

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

     

<p class=BodyText> These     

objects, in fact, represent a special class of folders known as <i>virtual</i>     

folders. They are not maintained by the file system itself, rather by the shell     

namespace and several OLE COM interfaces. While many developers find the COM     

intimidating, it turns out that to work with the shell namespace, we only need     

to use a few COM interfaces. </p>     

     

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

     

<p class=Subheads>Working     

with the Shell Namespace</p>     

     

<p class=BodyText> While an     

in-depth discussion of the shell namespace and COM itself are well beyond the     

scope of this article, we'll briefly discuss those interfaces and shell     

functions that we'll use to fill our ListView. The first and most important is     

the <i>IMalloc</i> COM interface. Although     

this interface has several methods, the one we're primarily interested in (the     

one we'll use extensively) is the <i>IMalloc::Free</i>     

method. This is simply used to free any blocks of memory previously allocated     

by the shell. To get a pointer to this interface, we use the shell namespace <i     

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

     

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

     

<p class=BodyText> Another     

interface that's commonly used is <i>IShellFolder</i>.     

As the name suggests, this interface manages shell folder objects. The <i     

⌨️ 快捷键说明

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