📄 ch13.htm
字号:
items. Perform these steps:</P><DL> <DT></DT> <DD><B>1. </B>Right-click on the ActionList Editor and this time choose New Action. A new TAction is created and is shown in the Object Inspector. <P> <DT></DT> <DD><B>2. </B>Change the Name property to SaveAction, the Caption property to &Save..., the Category property to File, the Hint property to Save|Save a File, the ImageIndex property to 2, and the ShortCut property to Ctrl+S. <P> <DT></DT> <DD><B>3. </B>Create another new action. Change the Name property to SaveAsAction, the Caption property to Save &As..., and the Category property to File. You don't need to set the Hint or ImageIndex properties because this action doesn't have an associated button on the toolbar. Figure 13.7 shows the ActionList Editor at this point. <P> <DT><A HREF="javascript:popUp('28671307.gif')"><B>FIGURE 13.7.</B></A><B> </B><I>The ActionList Editor after creating the action items.</I></DT> <DT><I></I></DT> <DD><B>4. </B>Close the ActionList Editor. <P></DL><BLOCKQUOTE> <P><HR><strong>NOTE:</strong> You can create categories of actions if you have several dozen actions to keep track of. To create an action category, simply set the Category property of one or more actions to any text you want. For example, to create a category for the edit actions created earlier, set each action's Category property to Edit. Action categories are simply for organization and don't have any bearing on the way actions operate. <HR></BLOCKQUOTE><H4>Attaching Actions to Components</H4><P>The next step is to attach the actions you just created to the various menu itemsand toolbar buttons to which those actions correspond. Perform these steps:</P><DL> <DT></DT> <DD><B>1. </B>Double-click on the MainMenu component to start the Menu Editor. <P> <DT></DT> <DD><B>2. </B>Select the File|Save menu item and change its Action property to SaveAction. <P> <DT></DT> <DD><B>3. </B>Select the File|Save As menu item and change its Action property to SaveAsAction. <P> <DT></DT> <DD><B>4. </B>Move to the Edit menu and select the Cut menu item. Change the Action property to CutAction. <P> <DT></DT> <DD><B>5. </B>Repeat step 4 for the Copy and Paste items on the Edit menu using CopyAction and PasteAction for the Action property, respectively. Close the Menu Editor. <P> <DT></DT> <DD><B>6. </B>In the Form Designer, click on the File Save button on the toolbar. Change the Action property of the button to FileSaveAction. <P> <DT></DT> <DD><B>7. </B>Repeat step 6 for the Cut, Copy, and Paste buttons on the toolbar, setting the Action property to CutAction, CopyAction, and PasteAction, respectively. <P> <DT></DT> <DD><B>8. </B>Change the Action property of the MemoPopup menu items as needed. <P></DL><P>You probably didn't notice, but when you assigned SaveAction to the Action propertyof a component, that component's Caption, Checked, Enabled, HelpContext, Hint, ImageIndex,ShortCut, and Visible properties all changed to the values of those properties inthe SaveAction object. It is important to understand that the action's propertieswill overwrite the properties of any component that the action is assigned to. Youmust set up the action with that in mind. That is why I had you change the Hint andItemIndex properties when you created the actions. Had you not done that, the hinttext and toolbar button glyphs would not be correct.</P><P>Now each of the components just listed is hooked to an action. When a particularaction changes, any components hooked to that action will change as well. Take thefollowing code, for example:</P><P><PRE>SaveAction.Enabled := False;</PRE><P>When this code executes, any components with their Action property set to SaveActionwill be disabled (the main menu Save item and the Save button on the toolbar). Toenable all items associated with this action, use this code:</P><P><PRE>SaveAction.Enabled := True;</PRE><P>It's as simple as that. Because the main menu and toolbar Save components havetheir Action property set to SaveAction, the following two code snippets are equivalent:</P><P><PRE>{ One-shot using the Action. }SaveAction.Enabled := False;{ The hard way. }FileSave.Enabled := False;FileSaveBtn.Enabled := False;</PRE><P>Granted you save only one line of code in this example, but if you have severalcomponents that need to be enabled or disabled, actions can save you a lot of time.After you create an action and associate that action with one or more components,command enabling is as simple as one line of code. The beauty of this system is thatit doesn't matter how many components you need to enable or disable. It's still justone line of code.</P><P>Run the ScratchPad program. Notice that the Cut and Copy buttons are disabled.Type some text in the memo and highlight it. The Cut and Copy buttons on the toolbarare magically enabled. Click anywhere in the memo to deselect the selected text.The Cut and Copy buttons are disabled again. Is the Paste button enabled? If so,type Alt+Print Screen on the keyboard. (This copies the current window to the Clipboardas a bitmap.) When you press Alt+Print Screen, the Paste button should become disabledbecause you can't paste a bitmap into a memo. Select some text and click either theCut or the Copy button. The Paste button is now enabled because the Clipboard containstext you can paste into a memo.</P><P>How does it work? The TEditCopy, TEditCut, and TEditPaste standard actions automaticallyknow how to enable and disable their associated components when any type of editcontrol has input focus. It's not magic, but it's the next best thing to it! Youonly have to create the standard actions and the rest is automatic. You didn't haveto write any code to get the Edit menu command enablers working. You can't beat that!</P><P><H4>Command Enabling for the Save and Save As Items</H4><P>The Edit menu items were easy because you didn't have to write any code. The Filemenu items, Save and Save As, will take a little more work because there are no standardactions for these menu items. Not to worry, though--adding command enabling for thosemenu items doesn't take much time. To implement command enabling for these menu items,you will make use of the OnUpdate event. But first you need a little background informationto put the OnUpdate event in perspective.</P><P>The OnUpdate event provides a convenient place to put your command-enabling code.When your application runs out of messages to process, Windows sends it a WM_ENTERIDLEmessage. Windows, in effect, tells your program, "I don't have anything foryou to do right now, so relax and take it easy for a while." When a Delphi applicationreceives a WM_ENTERIDLE message, it triggers a TAction's OnUpdate event. All youhave to do is create an event handler for the OnUpdate event and do your commandenabling there. You can use the event handler to check the state of the memo componentand enable the Save and Save As items accordingly.</P><P>The only step remaining, then, is to create an event handler for the action'sOnUpdate event. Perform these steps:</P><DL> <DT></DT> <DD><B>1. </B>Double-click the ActionList component to start the ActionList Editor. <P> <DT></DT> <DD><B>2. </B>Select the SaveAction action from the list of available actions. Click on the File action category or (All Actions) if you don't see the action in the action list. <P> <DT></DT> <DD><B>3. </B>In the Object Inspector, double-click the Value column next to the OnUpdate event. The Code Editor displays the OnUpdate event handler. You add code to the event handler in just a bit. <P> <DT></DT> <DD><B>4. </B>Locate the ActionList Editor (use View|Window List if you can't find the ActionList Editor window). Select SaveAsAction from the list of actions. <P> <DT></DT> <DD><B>5. </B>In the Object Inspector, click the drop-down arrow next to the OnUpdate event. Choose SaveActionUpdate from the list. This enables the Save and Save As items to use the same OnUpdate event handler. <P> <DT></DT> <DD><B>6. </B>Close the ActionList Editor. <P></DL><P>Creating the event handler is the simple part, of course. The more difficult aspectis writing the code that goes between the begin and end statements. Listing 13.2shows the completed OnUpdate event handler. Switch to the Code Editor and enter thecode shown in Listing 13.2 into your OnUpdate event handler.</P><P><H4>LISTING 13.2. THE ScratchPad OnUpdate EVENT HANDLER.</H4><PRE>procedure TMainForm.SaveActionUpdate(Sender: TObject);begin { Command enabler for Save and Save As. } SaveAction.Enabled := Memo.Modified and (Length(Memo.Lines.Text) > 0); SaveAsAction.Enabled := SaveAction.Enabled;</PRE><PRE> { The following two command enablers don't use actions. }</PRE><PRE> { Instead the Enabled property of the two menu items } { is accessed directly. } { Command enabler for Select All. } EditSelectAll.Enabled := Memo.Lines.Count > 0; { Command enabler for Undo. } EditUndo.Enabled := Memo.Modified;end;</PRE><P>The SaveAction's Enabled property is set based on whether or not the memo hasbeen modified and whether or not the memo contains text. In a nutshell, the Saveaction is enabled if the memo has been modified since it was loaded and if it containstext. The same value is assigned to the Enabled property of the SaveAsAction. Thisenables both Save and Save As at the same time using the same criteria.</P><P>Notice that I slipped a couple of extra commands into the OnUpdate event handler.The command enablers for the Select All and Undo items of the Edit menu do not useactions. Instead, the Enabled property of the menu items is set directly. Using actionsfor these two items is overkill because there is only one line of code in each case.As long as you have an OnUpdate event handler, you can use it for any type of commandenabling you want. Put another way, this OnUpdate event handler is not exclusivelyfor the File menu items Save and Save As. Any command enabling can be done in theOnUpdate event.</P><BLOCKQUOTE> <P><HR><strong>NOTE:</strong> The OnUpdate event handler might be called thousands of times per second. For that reason, you must keep code in this method as short as possible. <HR><BR> </P> <P><HR><strong>NOTE:</strong> Debugging code in the OnUpdate event handler is tricky. The problem is that any breakpoints in the OnUpdate event handler will be hit as soon as you run the program. You will have to use debugging methods other than straight breakpoints when debugging code in the OnUpdate event handler. Two such methods are conditional breakpoints and using OutputDebugString to send messages to the Event Log. <HR></BLOCKQUOTE><H4>A TCommandList Bonus</H4><P>There's an added benefit to command lists that I haven't mentioned yet. To seethis hidden (up to now) benefit, perform these steps:</P><DL> <DT></DT> <DD><B>1. </B>Select the MainMenu icon on ScratchPad's main form. <P> <DT></DT> <DD><B>2. </B>Change the Images property to ImageList. <P> <DT></DT> <DD><B>3. </B>Do the same for the PopupMenu. <P></DL><P>Now run the program and look at the File and Edit menus. Wow! Instant menu bitmaps!The menu items inherit the ImageIndex property of their associated action. All youhave to do to enable the bitmaps is assign the same image list use for the actionsto the menu's Images property. The rest is automatic.</P><P><H2><A NAME="Heading10"></A>Printing in Delphi Applications</H2><P>Printing is an everyday necessity for most Windows users. Whereas plenty of programsdo not have printing capability, the majority of Windows applications have some formof printing support. I'll cover the basics of printing in this section.</P><P>Providing printing capabilities in a DOS application used to be a real chore.A DOS program had to provide and install printer drivers for every type of printerthat the program supported. That put a huge burden on software developers, especiallyon small companies or shareware developers. Windows changed all that. For the mostpart, Windows takes on the burden of dealing with different printers, printer drivers,and so on. All you have to do is send output to the printer just as you would sendoutput to a window. I'll get to that soon.</P><P>Printing in Delphi applications comes in several flavors. You'll probably be relievedto learn that, in many cases, printing is built into VCL and comes nearly automatically.In other cases, though, you have to do some specialized printing. Before you learnhow to go about that, let's look at the common dialog boxes that pertain to printing.After that I'll discuss the different ways you can print from a Delphi application.</P><P><H3><A NAME="Heading11"></A>The Common Printing Dialog Boxes</H3><P>Windows provides the common Print and Print Setup dialog boxes for use in yourapplications. You use the Print dialog box just before printing begins and the PrintSetup dialog box to configure the printer. First, though, you must add the componentsto your form.</P><P><H4>The Print Dialog Box</H4><P>As I've mentioned, the Print dialog box is displayed just before printing begins,usually when the user chooses File|Print from the main menu. If the user clicks OK,printing begins; if the user clicks Cancel, printing is aborted. Figure 13.8 showsthe Windows Print dialog box in its most basic form.</P><P><A HREF="javascript:popUp('28671308.gif')"><B>FIGURE 13.8.</B></A><B> </B><I>TheWindows Print dialog box.</I></P><P>No doubt this is not the first time you have seen this particular dialog box.The combo box at the top of the dialog box enables you to choose the particular printerto which you want to print. The Properties button brings up a dialog box specificto the printer currently selected that enables you to set the orientation, resolution,and other properties specific to that printer. The Prin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -