📄 ch14.htm
字号:
<strong>NOTE:</strong> You might not be able to continue execution of your program after an exception is raised. Whether you can continue debugging depends on what went wrong in your program. <HR></BLOCKQUOTE><P>Sometimes the except block is in the VCL code. This will be the case for VCL exceptionsthat you don't handle in your code. In this circumstance, the CPU view will showthe execution point.</P><P>Another aspect of debugging with exceptions is that the VCL exception messagebox is displayed even when you are handling the exception yourself. This can be confusingand somewhat annoying if you haven't encountered it before. To prevent the VCL messagebox from being displayed and the debugger from breaking on exceptions, go to theLanguage Exceptions page of the Debugger Options dialog box and uncheck the Stopon Delphi Exceptions check box at the top of the page. When Stop on Delphi Exceptionsis off, the debugger will not pause program execution when a VCL exception is raised.</P><P>As with many other aspects of Delphi and VCL, learning exception handling takes<BR>some time. Remember to use exception handling where necessary, but use traditionalerror-handling techniques for the minor errors.</P><P>The book's code contains a program called EHTest. This program demonstrates raisingand catching several kinds of exceptions. For this program to function properly,be sure that the Stop on Delphi Exceptions option is off as described earlier. Youcan download the book's code at <A target="_new" HREF="http://www.mcp.com/info">http://www.mcp.com/info</A>.Figure 14.2 shows the EHTest program running.</P><P><A HREF="javascript:popUp('28671402.gif')"><B>FIGURE 14.2.</B></A><B> </B><I>TheEHTest program running.</I></P><P><H2><A NAME="Heading14"></A>Using the Registry</H2><P>Once upon a time, Windows programs used configuration files (.ini files) to storeapplication-specific information. The master configuration file is, as you probablyknow, called WIN.INI. Applications could store system-wide information in WIN.INIor application-specific configuration data in a private .ini file. This approachhas several advantages, but also some disadvantages.</P><P>Somewhere along the line someone smarter (presumably) than I decided that thenew way to do things would be to use the Registry to store application-specific configurationinformation. Throughout the land, knaves everywhere bowed to the king and said, "TheRegistry is good." Whether good or bad, conventional wisdom has it that theuse of .ini files is out and the use of the Registry is in.</P><P>The term <I>Registry</I> is short for the Windows Registration Database. The Registrycontains a wide variety of information about your Windows configuration. Just aboutevery option and every setting in your Windows setup is stored in the Registry. Inaddition to the system information stored in the Registry, you will find data specificto installed applications. The type of information stored for each application dependsentirely on the application but can include information such as the last size andposition of the window, a list of most recently used documents for the application,the last directory used when opening a file, and on and on. The possibilities areendless.</P><P>Windows 95 and NT come with a program called the Registry Editor (REGEDIT.EXE)that can be used to browse the Registry and to make changes to the entries in it.</P><BLOCKQUOTE> <P><HR><strong>CAUTION:</strong> Be very careful about making changes to the Registry! Registry changes can affect how individual programs operate and even how Windows itself operates. <HR></BLOCKQUOTE><P>Figure 14.3 shows the Registry Editor as it displays the Delphi Code Insight options.</P><P><A HREF="javascript:popUp('28671403.gif')"><B>FIGURE 14.3.</B></A><B> </B><I>TheWindows Registry Editor.</I></P><P>As you can see from Figure 14.3, the Registry is hierarchical. You can approachthe Registry exactly as you approach files and directories on a hard drive.</P><P><H3><A NAME="Heading15"></A>Registry Keys</H3><P>Each item in the Registry is called a <I>key</I>. A key can be likened to a directoryon your hard drive. To access a particular key, you first have to open the key. Afterthe key is open, you can write to or read from it. Take a look at Figure 14.3. Thekey that is being displayed is</P><P><BR>MY COMPUTER\HKEY_CURRENT_USER\SOFTWARE\BORLAND\DELPHI\4.0\CODE INSIGHT</P><P>You can't see every branch of the Registry tree, but if you look at the statusbar of the Registry Editor you can see the current key displayed. Also notice thatthe Delphi\4.0 key has several <I>subkeys</I>. You can create as many keys and subkeysas you want for your application.</P><P>An individual key can store data in its <I>data items</I>. Every key has a dataitem called (Default). The default value is not normally used because you will almostalways create your own data items for a particular key. By looking at Figure 14.3,you can see that the Code Insight key has the following data items:</P><P><PRE>Auto Code CompletionsAuto Code ParametersCode Complete DelayDeclaration InformationExplorer VisibleScope Sort</PRE><P>If you've been paying attention, you will recognize that these data items correspondto the Code Insight options on the Code Insight page of the Environment Options dialogbox. Each data item has an associated value. You can write to the Registry to changethe data item or you can read the data item.</P><P><H3><A NAME="Heading16"></A>Registry Data Types</H3><P>The Registry has the capability to store several different types of data in thedata items. The primary types of data are the binary data, string, and integer datatypes. The <I>binary data type</I> can be used to store any kind of binary data.You can, for example, store an array of integers in a binary data item. You probablywon't directly use the binary data type very often, if ever.</P><P>For most of your purposes, you will probably be concerned only with reading andwriting strings or integer values. As you can see in Figure 14.3, even numericaldata can be stored as strings. It's really up to you to decide how to store datain the Registry.</P><P>Up to this point, I have discussed what you can do with the Registry but not <I>how</I>you do it. Let's look at that next.</P><P><H3><A NAME="Heading17"></A>The TRegistry Class</H3><P>The Windows API provides several functions for Registry manipulation. These functionsinclude RegCreateKey, RegOpenKey, RegQueryValue, RegSetValue, RegDeleteKey, and manymore. Dealing with the Registry at the API level is a bit tedious. I am thankful(and you should be, too) that the folks at Borland thought to provide a VCL classcalled TRegistry that encapsulates Registry operations. This class provides everythingyou need to write to and read from the Registry. Before I get into how to use theTRegistry class, let's go over the properties and methods of this class.</P><P><H4>TRegistry Properties</H4><P>TRegistry has just four properties. The CurrentKey property contains the valueof the current key, which is an integer value that identifies the key. When you calla TRegistry method, that method acts on the current key. The CurrentKey propertyis set for you when you open a key. This property can be read, but reading it isof dubious value.</P><P>The RootKey and CurrentPath properties work together to build a text string tothe current key. The CurrentPath property contains a text description of the currentkey's path excluding the RootKey value. Take this key, for example:</P><P><PRE>\HKEY_CURRENT_USER\Software\Borland\Delphi\4.0\Code Insight</PRE><P>In this case the root key, \HKEY_CURRENT_USER, comes from the RootKey property,and the value, Software\Borland\Delphi\4.0\Code Insight, comes from the CurrentPathproperty.</P><BLOCKQUOTE> <P><HR><strong>NOTE:</strong> By default, the RootKey has a value of \HKEY_CURRENT_USER. This is where you should store application-specific data, so it is not normally necessary to change the root key. If you need to change the root key, you can assign a new value to the RootKey property. Note that the root key types are not string values, but are special Windows-defined values. Other root key <BR> values include HKEY_CLASSES_ROOT, HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CURRENT_CONFIG, and HKEY_DYN_DATA. <HR></BLOCKQUOTE><P>The LazyWrite property determines how the application writes the data to the specifickey. If LazyWrite is True, control is immediately returned to the application whenyou close the key. In other words, the writing of the key begins and then your applicationgoes on its way. If LazyWrite is False, control will not return to the applicationuntil the writing of the key is completed. By default, LazyWrite is True, and youshould leave it set to True unless you have some critical data that needs to be writtenbefore your application resumes operation.</P><P><H4>TRegistry Methods</H4><P>The TRegistry class has several methods that you use to read from and write tothe Registry. Table 14.1 lists the primary methods and their descriptions.</P><P><H4>TABLE 14.1. PRIMARY METHODS OF TRegistry.</H4><P><TABLE BORDER="1"> <TR ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT"><I>Method</I></TD> <TD ALIGN="LEFT"><I>Description</I></TD> </TR> <TR ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT">CloseKey</TD> <TD ALIGN="LEFT">Closes the key and writes the data to the key. You should close a key as soon as you are done with it, but you don't have to specifically call CloseKey because the TRegistry destructor will close the key for you.</TD> </TR> <TR ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT">CreateKey</TD> <TD ALIGN="LEFT">Creates a key but does not open it for use. Use the OpenKey method rather than CreateKey if you are going to create the key and begin writing data to it.</TD> </TR> <TR ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT">DeleteKey</TD> <TD ALIGN="LEFT">Deletes the specified key. You can specify any key to delete. To delete the current key, pass an empty string to DeleteKey.</TD> </TR> <TR ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT">GetKeyNames</TD> <TD ALIGN="LEFT">Returns all of the subkeys for the current key in a TStrings object. You can use this method if you need to iterate all the subkeys for a given key.</TD> </TR> <TR ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT">GetValueNames</TD> <TD ALIGN="LEFT">Returns the names of all of the data items for the current key. Use this method if you need to iterate the data items of a given key.</TD> </TR> <TR ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT">KeyExists</TD> <TD ALIGN="LEFT">Returns True if the key exists or False if it does not exist. You can use this method to check for the existence of a key before attempting to read the key.</TD> </TR> <TR ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT">LoadKey</TD> <TD ALIGN="LEFT">Loads a key previously stored on disk. See the Delphi online help for specific details.</TD> </TR> <TR ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT">OpenKey</TD> <TD ALIGN="LEFT">Opens the specified key. If the key does not exist, the value of the CanCreate parameter determines whether the key will be automatically created. Use this method rather than CreateKey if you are going to create the key and begin writing data to it because OpenKey creates the key and then opens it, whereas CreateKey just creates the key but does not open it.</TD> </TR> <TR ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT">ReadBinaryData</TD> <TD ALIGN="LEFT">Reads binary data from the specified data item.</TD> </TR> <TR ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT">ReadBool</TD> <TD ALIGN="LEFT">Reads a Boolean value from the specified data item.</TD> </TR> <TR ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT">ReadDateTime</TD> <TD ALIGN="LEFT">Reads a date and time value from the specified data item. The returned value is an instance of the TDateTime class. To retrieve just a date value, use ReadDate; to retrieve just a time value, use ReadTime.</TD> </TR> <TR ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT">ReadFloat</TD> <TD ALIGN="LEFT">Reads a floating-point value from the specified data item.</TD> </TR> <TR ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT">ReadInteger</TD> <TD ALIGN="LEFT">Reads an integer value from the specified data item.</TD> </TR> <TR ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT">ReadString</TD> <TD ALIGN="LEFT">Reads a string value from the specified data item.</TD> </TR> <TR ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT">SaveKey</TD> <TD ALIGN="LEFT">Saves a key to disk so that it can be loaded later with LoadKey. Generally speaking, you shouldn't store more than 2KB (2048 bytes) of data by using this method.</TD> </TR> <TR ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT">ValueExists</TD> <TD ALIGN="LEFT">Returns True if the specified data item exists.</TD> </TR> <TR ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT">WriteBinaryData</TD> <TD ALIGN="LEFT">Writes a binary data item to the specified key. Use this item to store arrays or other types of binary data.</TD> </TR> <TR ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT">WriteBool</TD> <TD ALIGN="LEFT">Writes a Boolean value to the specified data item. The value is converted to an integer and then stored in the data item.</TD> </TR> <TR ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT">WriteDateTime</TD> <TD ALIGN="LEFT">Writes a TDateTime object to the specified data item. To store just a date object, use WriteDate. To store just a time object, use WriteTime. The TDateTime object is converted to a binary data type before being stored.</TD> </TR> <TR ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT">WriteFloat</TD> <TD ALIGN="LEFT">Writes a floating-point value to the specified data item after converting it to binary data.</TD> </TR> <TR ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT">WriteInteger</TD> <TD ALIGN="LEFT">Writes an integer value to the specified data item.</TD> </TR> <TR ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT">WriteString</TD> <TD ALIGN="LEFT">Writes a string to the specified data item.</TD> </TR></TABLE></P><P>Although there are a lot of methods listed in Table 14.1, many of them performthe same operations--they just use different data types. When you know how to useone of these methods, you pretty much know how to use them all. Notice that severalof these methods convert the value passed to binary data and then store it in theRegistry.</P><P><H3><A NAME="Heading18"></A>Using TRegistry</H3><P>Using TRegistry is fairly easy. Most of your interaction with the Registry willrequire just these four steps:</P><DL> <DT></DT> <DD><B>1. </B>Create an instance of the TRegistry class. <P> <DT></DT> <DD><B>2. </B>Create, if necessary, and open a key by using the OpenKey method. <P> <DT></DT> <DD><B>3. </B>Read or write data using one or more of the Read or Write functions. <P> <DT></DT> <DD><B>4. </B>Free the instance of the TRegistry class. <P></DL><BLOCKQUOTE> <P><HR><strong>NOTE:</strong> Before you can use TRegistry, you must add the Registry unit to your
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -