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

📄 cb199910nf_f.asp.htm

📁 C++builder学习资料C++builder
💻 HTM
📖 第 1 页 / 共 2 页
字号:
      <P class=Code><SPAN    

      class=Code>&nbsp;&nbsp;&nbsp;&nbsp;RegisterComponents("Informant",    

      classes, 0);</SPAN></P>   

      <P class=Code><SPAN class=Code>&nbsp;&nbsp;}</SPAN></P>   

      <P class=Code><SPAN class=Code>}</SPAN></P>   

      <P class=Code><SPAN class=Code><I><SPAN class=CodeBlue>//    

      --------------------------------------------------------</SPAN></I></SPAN></P>   

      <P class=Captions><B>Figure 4:</B> The wizard creates skeleton source for    

      the component.<B> </B></P>   

      <P class=BodyText> </P>   

      <P class=BodyText>As mentioned earlier, custom components are classes    

      subclassed from existing classes. To be a component, a class must inherit    

      from at least <I style="mso-bidi-font-style: normal">TComponent</I>. This    

      is the class that encapsulates the common behavior evidenced by all    

      components, namely, the ability to be dropped on a form at design time, to    

      have properties set in the Object Inspector, and to be registered on the    

      Component palette. Not surprisingly, the <I>DefaultedDBNavigator</I>    

      inherits from the built-in <I>TDBNavigator</I> class. </P>   

      <P class=BodyText> </P>   

      <P class=BodyText>Notice that the PACKAGE modifier is added to the class    

      declaration. This facilitates the instantiation from the package DLL.    

      Currently, the only method that appears in the class declaration is the    

      constructor. For this simple component, no methods need to be added, thus    

      this header file doesn't need to change. </P>   

      <P class=BodyText> </P>   

      <P class=BodyText>The source file includes some handy header files    

      (including the header file for this component), and a method named    

      <I>ValidCtrCheck</I>. This function is automatically included in every    

      custom component's source file. It allows the component user to try to    

      instantiate an instance of the component to ensure that none of the    

      methods are pure virtual methods. In other words, this function is a    

      helper to ensure the class is legally instantiable. It does this by    

      creating a new instance of the class, then immediately allowing it to go    

      out of scope. If the class cannot be created, an exception is thrown    

      indicating that some methods aren't implemented. </P>   

      <P class=BodyText> </P>   

      <P class=BodyText>The empty constructor is also present in the source    

      file. It includes in its member initialization list the constructor call    

      to the parent class' constructor. This is a convenience; one of the    

      classic blunders when creating components in Delphi/C++Builder is to    

      forget to chain the call to the parent's constructor. This call to the    

      base class constructor should never be removed. </P>   

      <P class=BodyText> </P>   

      <P class=BodyText>The last entry in the source file is the <I>Register</I>    

      function, included in a specific custom name space. This function takes    

      care of registering the component onto the Component palette. The name of    

      the palette page specified from the wizard is included here and can be    

      changed here. </P>   

      <P class=BodyText> </P>   

      <P class=BodyText>To override default property values for a component, the    

      new values need only to be added to the constructor. So, to create the    

      custom navigator with the desired characteristics, three lines of code    

      must be added to the constructor. This newly modified constructor is shown    

      in Figure 5. First, the current button set of the navigator is cleared.    

      Then, new values are added to the empty button set. Last, the    

      <I>ShowHint</I> property is toggled to <B>true</B>.</P>   

      <P class=BodyText> </P>   

      <P class=Code><SPAN class=Code><B>__fastcall</B>    

      TDefaultedDBNavigator::TDefaultedDBNavigator(</SPAN></P>   

      <P class=Code><SPAN class=Code>&nbsp;&nbsp;TComponent* Owner):    

      TDBNavigator(Owner)</SPAN></P>   

      <P class=Code><SPAN class=Code>{</SPAN></P>   

      <P class=Code><SPAN    

      class=Code>&nbsp;&nbsp;VisibleButtons.Clear();</SPAN></P>   

      <P class=Code><SPAN class=Code>&nbsp;&nbsp;VisibleButtons =</SPAN></P>   

      <P class=Code><SPAN class=Code>&nbsp;&nbsp;&nbsp;&nbsp;VisibleButtons    

      &lt;&lt; nbFirst &lt;&lt; nbPrior &lt;&lt; nbNext &lt;&lt;    

      nbLast;</SPAN></P>   

      <P class=Code><SPAN class=Code>&nbsp;&nbsp;ShowHint = <B    

      style="mso-bidi-font-weight: normal">true</B>;</SPAN></P>   

      <P class=Code><SPAN class=Code>}</SPAN></P>   

      <P class=Captions><B>Figure 5:</B> To override default property values for    

      a component, the new values need to be added to the constructor.<B    

      style="mso-bidi-font-weight: normal"></B></P>   

      <P class=BodyText> </P>   

      <P class=BodyText>To install the component, the package must be compiled,    

      which is accomplished via the Package editor. Like a project, it will    

      automatically compile all the constituent source files that have been    

      changed since the last compilation. Once it has been successfully    

      compiled, the components in the package are installed on the Component    

      palette by choosing the Install button on the Package editor. In this    

      case, a new palette page is created, and the new    

      <I>TDefaultedDBNavigator</I> appears, ready for use. </P>   

      <P class=BodyText> </P>   

      <P class=Subheads>"Defaulted" Component Characteristics</P>   

      <P class=BodyText>When this new component is dropped on a form, only the    

      navigation buttons appear, and the <I>ShowHint</I> property is <B>true    

      </B>by default. This new component is shown in Figure 6. </P>   

      <P class=BodyText> </P>   

      <P class=Captions><IMG height=91    

      src="images/CB199910nf_f_image008.gif" width=250    

      tppabs="http://www.cbuilderzine.com/features/1999/10/CB199910nf_f/CB199910nf_f_image008.gif">    

      <BR><B>Figure 6:</B> When the new component is dropped on a form, only the    

      navigation buttons appear, and the <I>ShowHint</I> property is <B>true</B>    

      by default.<B> </B></P>   

      <P class=BodyText> </P>   

      <P class=BodyText>However, what will happen now if the developer changes    

      one of these properties? Will it allow these changes and allow the    

      properties to be set at both design time and run time? In fact, it will.    

      The developer can still change these new defaults in the Object Inspector    

      and they will appear correctly at run time. How can this be? Aren't these    

      properties being set to their values in the constructor of the class? The    

      answer to this puzzle lies in the way C++Builder builds forms at run time    

      (and, by extension, design time as well). This is slightly simplified, but    

      close enough to illustrate the point. </P>   

      <P class=BodyText> </P>   

      <P class=BodyText>First, C++Builder fires the constructor for the form.    

      During this step, it opens the contents of the DFM file (which is at this    

      time embedded within the executable), reads the names of all the    

      components, and constructs them one by one. When it constructs them,    

      however, it ignores the property settings embedded in the DFM file. So,    

      the order in which the components are created corresponds to the order in    

      which they appear in the DFM file. Second, after the form's constructor    

      has finished, it goes back to the DFM file and starts applying all the    

      changes to the default values of all the components. </P>   

      <P class=BodyText> </P>   

      <P class=BodyText>Notice that C++Builder always constructs components with    

      all their default values and later applies the DFM changes. This also    

      explains why this new component works correctly; even though the new    

      defaults are set in the constructor of the component, the form will ensure    

      that whatever changes are embedded in the DFM file will overlay these new    

      defaults. This means it's easy and useful to create these "lightweight"    

      components with new defaults because it doesn't preclude the developer    

      from changing the defaults if required. </P>   

      <P class=BodyText> </P>   

      <P class=BodyText>This technique works equally well with database    

      components. For example, if a particular project always used the same    

      database connection characteristics, it would be easy to create a custom    

      Database component that already had all the connectivity options set, e.g.    

      user name, password, server characteristics, etc. The same is true for    

      tables or queries that are reused often. </P>   

      <P class=BodyText> </P>   

      <P class=BodyText>It's possible for the developer to take advantage of the    

      behavior of the form-loading architecture. One of the methods that can be    

      overridden in a component is the <I>Loaded</I> method. The form    

      automatically calls this method when it has finished applying the changes    

      in the DFM file. This means the component developer can add some of his or    

      her own behavior at this time. Some of the components created in future    

      installments of this series will illustrate this technique. </P>   

      <P class=BodyText> </P>   

      <P class=BodyText>When the new component is installed, it will take on the    

      component bitmap of its immediate parent or the "generic" component bitmap    

      (which is similar to the Shape component bitmap). It's also possible to    

      create your own new component bitmaps. </P>   

      <P class=BodyText> </P>   

      <P class=Subheads>Component Bitmaps</P>   

      <P class=BodyText>Palette bitmaps aren't compiled into the component unit    

      because they're only needed at design time, not at run time. Instead, they    

      should be supplied in a resource file with a .DCR (Dynamic Component    

      Resource) extension and the same name as the component unit. This is a    

      critical requirement; the bitmap will not load if the names differ.    

      C++Builder provides an Image Editor tool to create component bitmap images    

      (see Figure 7). It creates a new DCR file. </P>   

      <P class=BodyText> </P>   

      <P class=Captions><IMG height=215    

      src="images/CB199910nf_f_image010.gif" width=250    

      tppabs="http://www.cbuilderzine.com/features/1999/10/CB199910nf_f/CB199910nf_f_image010.gif">    

      <BR><B>Figure 7: </B>The Image Editor.<B> </B></P>   

      <P class=BodyText> </P>   

      <P class=BodyText>To create an image for a particular component, the    

      developer right-clicks and chooses to create a new bitmap. This leads to    

      the Bitmap Properties dialog box, shown in Figure 8. The image must be    

      24x24 pixels square and VGA (16 colors). </P>   

      <P class=BodyText> </P>   

      <P class=Captions><IMG height=132    

      src="images/CB199910nf_f_image012.gif" width=250    

      tppabs="http://www.cbuilderzine.com/features/1999/10/CB199910nf_f/CB199910nf_f_image012.gif">    

      <BR><B>Figure 8: </B>The Bitmap Properties dialog box. </P>   

      <P class=BodyText> </P>   

      <P class=BodyText>To actually create the bitmap, the speed menu option for    

      editing the bitmap should be selected. A palette to create or edit the    

      bitmap image will appear, as shown in Figure 9. The developer can create    

      as elaborate an image as possible given the limited size and palette    

      available. To many developers, this is the most difficult aspect of    

      component creation. </P>   

      <P class=BodyText> </P>   

      <P class=Captions><IMG height=227    

      src="images/CB199910nf_f_image014.gif" width=250    

      tppabs="http://www.cbuilderzine.com/features/1999/10/CB199910nf_f/CB199910nf_f_image014.gif">    

      <BR><B>Figure 9:</B> A palette to create or edit bitmap images.<B>    

