全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1446
推到 Plurk!
推到 Facebook!

Actions元件使用技巧

 
axsoft
版主


發表:681
回覆:1056
積分:969
註冊:2002-03-13

發送簡訊給我
#1 引用回覆 回覆 發表時間:2002-09-23 09:12:21 IP:61.218.xxx.xxx 未訂閱

Actions !

From "The Bits..." the C Builder Information & Tutorial Site http://www.thebits.org ?The Bits..."2001. ?TheBits.org. All rights reserved This article was originally printed by UK Borland User Group magazine, www.ukbug.co.uk. Actions ! Oh boy have I just spent a fun two days. You see, someone asked on the newsgroups if there was any chance of someone doing an article about Actions, not just a simple use of, but inheriting, creating and registering your own Actions. Like the mug I am, I said yes. So, here you have the result of two days of investigation. Actions are no hard, but finding out where to start is not easy. The documentation are written in that style which suggests you should already know what you should be doing, and of course the source is in Object Pascal. Such is life. In a moment well produce our own custom action, and a small application to demonstrate it, but first, we should check what actions are capable of. My thanks to Mike Orris for clarifying this for me, the clearest way I can explain it is, that an action is basically the place to centralise code. However, to be useful, (that is part of the ActionList component well described by Dr. Bob in the March/April issue), it is code that should respond to user events? click handlers. As with the default actions defined for us, (standard, dataset and window), you will use Actions and ActionLists with buttons, menus and the like. The main advantage being that we can create a package providing a set of default actions for any menus, toolbars that your application, or your group of applications may use. And Action ! Right. Were going to create a set of Actions called Font Actions? which will provide us with a set of actions for handling Fonts within any descendant of TCustomEdit. In the interests of brevity Ill only cover two such Actions here, which Ive called FontAction and SetFontAction, but youll easily be able to add your own. The first will fire the standard TFontDialog and allow the user to choose their own fonts. The second, takes a font set at design time, (or assigned at runtime), and changes the edits font settings to match. The majority of our work is done in FontAction, with others derived from this. To start with create a new package, (File|NewPackage). Under Options | Description type Bug Font Actions? and click OK. Next, with contains?highlighted, hit the Add button; new component tab which makes things a little easier. Under Ancestor type? type TAction. (NB its not available from the drop down list). Class Name?TFontAction, and check the file you want to save if need be. Hit okay and you get the default component generation. The Palette Page?setting doesnt matter as were about to override it. Before we do anything else well set up the Action registration. We do this in the component registration function, currently at the end of the code you have. You need to change the function so it looks as follows,
namespace Fontaction
{
void __fastcall PACKAGE Register()
{
TMetaClass *classes[2] = {__classid(TFontAction), __classid(TSetFontAction)}
        RegisterActions(Font Actions? classes, 1, NULL);
}
}
What were doing here is using the RegisterActions function to ensure our Actions will be visible to a default TActionList. This works in the same way as you would register normal components, indeed you can combine the normal component register calls into the same function if youre registering components as well as Actions. Still, were registering two Actions here. We are naming our group?of Actions Font Actions? and the parameters are fairly straightforward. The NULL is not explained anywhere, other than component writers should pass NULL? which is what well do. Okay, now open the header file and well look at the classes well need. Already there is class PACKAGE TFontAction. Add the following to it,
class PACKAGE TFontAction : public TAction
{
private:
TCustomEdit *FControl;
void __fastcall SetCustomEdit(TCustomEdit *);
protected:
void __fastcall Notification(TComponent *, TOperation);
public:
/*virtual */__fastcall TFontAction(TComponent* Owner);
bool __fastcall HandlesTarget(TObject*);
void __fastcall UpdateTarget(TObject *);
void __fastcall ExecuteTarget(TObject *);
__property TCustomEdit *Control = {read=FControl, write=SetCustomEdit};
__published:
};
This is our main class, the one which does most of the work. Ill talk through the functions when we define them later. Next we add a descendant class, TSetFontAction, as follows
class TSetFontAction : public TFontAction
{
private:
TFont *FFont;
void __fastcall SetFont(TFont *);
public:
__fastcall TSetFontAction(TComponent *);
__fastcall ~TSetFontAction();
void __fastcall ExecuteTarget(TObject *);
__published:
__property TFont *Font = {read=FFont, write=SetFont};
};
Again well look at it in more detail in a moment, but note that all we override is the ExecuteTarget function, all the other functionality comes from the base class. Finally we need a little helper?class, which we use to bypass protection and accessibility problems, in other words, it makes the Font property visible.
class JControl : public TControl
{//expose the font property of TControl
public:
__property Font;
};
The constructor for TFontAction is simplicity and could be inline,
__fastcall TFontAction::TFontAction(TComponent* Owner)
    : TAction(Owner)
{
}
The first function well look at is the HandlesTarget. Nice one this. I havent had time to find out why, but this function fires frequently, I believe as part of the TActionList component. It appears that Target?is passed as each component on the parent of the ActionList, but dont quote me. What we need to do is tell the caller, (whoever it may be), whether the Target?it has passed us is of a type were interested in. This opens the mechanism later for enabling and disabling controls attached to our Action. In our case, we only want to Handle a Target if it is descended from TCustomEdit, *AND* currently has focus.
bool __fastcall TFontAction::HandlesTarget(TObject *Target)
{
if(Target->InheritsFrom(__classid(TCustomEdit)))
{//we can use it
if(reinterpret_cast  (Target)->Focused())
return true;
else
return false;        //its not focused
}
else
{//its not descended from TCustomEdit
return false;   //we don't want it
}
}
The next function, Notification, is used at design time for removing the Action from the ActionList. We simply call the inherited function, and then set the Control to NULL.
void __fastcall TFontAction::Notification(TComponent *AComponent, TOperation Operation)
{
    TAction::Notification(AComponent, Operation);
    if((Operation == opRemove) && (AComponent == Control))
        Control = NULL;
}
SetCustomEdit is used to set the property to the correct control.
void __fastcall TFontAction::SetCustomEdit(TCustomEdit *Value)
{
if(Value)
{//if it's not a custom edit we shouldn't get here
if(FControl != Value)
{
FControl == Value;
Value->FreeNotification(this);
}
}
else
{
FControl = NULL;    
}
}
聯盟----Visita網站http://www.vista.org.tw ---[ 發問前請先找找舊文章 ]--- 發表人 - axsoft 於 2002/09/23 09:26:04
系統時間:2024-04-24 6:02:54
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!