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

📄 delsec05.txt

📁 《Delphi开发人员指南》配书原码
💻 TXT
📖 第 1 页 / 共 3 页
字号:
SECTION 5 - Delphi VCL

This document contains information that is most often provided
to users of this section.  There is a listing of common
Technical Information Documents that can be downloaded from 
the libraries, and a listing of the most frequently asked
questions and their answers.
 
Fax-back Technical Information Documents related to VCL components:
TechFax number: 800-822-4269

  1171  Bug Report Form
  2711  How to Circumvent the "Index not found" Exception
  2776  List of Delphi books from Third-Party Publishers
  2779  Delphi Client/Server and PowerBuilder Compared
  2781  Step by Step Configuration of an ODBC Driver

Delphi FTP and WWW sites on Internet:

  ftp.borland.com
  ftp.netcom.com   /pub/ic/ice-floe.

  http://www.Borland.com
  http://www.cybernetics.net/users/bstowers/delphi-bugs.html
  http://www.coriolis.com/coriolis/whatsnew/delphi.htm

Zip files related to VCL components:

MDI_BGRD.ZIP  Sample MDI application with a wallpaper background.
CURREDIT.ZIP  Currency edit component.

Questions and answers:

------------------------------------------------------------------------

Q: "How can VCL components be created on the fly at run-time?"

A: The following code will create a modal password form at runtime.
   The TPasswordForm type is a TForm descendent class defined either
   in the current unit or in a separate unit referenced by the current
   unit's uses clause.

   with TPasswordForm.Create(Application) do
   begin                               ( i.e TForm1, TPasswordForm etc. } 
      ShowModal;                       { Display form as a modal window }
      Free;                            { Free the form when it is closed }
   end;      

   The following are the general steps to add a component to a form at 
   run-time:  

   1. Declare an instance variable of the component type that you wish to
      create {i.e. TButton }. Note: instance variables are used to point
      to an actual instance of an object. They are not objects themselves.
   2. Use the component's Create constructor to create an instance
      of the component and assign the instance to the instance 
      variable declared in step 1.  All components' Create constructors 
      take a parameter - the component's owner.  Except in special 
      circumstances, you should always pass the form as the owner 
      parameter of the component's Create constructor.
   3. Assign a parent to the component's Parent property (i.e. Form1,
      Panel1, etc).  The Parent determines where the component will be 
      displayed, and how the component's Top and Left coordinates are 
      interpreted. To place a component in a groupbox, set the 
      component's Parent property to the groupbox.  For a component
      to be visible, it must have a parent to display itself within.
   4. Set any other properties that are necessary  (i.e. Width, Height).
   5. Finally, make the component appear on the form by setting the 
      component's Visible property to True. 
   6. If you created the component with an owner, you
      don't need to do anything to free the component - it will be freed
      when the owner is destroyed.  If you did not give the component an
      owner when you created it, you are responsible for making sure
      the component is freed when it is no longer needed.
      The following demonstrates how to add a TButton component to the 
      current form at run-time:  

   var
     TempButton : TButton;  { This is only a pointer to a TButton }    
   begin 
     TempButton := TButton.Create(Self); { Self refers to the form }
     TempButton.Parent := Self;          { Must assign the Parent } 
     TempButton.Caption := 'Run-time';   { Assign properties now }
     TempButton.Visible := True;         { Show to button }
   end; 

   Since the button was created with an owner, it will be freed 
   automatically when its owner, the form, is freed.     

------------------------------------------------------------------------

Q: "How can the event handler of a popup menu item determine which 
   component was right-clicked upon to activate that menu?

A: Use the PopupMenu.PopupComponent property 
   to determine what control the menu was activated for.

   procedure TForm1.PopupItem1Click(Sender: TObject);
   begin
     Label1.Caption := PopupMenu1.PopupComponent.ClassName;
   end;

   The form's ActiveControl property can also be used, however, 
   the active control may not necessarily be the control that
   caused the popup menu to appear. 

------------------------------------------------------------------------

Q: "What are the capacity limits of the standard Delphi controls?"

A: Any component that uses a TList to store information has an upper
   bound of 16368 items. For example, a TTabControl can contain up to
   16368 tabs and the Delphi Component Palette can contain up to
   16368 palette pages.

   Many of the Delphi standard components are wrappers around standard
   Windows controls.  Windows 3.1 imposes its own limits on these 
   components.  For example: a TComboBox or TListbox can hold up to
   5440 items and TMemo or TEdit (and related components) can hold up 
   to 32k of text.

   Windows 3.1 resource space imposes a limit of 570 pages in a 
   TNoteBook component. (It's difficult to get more than 500 window 
   handles in any Windows application.)

   Note 1: Exceeding these limits will raise exceptions or cause Windows
   to behave strangely.
 
   Note 2: Many of the Windows-based capacity limits are much higher 
   in the 16-bit WOW box of Windows NT and in Windows 95.  In future
   32 bit releases of Delphi, virtually all of these limits will 
   disappear.

------------------------------------------------------------------------

Q: "How can I determine the Length in pixels of a string after a
   specific font has been aplied to it?"