</B></P>   

      <P class=BodyText> </P>   

      <P class=BodyText>If the component has already been added to the palette,    

      it must be removed from the package and re-added to force C++Builder to    

      include the DCR file in the package. Once it's been correctly installed,    

      it will appear along with the component in the Package editor. The    

      <I>DefaultedDBNavigator</I> component (along with its bitmap) is shown in    

      Figure 10. </P>   

      <P class=BodyText> </P>   

      <P class=Captions><IMG height=72    

      src="images/CB199910nf_f_image016.jpg" width=177    

      tppabs="http://www.cbuilderzine.com/features/1999/10/CB199910nf_f/CB199910nf_f_image016.jpg">    

      <BR><B>Figure 10: </B>The <I>DefaultedDBNavigator</I> component and its    

      bitmap.<B> </B></P>   

      <P class=BodyText> </P>   

      <P class=Subheads>Up Next</P>   

      <P class=BodyText>C++Builder has created the most powerful, yet    

      easy-to-use, component model ever seen in the C++ world. This article    

      doesn't even begin to scratch the surface. In the next installment of this    

      series, the implications and implementation of new component properties    

      will be discussed. The technique of object wrapping (taking some complex    

      behavior and wrapping it into a component) will also be discussed. </P>   

      <P class=BodyText> </P>   

      <P class=BodyText><I>The files referenced in this article are available    

      for <a href="download/CB199910nf_f.zip" tppabs="http://www.cbuilderzine.com/features/1999/10/CB199910nf_f/CB199910nf_d.asp">download</a>.   

      </I></P>  

      <P class=BodyText> </P>  

      <P class=Biotext>Neal Ford is Vice President of Technology at The DSW    

      Group. He is also the designer and developer of applications,    

      instructional materials, magazine articles, video presentations, and    

      co-author of <I>JBuilder 3 Unleashed</I> [SAMS, 1999]. He can be reached    

      at <A    

      href="mailto:nford@thedswgroup.com">mailto:nford@thedswgroup.com</A>, or    

      by calling The DSW Group at (800) 356-9644. </P>   

      <!-- Abstract<p class=Abstract>Neal Ford   

begins a series on creating custom components in C++Builder. Part I kicks off   

with an introduction to new defaults for native components. </p>Abstract -->   

      <!-- Blurb<p class=Blurb>Whether a component user or a component writer, you're sure to   

gain productivity after reading this series on creating custom components.</p>Blurb --></TD></TR></TBODY></TABLE>   

<!-- <PubToken>cb</PubToken> --></BODY></HTML>   

⌨️ 快捷键说明

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