📄 ch07.htm
字号:
<P><H2>TStrings</H2><P>The TStrings class is a VCL class that manages lists of strings. Several VCL componentsuse instances of TStrings to manage their data (usually text). For example, on Day6 you used TStrings when you built the ScratchPad application. "I don't recallusing a TStrings class," you say. Well, you did, but you just weren't awareof it. Remember when you saved and loaded files? You used something like this:</P><P><PRE>Memo.Lines.SaveToFile(SaveDialog.FileName);</PRE><P>The Lines property of TMemo is an instance of the TStrings class. The SaveToFilemethod of TStrings takes the strings and saves them to a file on disk. You can usethe same technique to load a list box from a file on disk or save the contents ofa list box to disk. In the case of the TListBox class, the property that holds thelist box items is called Items. For example, try this exercise:</P><DL> <DT></DT> <DD><B>1. </B>Create a new application and place a ListBox component on the form. Size the list box as desired. <P> <DT></DT> <DD><B>2. </B>Change the Name property of the list box to ListBox. <P> <DT></DT> <DD><B>3. </B>Double-click the background of the form (not on the list box). The Code Editor displays the FormCreate function. <P> <DT></DT> <DD><B>4. </B>Modify the FormCreate function so that it looks like this: <P></DL><BLOCKQUOTE> <PRE>procedure TForm1.FormCreate(Sender: TObject);var WinDir : array [0..255] of Char; FileName : string;begin GetWindowsDirectory(WinDir, SizeOf(WinDir)); FileName := WinDir + `\win.ini'; ListBox.Items.LoadFromFile(FileName);end;</PRE></BLOCKQUOTE><PRE></PRE><DL> <DT></DT> <DD><B>5. </B>Click the Run button to compile and run the program. <P></DL><P>When the program runs, the list box will contain the contents of your WIN.INIfile. Using this method, it's easy to load a list box from any ASCII text data file.The ComboBox component also has an Items property that works in exactly the sameway.</P><P>You can add, delete, insert, and move items in a list box, combo box, or memoby calling the Add, Append, Delete, Insert, and Move methods of the TStrings class.</P><BLOCKQUOTE> <P><HR><strong>NOTE:</strong> How Add performs depends on the value of the Sorted property. If the Sorted property is set to True, Add will insert the string where it needs to be in the list of items. If Sorted is False, the new string will be added at the end of the list. <HR></BLOCKQUOTE><P>A component can be cleared of its contents by calling the Clear method. An individualstring can be accessed by using the array subscript operator. For example, to retrievethe first string in a list of strings, you would use</P><P><PRE>Edit.Text := ListBox.Items[0];</PRE><BLOCKQUOTE> <P><HR><strong>NOTE:</strong> The strings in a TStrings class are actually contained in the Strings property. The Strings property is declared as the <I>default array property</I> for the TStrings class, so you don't specifically have to reference it when retrieving a specific string (although you can if you want to). Given that, then, the following two lines result in the same code being generated by the compiler:</P> <PRE>Edit.Text := ListBox.Items[0];Edit.Text := ListBox.Items.Strings[0];</PRE> <P><HR></BLOCKQUOTE><PRE></PRE><P>Each string in a TStrings array contains the string itself and four bytes of extrastorage. This extra storage can be accessed through the Objects property, and youcan use the extra storage any way you like. Let's say, for example, that you createan owner-drawn list box that displays bitmaps. You can store the string in the usualway and store a pointer to the TBitmap object in the Objects array.</P><BLOCKQUOTE> <P><HR><strong>TIP:</strong> There might be times when you need to manage a list of strings unrelated to a component. The TStringList class is provided for exactly that purpose. This class works just like TStrings but can be used outside of components. TStringList is particularly convenient for reading, manipulating, and storing text files. <HR><BR> <HR><strong>NOTE:</strong> In reality, TStrings is what is called an <I>abstract base class</I>. An abstract base class is never used directly; it serves only as a base class from which to derive other classes. The Lines property is actually an instance of the TMemoStrings class rather than an instance of the TStrings class as I said in this section. This can be confusing because the Lines property <I>is</I> declared as a TStrings pointer but is actually an instance of TMemoStrings. The declaration and creation of the Lines property looks like this:</P> <PRE>var Lines : TStrings;{ ...later } Lines := TMemoStrings.Create;</PRE></BLOCKQUOTE><PRE></PRE><BLOCKQUOTE> <P>This is why the Lines property appears to be a TStrings but is really not. I didn't mean to lead you astray, but I thought it was best to make this distinction after the discussion on TStrings rather than confuse you with this information during that discussion. <HR></BLOCKQUOTE><P><strong>New Term:</strong> An <I>abstract base class</I> is a class that cannot be useddirectly. A descendent class must be created using the abstract base class, and aninstance of the descendent class is used instead.</P><P><H2><A NAME="Heading17"></A>Standard Windows Control Components</H2><P>Back in the Jurassic age, there was something called Windows 3.0. Windows 3.0gave you options such as edit controls (single line and multiline), list boxes, comboboxes, buttons, check boxes, radio buttons, and static controls. These controls musthave been fairly well designed because they are very prevalent in Windows programstoday--even considering all the new Win32 controls.</P><P>I'm not going to go over every Windows control and its corresponding VCL component.There are a few points, though, that you should know regarding the standard components,which are covered in the next sections.</P><BLOCKQUOTE> <P><HR><strong>NOTE:</strong> I will refer to components in one of two ways: by the component's name or by the name of the VCL class that defines the component. I might say, "The Label component is used for..." or I might say, "TLabel is used for...." In either case, I am talking about the same component. <HR></BLOCKQUOTE><P><H2><A NAME="Heading18"></A>Edit Controls</H2><P>Delphi comes with four edit-control components. The Edit, Memo, and MaskEdit componentsare based on the standard Windows edit control. The RichEdit component is based onthe Win32 rich edit control, which is not one of the standard Windows controls. Still,I will discuss RichEdit here because it has many features in common with the otheredit controls.</P><P><H4>The Edit Component</H4><P>The Edit component encapsulates the basic single-line edit control. This componenthas no Align or Alignment property. It has no Alignment property because the textin a single-line edit control can only be left-justified. The Edit component hasno Align property because it cannot (or more accurately, should not) be expandedto fill the client area of a window.</P><BLOCKQUOTE> <P><HR><strong>TIP:</strong> If you need text in an edit component to be right-justified or centered, use a Memo component but make its height the height of a standard Edit component. Then set the Alignment property as needed. <HR></P> <P><HR><strong>NOTE:</strong> Keep your forms standard whenever possible. Although you can make an Edit component as tall as you like, it will confuse users if you make its height greater than a standard Windows edit control (it might appear to the user to be a multiline edit). <HR></BLOCKQUOTE><H4><BR>The MaskEdit Component</H4><P>The MaskEdit component is an Edit component with an input filter, or mask, attached.The MaskEdit does not represent a Windows control per se, but rather is just a VCLextension of a standard edit control. A mask is used to force input to a specificrange of numbers or characters. In addition, the mask can contain special charactersthat are placed in the edit control by default. For example, a date is commonly formattedas follows:</P><P><PRE>03/21/98</PRE><P>An edit mask for a date can already have the slashes in place so the user onlyhas to enter the numbers. The edit mask would specify that only numbers can be enteredto avoid the possibility of the user entering a nonnumeric character.</P><BLOCKQUOTE> <P><HR><strong>NOTE:</strong> The DateTimePicker component (found on the Win32 tab) enables you to pick a date or a time from a specialized edit component. When the Kind property is set to dtkDate, the component displays a drop-down calendar from which the user can choose a date. When Kind is set to dtkTime, the DateTimePicker displays a multi-field edit control that enables the user to set the hours, minutes, seconds, and AM or PM. The DateTimePicker is preferred over the MaskEdit for date and time entry. <HR></BLOCKQUOTE><P>The EditMask property controls the mask that is used. When you click the ellipsisbutton in the Value column for the EditMask property, the Input Mask Editor is displayed.This dialog box enables you to choose from one of the predefined masks or to createyour own. You can choose prebuilt masks from several countries. Figure 7.3 showsthe Input Mask Editor displaying the United States' set of predefined input masks.</P><P><A HREF="javascript:popUp('28670703.gif')"><B>FIGURE 7.3.</B></A><B> </B><I>TheInput Mask Editor.</I></P><P>For more information on building your own masks, see the Delphi online help.</P><P><H4>The Memo Component</H4><P>The Memo component encapsulates a multiline edit control. The Lines property isthe most significant property in a Memo component. As I mentioned earlier in thediscussion on TStrings, the Lines property enables you to save the contents of theMemo component to disk, load the Memo with text from a file, or access the memo'slines individually.</P><P>The ScrollBars property is unique to the Memo component. This property enablesyou to specify whether your component has a horizontal scrollbar, a vertical scrollbar,or both. You used the ScrollBars property on Day 6 when you wrote the ScratchPadapplication. The Memo component is a very versatile component that you will probablyfind yourself using frequently.</P><P><H4>The RichEdit Component</H4><P>The RichEdit component is the biggest and the best of all the edit components;it is based on the Win32-rich edit control. The RichEdit component enables you tochange fonts, use indentation, set text to bold, italic, or underlined, and muchmore. Basically, the RichEdit component is a mini word processor in one neat package.RichEdit has surprisingly few design-time properties over what the Memo componenthas.</P><P>Key runtime properties include SelAttributes and Paragraph. The RichEdit componentis complex but easy to use, considering its complexities. See the Delphi online helpfor full details on the RichEdit component.</P><P><H4>Common Edit Control Properties</H4><P>Table 7.4 lists the properties specific to components based on edit controls.</P><P><H4>TABLE 7.4. PROPERTIES FOR EDIT CONTROLS.</H4><P><TABLE BORDER="1"> <TR ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT"><I>Item</I></TD> <TD ALIGN="LEFT"><I>Applies To</I></TD> <TD ALIGN="LEFT"><I>Description</I></TD> </TR> <TR ALIGN="CENTER" VALIGN="TOP"> <TD ALIGN="CENTER" COLSPAN="3"> <P ALIGN="CENTER"><B>Properties</B> </TD> </TR> <TR ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT">AutoSelect</TD> <TD ALIGN="LEFT">Edit, MaskEdit</TD>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -