Registering a custom Frame

前端 未结 5 1028
说谎
说谎 2021-01-01 04:58

In Delphi 2009, In one of my projects, I have a custom frame with some controls on it which I want to use as the base class for some other controls. I want to register this

5条回答
  •  没有蜡笔的小新
    2021-01-01 05:41

    Yes it can be done!

    I have done precisely what you are asking in both Delphi 2007 and 2009 and can say that it works well for both versions irrespective of update level. I did run into some interesting problems along the way, but the final solution was very straight forward in hind sight (after beating my head against a wall for a day). More about this below in my answer.

    I placed my custom frame into a runtime package referenced by my component's designtime package. This was necessary to allow the frame to be used in applications using runtime packages and also to allow the same frame to be used in other custom component packages. The designtime package also contained a custom module expert to add the frame to the File -> New -> Other... -> "New Items" gallery and to generate custom default module code. That later part was mainly a nicety to save coding time during actual usage and was a royal pain to get right. I chalk that up to learning curve since I could not find a complete example that matched my situation.

    Code from the designtime DPK:

    requires
      DesignIDE,
      FramePageListD11R,
    ...
    contains
      FramePageListPkgReg in 'FramePageListPkgReg.pas',
    

    And from FramePageListPkgReg

    implementation
    
    {$R FramePageListIcons.res}
    
    procedure Register;
      begin
        ...
        RegisterCustomModule(TBaseDisplayFrame, TCustomModule);
        RegisterPackageWizard(TDisplayFrameModuleExpert.Create);
      end;
    

    My frame implementation had no visual components on the frame since my goal was to introduce virtual methods, published properties, events and to implement a custom interface for my dynamic frame handling logic. Here is the contents of the DFM file and part of the PAS file for reference. Please ignore the IDisplayFrameEvent interface since it is irrelevant to the current topic of discussion.

    object BaseDisplayFrame: TBaseDisplayFrame
      Left = 0
      Top = 0
      Width = 500
      Height = 300
      HorzScrollBar.Smooth = True
      HorzScrollBar.Style = ssHotTrack
      HorzScrollBar.Tracking = True
      VertScrollBar.Smooth = True
      VertScrollBar.Style = ssHotTrack
      VertScrollBar.Tracking = True
      TabOrder = 0
    end
    
    TBaseDisplayFrame = class(TFrame, IDisplayFrameEvent)
    private
      FOnPageShow : TDisplayFrameEvent;
      FOnPageHide : TDisplayFrameEvent;
      ...
    published
      ...
      property OnPageShow: TDisplayFrameEvent read FOnPageShow write FOnPageShow;
      property OnPageHide: TDisplayFrameEvent read FOnPageHide write FOnPageHide;
    end;
    

    As for getting the DFM to load, I did not need any special coding. What I did find is that there is a bug in the Delphi IDE that foo bars the inclusion of the form into the package. I do not recall all of the details, but the problem was easily fixed by manually editing the generated DPK code. Here is the relevant part of the DPK for reference. I suspect this is your main problem. Pay careful attention to the comment part of the line since that is critical to DFM inclusion in the package.

    contains
      BaseDisplayFrameModule in 'BaseDisplayFrameModule.pas' {BaseDisplayFrame: TFrame};
    

    Once everything is working, you can create frames as usual and then modify the PAS file and DFM to inherit from the frame. As Jamo noted, do not forget to change "object" to "inherited" in the first line in the DFM. The only quirk I have seen is the name of event handlers on the inherited frame does not conform to typical Delphi naming conventions, but rather derives from the base frame class. This is purely cosmetic and I have not taken the time to figure out if there is an easy fix.

    Best of luck!

提交回复
热议问题