【问题标题】:Problems with property editor in Embarcadero XE6Embarcadero XE6 中的属性编辑器问题
【发布时间】:2014-07-17 02:49:45
【问题描述】:

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

***************** H 文件 ***************** ***********

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

#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!!!!!!!谢谢.....

【问题讨论】:

  • 问题是……?
  • 为什么要为设计时编辑器的属性注册属性编辑器?您应该将其注册为运行时组件的属性。你的组件在哪里?
  • Matt:问题是什么都没有发生,代码运行没有错误,包安装正常,但是没有字幕编辑器……仅此而已,Embarcadero 的典型……
  • Remy:我不明白你的问题,编辑器是为 TLabel 和其他组件的标题属性制作的。
  • 关于其他 IDE 的建议,我不是在开玩笑,我已经厌倦了与 Embarcadero 斗争的生活。如果有人有其他 IDE 的提示,我将不胜感激!

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


【解决方案1】:

您的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,仅当TfrmLabelEditor 的实例在表单设计器中处于活动状态并且其Caption 属性在对象检查器中被编辑时,对象检查器才会调用TLabelProperty。但是表单设计器永远不会在项目中看到TfrmLabelEditor 的实例,因此对象检查器永远不会调用您的TLabelProperty 编辑器。这就是为什么你看不到任何事情发生的原因。

Read the documentation更加小心。第二个参数指定一个特定的 runtime 组件类型,或 NULL 用于所有组件类型,它们具有指定属性类型的指定属性。 TfrmLabelEditor 没有资格。

【讨论】:

  • 嗨 Remy,感谢您的 cmets,我已经尝试了您的确切代码,但仍然无法正常工作!没有错误,编译ok,添加包ok但还是没有编辑器...
  • 它不起作用,因为您将RegisterPropertyEditor()的第二个参数设置为错误的值。
【解决方案2】:

对 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);
}

【讨论】:

  • 它“有效”是因为您正在从已知的运行时组件中检索本机 String RTTI,然后将 RegisterPropertyEditor() 的第二个参数设置为 NULL,因此您实际上是在说“注册 TLabelProperty for Caption 为字符串的所有组件的 Caption 属性”。您的原始代码改为“为 TfrmLabelEditor 的 Caption 属性注册 TLabelProperty,其中 Caption 是 AnsiString”,这将不起作用。
猜你喜欢
  • 2014-08-27
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
  • 1970-01-01
  • 1970-01-01
  • 2012-11-29
  • 2018-08-25
  • 1970-01-01
相关资源
最近更新 更多