A: Use the Canvas methods TextHeight and TextWidth to
   determine the text height and width of a string in
   pixels.  Be sure to assign the font into the Canvas before
   drawing or taking measurements.

   All visual components have a Canvas property, but
   usually this property is protected so that only direct descendents
   can draw on the Canvas.  Since you write much of your code
   inside methods of a TForm descendent, you always have access to 
   your form's inherited Canvas property.  The TPaintBox component
   makes its Canvas property public so that you can draw on the
   component from OnPaint event methods in the form.

   If a component doesn't have a Canvas property you can use the
   following function to get the text width based on the font passed.

   function GetTextWidth(CanvasOwner: TForm; Text : String;
                         TextFont :  TFont): Integer;
   var
     OldFont : TFont;
   begin
     OldFont := TFont.Create;
     try
       OldFont.Assign( CanvasOWner.Font );
       CanvasOWner.Font.Assign( TextFont );
       Result := CanvasOwner.Canvas.TextWidth(Text);
       CanvasOWner.Font.Assign( OldFont );  
     finally
       OldFont.Free;
     end;
   end;

------------------------------------------------------------------------

Q: "Why do some visual components like TPanel and TEdit not have a
   Canvas property?"

A: All descendents of TCustomControl have a Canvas property, however,
   most are protected to prevent 'outsiders' from drawing on the
   component.  Descendents of a component can always access the 
   protected properties they inherit from the component 
   (such as Canvas), but users of the component cannot.

   type
     TCanvasPanel = class(TPanel)
     public
       property Canvas;
     end;

   If you want to draw on a component that doesn't have a public 
   canvas property, consider using a different component that was 
   intended for arbitrary drawing (TPaintBox), or layer components to 
   achieve the desired result (client-align a TPaintBox inside a TPanel
   to get a bevelled, drawable area).

------------------------------------------------------------------------

Q: "How can I get a horizontal scrollbar on a list box?"

A: Send a LB_SetHorizontalExtent message to the listbox's window handle.
   For example, the message could be sent in the form's OnCreate:

   procedure TForm1.FormCreate(Sender: TObject);
   begin
     SendMessage(Listbox1.Handle, LB_SetHorizontalExtent, 1000, Longint(0));
   end;

------------------------------------------------------------------------

Q: "Does Delphi have a component that supports serial communications?"

A: No. However, there are serial communications libraries (and soon 
   Delphi components) for Delphi available from third party vendors
   such as TurboPower, SaxComm, and and others.

------------------------------------------------------------------------

Q: "How can the tab stops be set in a TMemo control?"

A: To change the tab stops for a multiline edit control
   (i.e. a TMemo) send the EM_SetTabStops message to the
   component.  The Tabs array indicates where the tab stops 
   will be located.  Since the WParam parameter to 
   SendMessage is 1, then all tab stops will be set to the 
   value passed in the Tabs array.  Remember to set the
   WantTabs property of TMemo to True to enable the tabs.

   procedure TForm1.FormCreate( Sender : TObject );
   const
     TabInc : LongInt = 10;
   begin
     SendMessage( Memo1.Handle, EM_SetTabStops, 1, Longint( @TabInc ) );
   end;

------------------------------------------------------------------------

Q: "Where is the best place to open a splash screen on program start up?"

A: The best place to open a splash screen is in the project source 
   file after the first Application.FormCreate and before the
   Application.Run.  This is accomplished by creating a form on
   the fly and then displaying it before the application is actual
   opened.

   program Project1;

   uses Forms, Unit1 in 'UNIT1.PAS' {Form1}, Splash;

   {$R *.RES}
   var
     SplashScreen : TSplashScreen;  {in the Splash unit}
   begin
     Application.CreateForm(TForm1, Form1);
     SplashScreen := TSplashScreen.Create(Application);
     try
       SplashScreen.Show;
       SplashScreen.Update; {Process any pending Windows paint messages}
       {
        do other CreatForms or any other processing before the
        application is to be opened.  If the start up processing is
        going to take a long time you may want to run
        Application.ProcessMessages periodically to allow Windows
        to respond to Windows messages.
       }
     finally               {Make sure the splash screen gets released}
       SplashScreen.Free; 
     end;   
     Application.Run;
   end.

------------------------------------------------------------------------

Q: "Why does the OnExit event of a TEdit component not execute when 
   the user clicks on a speed button?  Is there a way to make a 
   an OnExit event execute when a speed button is pressed?"

A: A speed button never actually gets focus, so the active
   control never loses its focus, consequently the active
   control's OnExit event never occurs. 

   One way to execute the active control's OnExit event is to
   explicitly call it in the OnClick event of the speedbutton. 
   For example:

   procedure TForm1.SpeedButton1Click(Sender: TObject);
   begin
     If ActiveControl is TEdit then 
        (ActiveControl as TEdit).OnExit(ActiveControl);
   end;

------------------------------------------------------------------------
  
Q: "When I open the child windows at run-time each one is 
   positioned slightly down and to the right of the previous
   window.  My problem is that if I then close some of the child 
   windows and then open a new one, the new one is placed 
   down and to the right of where the last child window was 
   before I closed it, even though it is no longer there! 
   Is this as designed?"  

A: That's how MDI windows works. VCL doesn't override Windows
   default behavior in this situation.

   Untested suggestion: In the FormCreate procedure try 
   setting the Top, Left, Width & Height properties to the values
   that you require.  The MDI child form's FormCreate is called 
   before the window is displayed.

------------------------------------------------------------------------

Q: "Why can't my program find any of the resources that I put in a .RES 
   file if that .RES file is the same name as my form's unit name?"

A: If the name of an included .RES file is the same as the name
   of a .DPR file Delphi wll overwrite it with it's own .RES file.  
   In addition, the project RES file is for the Delphi project
   manager only; don't edit or add resources to this RES file.  

------------------------------------------------------------------------

Q: "How can you do scrolling functions in a TForm component using 
   keyboard commands?  For example, scrolling the form up and down 
   with the PgUp and PgDn keys.  

⌨️ 快捷键说明

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