Embarcadero XE6中属性编辑器的问题

时间:2014-07-17 02:49:46

标签: c++builder c++builder-xe6

像往常一样,每个新版本的c ++ builder都需要几天的更改...... 我在修复属性编辑器时遇到问题,代码是:

***************** H HILE ***************** ***********

//---------------------------------------------------------------------------

#ifndef ufrmLabelEditorH
#define ufrmLabelEditorH
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.Buttons.hpp>
#include <Vcl.ExtCtrls.hpp>

#include <DesignIntf.hpp>
#include <TypInfo.hpp>
#include <DesignEditors.hpp>
#include <Classes.hpp>

// Add DesignIDE.bpi to your package's Requires list in the Project Manager
#pragma comment(lib, "DesignIDE.bpi")



//---------------------------------------------------------------------------


class TfrmLabelEditor : public TForm
{
__published:    // IDE-managed Components
TPanel *Panel1;
TMemo *Memo1;
TBitBtn *BitBtn1;
TBitBtn *BitBtn2;
private:    // User declarations
public:     // User declarations
__fastcall TfrmLabelEditor(TComponent* Owner);
};


class PACKAGE TLabelProperty : public TStringProperty
{
public:
virtual Designintf::TPropertyAttributes __fastcall GetAttributes() {
    return TStringProperty::GetAttributes()<<paDialog;
}

virtual void __fastcall Edit(void) {
    TfrmLabelEditor *frmEditor = new TfrmLabelEditor(Application);
    frmEditor->Memo1->Lines->Text = GetStrValue();
    try {
        if (frmEditor->ShowModal()==mrOk) {
            int i;
            for (i = 0; i < PropCount; i++) {
                ((TLabel*)GetComponent(i))->Caption = frmEditor->Memo1->Lines->Text;
            }
            Modified();
        }
    } catch (...) {
    }
    frmEditor->Free();
}

};



//---------------------------------------------------------------------------
extern PACKAGE TfrmLabelEditor *frmLabelEditor;
//---------------------------------------------------------------------------
#endif

************** CPP文件 ******************** *****

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "ufrmLabelEditor.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TfrmLabelEditor *frmLabelEditor;
//---------------------------------------------------------------------------
__fastcall TfrmLabelEditor::TfrmLabelEditor(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------

namespace Labelproperty {

void __fastcall PACKAGE Register()
{
    TTypeInfo* typeInfo = new TTypeInfo();
    typeInfo->Name = "AnsiString";
    typeInfo->Kind = tkLString;

    Designintf::RegisterPropertyEditor(typeInfo,__classid(TfrmLabelEditor),"Caption",     __classid(TLabelProperty));

    TComponentClass classes[1] = {__classid(TfrmLabelEditor)};
    RegisterComponents(L"SGM", classes, 0);
}
}

这两个文件都只是设计时c ++包的一部分......

有任何帮助吗?如果没有,请告诉我一些真正有用的c ++ ide !!!!!致谢.....

2 个答案:

答案 0 :(得分:0)

您的Register()函数依赖于不必要的黑客来伪造AnsiString RTTI。不仅如此,但VCL在XE6中使用Unicode字符串,因此除非您的Caption属性实际声明为AnsiString,否则您的属性编辑器将无法正确注册。

让属性本身为您提供正确的RTTI。 RegisterPropertyEditor() documentation甚至证明了这一点。这种方法适用于C ++ Builder(和Delphi)的每个版本:

void __fastcall PACKAGE Register()
{
    PPropInfo pProp = GetPropInfo(__typeinfo(TfrmLabelEditor), "Caption");
    RegisterPropertyEditor(*(pProp->PropType), __classid(TfrmLabelEditor), "Caption", __classid(TLabelProperty));

    TComponentClass classes[1] = {__classid(TfrmLabelEditor)};
    RegisterComponents(L"SGM", classes, 0);
}

更新:话虽如此,此注册将永远不会有效,因为您将RegisterPropertyEditor()的第二个参数设置为错误值。

TfrmLabelEditor本身已实现,仅存在于设计时包中。通过将第二个参数设置为TfrmLabelEditor,仅当TLabelProperty的实例在表单设计器中处于活动状态并且其TfrmLabelEditor属性在其中编辑时,对象检查器才会调用Caption对象检查器。但是表单设计器永远不会在项目中看到TfrmLabelEditor的实例,因此Object Inspector永远不会调用您的TLabelProperty编辑器。这就是为什么你没有看到任何事情发生的原因。

Read the documentation更加谨慎。第二个参数指定具有指定属性类型的指定属性的特定运行时组件类型或所有组件类型的NULLTfrmLabelEditor不符合此条件。

答案 1 :(得分:0)

REMY SOLUTION的一些改编已经奏效,不确定原因:

void __fastcall PACKAGE Register()
{
    TComponentClass classes[1] = {__classid(TfrmLabelEditor)};

    //********* register my editors ******************
    PPropInfo PropInfo = GetPropInfo(__typeinfo(TForm), "Caption");
    Designintf::RegisterPropertyEditor(*(PropInfo->PropType),NULL,"Caption", __classid(TLabelProperty));
    //*************************************************

    RegisterComponents(L"SGM", classes, 0);
}