📄 cb199910dc_f.asp.htm
字号:
<HTML>
<HEAD>
<TITLE>Exploring Possibilities</TITLE>
</HEAD>
<BODY>
<TABLE border=0 width="100%" cellpadding=0 cellspacing=0>
<TR valign=top>
<TD width="100%">
<p class=ColumnTitle><font size="2">In
Development</font></p>
<p class=ColumnSubtitle><font size="2">Development
Strategies / Component Design and</font> Creation / User Interface Issues</p>
<p class=BodyText> </p>
<p class=Byline>By Damon
Chandler</p>
<p class=BodyText> </p>
<p class=StoryTitle><font size="2">Exploring
Possibilities</font></p>
<p class=StorySubtitle><font size="2">Part
I: Designing an Explorer-style ListView Component</font></p>
<p class=BodyText> </p>
<p class=BodyText> Many
applications require some sort of shell interaction. Perhaps the user needs to
be able to select a group of files, or a certain applet in the control panel.
Or, what if the user needs a view of the files on the Desktop while extracting
a compressed file. Or a list of the printers installed on a system before choosing
to print a document? How will the user choose a group of files that will be
written to a CD-R disc without bouncing back and forth between open dialog
boxes? </p>
<p class=BodyText> </p>
<p class=BodyText> These
are some of the questions that developers frequently face in the early stages
of GUI (Graphical User Interface) design. Unfortunately, the selection of
components on the C++Builder Component palette that can handle these tasks is
severely limited. Wouldn't it be nice to have an Explorer pane, such as the one
shown in Figure 1, embedded in your application? It would be nice to have such
an object. The only problem is that it doesn't exist. </p>
<p class=BodyText> </p>
<p class=Captions><img width=333 height=328
src="images/cb199910dc_f_image002.jpg" tppabs="http://www.cbuilderzine.com/features/1999/10/cb199910dc_f/cb199910dc_f_image002.jpg"> <br>
<b>Figure 1:</b> The goal: An Explorer-like object
named ListViewEx (shown here in its "icon" mode). </p>
<p class=BodyText> </p>
<p class=BodyText> To solve
this problem, there are two choices: use a third-party component, or write your
own. In this two-part series, we'll discuss the techniques needed to create
such a component, from the design stages to the finishing touches. </p>
<p class=BodyText> </p>
<p class=BodyText> In this
first installment, we'll consider what functionality to implement and what
should be left to the component user. In addition, we'll discuss the use of
several COM interfaces and the use of the shell namespace to fill in the
ListView control of our component. (The code presented in this series is
available for download; see end of article for details. It was written using
Borland C++Builder 1.0; some of the methods may require slight modification for
newer versions.) </p>
<p class=BodyText> </p>
<p class=Subheads>Motivation</p>
<p class=BodyText> The GUI
is one of the means most commonly used to convey large amounts of information
in a small workspace. Windows itself is based on an intuitive, user-friendly
interface that allows maximum productivity in the least amount of time. From a
developer's standpoint, designing a user-friendly GUI requires a great deal of
work and planning. The end user interacts religiously with such an interface,
and often judges the quality of a product solely on its ease of use. Software
that's difficult to learn is most often overlooked as a viable tool to get the
job done. </p>
<p class=BodyText> </p>
<p class=BodyText> Presenting
the user with a familiar interface significantly lowers the learning curve for
an application. At the same time, it gives a product the needed edge during
review. While it's nearly impossible to create every product with an identical
layout, there are several areas that can be kept consistent. The Windows Common
dialog boxes are a good example of consistent design; if the end user knows how
to open a file in Microsoft Word, then by presenting the same dialog box in
another product, he or she will know how to accomplish this task in any application.
The same ideology applies to any aspect of an application's interface; if you
want to make it easy to learn, emulate something the user already knows. </p>
<p class=BodyText> </p>
<p class=Subheads>Is a
Component Necessary? </p>
<p class=BodyText> Before
jumping into any non-trivial project, it's often prudent to sit down and get a
grasp of what needs to be done and what initial approaches to take to
accomplish the desired goal. While the specifics aren't necessary, it's
generally helpful to get an idea of the big picture. </p>
<p class=BodyText> </p>
<p class=BodyText> The
first question to consider before designing any component is whether it's
necessary. Are we going to be using this component more than once? Is the
essential code adaptable to the component model? Will wrapping the code in a
component present a significant performance cost? These are some of the basic
considerations necessary before any actual design can take place. In many
situations, a component isn't called for, so let's begin by answering these
fundamental queries. </p>
<p class=BodyText> </p>
<p class=BodyText> <b>Will
the component most likely be used for multiple projects or by multiple
development teams? </b>A
few applications of the Explorer-style interface have already been discussed,
and it has been deemed that if such a component were to be created, then yes,
it would be used in multiple projects. Also, such a component would be an ideal
tool to add familiarity to any user interface created by other developers
throughout the department. </p>
<p class=BodyText> </p>
<p class=BodyText> <b>Does
the code required to implement this functionality fit the component model? </b>It isn't possible to answer this
with complete confidence, but, from what is known at this point, the component
will simply be an enhanced <i>TListView</i>.
It seems probable that, even with the added functionality, it will be possible
to encapsulate with design- and run-time interaction. </p>
<p class=BodyText> </p>
<p class=BodyText> <b>By
wrapping the code in a component, are we inflicting a significant performance
cost? </b>From what's
known so far, it seems unlikely that a component implementation will present
any major performance penalties. There may be some reflected messages, but this
is far outweighed by the advantages of encapsulated events. However, there may
exist some aspects not yet perceived. Some folders may contain hundreds, even
thousands, of files, so there's a good chance that even the smallest bottleneck
will impose an intolerable operating speed. </p>
<p class=BodyText> </p>
<p class=BodyText> Because
there seem to be enough convincing arguments and motivation, it seems a good
idea to proceed with designing a component to encapsulate the Explorer-style <i
style='mso-bidi-font-style:normal'>TListView</i>. By accepting this choice, we
agree to deal with the caveats and increased development time. In turn, we'll
reap the benefits of code reuse. </p>
<p class=BodyText> </p>
<p class=Subheads>The Big
Picture</p>
<p class=BodyText> At this
point, it's a good idea to get an overview of what we want to accomplish. Let's
first examine Explorer itself - this is what we want to achieve, or at least
come as close to as possible. We all know what Explorer looks like: The main
interface consists of a tree view on the left-hand side and a ListView control
to the right. It's the latter control that we're interested in, so let's close
the tree view portion. Observing the ListView control, we notice several
standard features, including multiple view styles, colorful icons, and object
names. </p>
<p class=BodyText> </p>
<p class=BodyText> Upon
closer inspection, we notice that each icon displays a unique context menu when
right-clicked. Switching to Details view, we notice that each file object
displays a description, size, and modified date/time. Furthermore, the control
implements forward and backward sorting, depending on the column header that's
clicked. Examining the header control further, we notice that the columns can
be rearranged by dragging and dropping the header sections. Also available is
the feature to enable hot tracking of the items and toggle the number of clicks
required to activate an item. Finally, we observe that activating a selected
item launches that item in its associated application. </p>
<p class=BodyText> </p>
<p class=BodyText> While
there are undoubtedly more features to be explored, we already have a big list
to fill. We'll see by the end of this series just how trivial some of these
features are to implement, while others are considerably more involved. For
now, let's decide which of these features are essential to our component. </p>
<p class=BodyText> </p>
<p class=BodyText> Before
drawing any conclusions, remember that the component must not close any doors
to future implementation. That is, we don't want to implement a feature that
cannot be changed or enhanced. One of the most common mistakes made during the
early design stages is the idea that if the functionality is easy to implement
(or is already implemented by an ancestor control), that feature gets a high
priority. Ease of implementation should rarely be used during the planning
stages. In fact, there will be some inherited features that we won't want to
publish in our derivation. </p>
<p class=BodyText> </p>
<p class=BodyText> A
typical decision process follows, where each of the described features are
considered and ranked according to priority: </p>
<ul>
<li>Multiple
views: Multiple views are natively supported by the Explorer interface;
however, because many applications won't require more than one view, this
feature isn't essential. On the other hand, since we can't predict which view
style the component user will require, it's prudent to support most of the view
styles. (Priority rank = 80 percent)
<li>Corresponding
icons: Although the ListView control has support for displaying icons, we'll
need to find the corresponding icon for each file type. This feature is
essential for any Explorer clone. (Priority rank = 100 percent)
<li>Corresponding
context menu: While at first this may seem like a hidden feature, those users
who've adapted to this functionality may become confused or irritated if it's
missing. Further, this feature applies to all view styles of the ListView.
(Priority rank = 75 percent)
<li>Details
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -