控件调用窗体,写过自定义控件的近来一下;

时间:2022-04-02 17:04:24
本来还以为跟delphi一样,包含一下就可以调用了;

但是编译时却提示:unresolved  extern....


自定义控件中,我想让他调出一个窗体来动态更改某些参数;
所以需要一个窗体,窗体头已经包含到自定义类中;#include "PropertyUnits.h"
然后开始调用:
void  __fastcall  TMyaaaa::PropertyClick(TObject *Sender)
{
TPropertyForm *pForm=new TPropertyForm (this);       //属性窗口
...
delete pForm;
}

单元编译没有问题。,但是一开始link就出现以上错误提示,望各位大大提提示一下如何解决....

10 个解决方案

#1


我的link错误一般的解决方法:
1.在bcb的lib目录下用windwos的查找功能,查含有出错部分函数名的所有.lib或.obj
2.将该lib/obj加入项目(我一般用#pragma link "xxxx.lib"的方法)
这个办法虽然繁了些,但一般能解决问题

#2


To: MEFULEU (没有作不到,只有想不到) 
属性编辑器不是你那样写的。
你可以参照$(bcb)\Examples\ShellControls的rootedit.*就是一个属性编辑页面。

#3


To: MEFULEU (没有作不到,只有想不到) 
属性编辑器不是你那样写的。
你可以参照$(bcb)\Examples\Controls下面也有的,你先看看,如果实在不行。我在给你封装一个例子。

你的组件是设计包运行包一起,还是分开的。

包设计详细的内容可以参考帮助里面的[新建一个用户组件]

#4


假设没有其它的错误.

把this改为Application.

TPropertyForm *pForm=new TPropertyForm (Application);

#5


TComponentClass classes[4] = {
                                    __classid(TShellTreeView)
                                    ,__classid(TShellComboBox)
                                    ,__classid(TShellListView)
                                    ,__classid(TShellChangeNotifier)
                                    };

        RegisterComponents(SPalletePage, classes, (sizeof(classes)/sizeof(TComponentClass))-1);

        // This is now to register property editors for AnsiString's.  ******* pls look  here 
        PPropInfo PropInfo = GetPropInfo(__typeinfo(TShellTreeView), SPropertyName);
        RegisterPropertyEditor(*(PropInfo->PropType),
            __classid(TShellTreeView), SPropertyName, __classid(TRootProperty));
            
        PropInfo = GetPropInfo(__typeinfo(TShellComboBox), SPropertyName);
        RegisterPropertyEditor(*(PropInfo->PropType),
            __classid(TShellComboBox), SPropertyName, __classid(TRootProperty));

        PropInfo = GetPropInfo(__typeinfo(TShellListView), SPropertyName);
        RegisterPropertyEditor(*(PropInfo->PropType),
            __classid(TShellListView), SPropertyName, __classid(TRootProperty));


        PropInfo = GetPropInfo(__typeinfo(TShellChangeNotifier), SPropertyName);
        RegisterPropertyEditor(*(PropInfo->PropType),
            __classid(TShellChangeNotifier), SPropertyName, __classid(TRootProperty));

        RegisterComponentEditor(__classid(TShellTreeView), __classid(TRootEditor));
        RegisterComponentEditor(__classid(TShellListView), __classid(TRootEditor));
        RegisterComponentEditor(__classid(TShellComboBox), __classid(TRootEditor));
        RegisterComponentEditor(__classid(TShellChangeNotifier), __classid(TRootEditor));

#6


//TNcAxisGrid is ur component,and TNcAxisGridCommPropEditor is ur 
//component's PropertyEditor. 

class PACKAGE TNcAxisGridCommPropEditor : public TPropertyEditor
{
public:
virtual void __fastcall Edit(void);
virtual TPropertyAttributes __fastcall GetAttributes(void);
virtual String __fastcall GetValue(void);
#if (__BORLANDC__ == 0x0520)
// TObject.Create
__fastcall TNcAxisGridCommPropEditor(void) : TPropertyEditor() { }
// TPropertyEditor.Destroy
__fastcall virtual ~TNcAxisGridCommPropEditor(void) { }
#endif
};

void __fastcall TNcAxisGridCommPropEditor::Edit(void)
{
  ((TNcAxisGrid *)GetComponent(0))->Edit(); // call component's Property Editor.
}

TPropertyAttributes __fastcall TNcAxisGridCommPropEditor::GetAttributes(void)
{
TPropertyAttributes Attributes;
Attributes << paDialog << paReadOnly;
return Attributes;
}

String __fastcall TNcAxisGridCommPropEditor::GetValue(void)
{
return String("(NcCommunication ...)");
}

// call component's Property Editor.
void __fastcall TNcAxisGrid::Edit(void)
{
NcCommPropForm = new TNcCommPropForm(Application);
if (NcCommPropForm->Execute(FNcCommunication, this) == mrOk){
if (ComponentState.Contains(csDesigning )){
TForm* FormOwner = TNclObject::FindFormOwner(this);
if (FormOwner != NULL){
FormOwner->Designer->Modified();
}
}
}
delete NcCommPropForm;  
NclNcAxisGrid->SetCommunication(*FNcCommunication);
}

然后再注册的时候给你的属性编辑器,注册一下就可以。注册代码上面已经发了,差不多。

#7


多说一句;

属性窗口是我自己的窗体;

控件的bpl包编译没有问题;也可以安装。

但是测试程序却无法link成功;各个目录已经包含完毕了。现在很奇怪的。

#8


应用:

keiy() 的方法似乎可以;

#pragma link "PropertyUnits.obj"

但是我再pck工程中已经包含了PropertyForm了阿;

USEFORM("PropertyUnits.cpp", PropertyForm);
//---------------------------------------------------------------------------
#pragma package(smart_init)
//---------------------------------------------------------------------------

//   Package source.
//---------------------------------------------------------------------------

#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*)
{
        return 1;
}
//---------------------------------------------------------------------------

真是奇怪阿,我再研究一下;


#9


同意truelove7283159(大头娃娃)。
你需要注册一个属性编辑器。

#10


不研究了,什么都不用注册,直接#pragma link "PropertyUnits.obj"

   TPropertyForm *pForm;       //自己的属性窗口
   pForm =new TPropertyForm(this);
   if (pForm->ShowModal()==mrOk)
   {      
        
   }
   delete pForm;


测试程序通过,控件包编译正常;

#1


我的link错误一般的解决方法:
1.在bcb的lib目录下用windwos的查找功能,查含有出错部分函数名的所有.lib或.obj
2.将该lib/obj加入项目(我一般用#pragma link "xxxx.lib"的方法)
这个办法虽然繁了些,但一般能解决问题

#2


To: MEFULEU (没有作不到,只有想不到) 
属性编辑器不是你那样写的。
你可以参照$(bcb)\Examples\ShellControls的rootedit.*就是一个属性编辑页面。

#3


To: MEFULEU (没有作不到,只有想不到) 
属性编辑器不是你那样写的。
你可以参照$(bcb)\Examples\Controls下面也有的,你先看看,如果实在不行。我在给你封装一个例子。

你的组件是设计包运行包一起,还是分开的。

包设计详细的内容可以参考帮助里面的[新建一个用户组件]

#4


假设没有其它的错误.

把this改为Application.

TPropertyForm *pForm=new TPropertyForm (Application);

#5


TComponentClass classes[4] = {
                                    __classid(TShellTreeView)
                                    ,__classid(TShellComboBox)
                                    ,__classid(TShellListView)
                                    ,__classid(TShellChangeNotifier)
                                    };

        RegisterComponents(SPalletePage, classes, (sizeof(classes)/sizeof(TComponentClass))-1);

        // This is now to register property editors for AnsiString's.  ******* pls look  here 
        PPropInfo PropInfo = GetPropInfo(__typeinfo(TShellTreeView), SPropertyName);
        RegisterPropertyEditor(*(PropInfo->PropType),
            __classid(TShellTreeView), SPropertyName, __classid(TRootProperty));
            
        PropInfo = GetPropInfo(__typeinfo(TShellComboBox), SPropertyName);
        RegisterPropertyEditor(*(PropInfo->PropType),
            __classid(TShellComboBox), SPropertyName, __classid(TRootProperty));

        PropInfo = GetPropInfo(__typeinfo(TShellListView), SPropertyName);
        RegisterPropertyEditor(*(PropInfo->PropType),
            __classid(TShellListView), SPropertyName, __classid(TRootProperty));


        PropInfo = GetPropInfo(__typeinfo(TShellChangeNotifier), SPropertyName);
        RegisterPropertyEditor(*(PropInfo->PropType),
            __classid(TShellChangeNotifier), SPropertyName, __classid(TRootProperty));

        RegisterComponentEditor(__classid(TShellTreeView), __classid(TRootEditor));
        RegisterComponentEditor(__classid(TShellListView), __classid(TRootEditor));
        RegisterComponentEditor(__classid(TShellComboBox), __classid(TRootEditor));
        RegisterComponentEditor(__classid(TShellChangeNotifier), __classid(TRootEditor));

#6


//TNcAxisGrid is ur component,and TNcAxisGridCommPropEditor is ur 
//component's PropertyEditor. 

class PACKAGE TNcAxisGridCommPropEditor : public TPropertyEditor
{
public:
virtual void __fastcall Edit(void);
virtual TPropertyAttributes __fastcall GetAttributes(void);
virtual String __fastcall GetValue(void);
#if (__BORLANDC__ == 0x0520)
// TObject.Create
__fastcall TNcAxisGridCommPropEditor(void) : TPropertyEditor() { }
// TPropertyEditor.Destroy
__fastcall virtual ~TNcAxisGridCommPropEditor(void) { }
#endif
};

void __fastcall TNcAxisGridCommPropEditor::Edit(void)
{
  ((TNcAxisGrid *)GetComponent(0))->Edit(); // call component's Property Editor.
}

TPropertyAttributes __fastcall TNcAxisGridCommPropEditor::GetAttributes(void)
{
TPropertyAttributes Attributes;
Attributes << paDialog << paReadOnly;
return Attributes;
}

String __fastcall TNcAxisGridCommPropEditor::GetValue(void)
{
return String("(NcCommunication ...)");
}

// call component's Property Editor.
void __fastcall TNcAxisGrid::Edit(void)
{
NcCommPropForm = new TNcCommPropForm(Application);
if (NcCommPropForm->Execute(FNcCommunication, this) == mrOk){
if (ComponentState.Contains(csDesigning )){
TForm* FormOwner = TNclObject::FindFormOwner(this);
if (FormOwner != NULL){
FormOwner->Designer->Modified();
}
}
}
delete NcCommPropForm;  
NclNcAxisGrid->SetCommunication(*FNcCommunication);
}

然后再注册的时候给你的属性编辑器,注册一下就可以。注册代码上面已经发了,差不多。

#7


多说一句;

属性窗口是我自己的窗体;

控件的bpl包编译没有问题;也可以安装。

但是测试程序却无法link成功;各个目录已经包含完毕了。现在很奇怪的。

#8


应用:

keiy() 的方法似乎可以;

#pragma link "PropertyUnits.obj"

但是我再pck工程中已经包含了PropertyForm了阿;

USEFORM("PropertyUnits.cpp", PropertyForm);
//---------------------------------------------------------------------------
#pragma package(smart_init)
//---------------------------------------------------------------------------

//   Package source.
//---------------------------------------------------------------------------

#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*)
{
        return 1;
}
//---------------------------------------------------------------------------

真是奇怪阿,我再研究一下;


#9


同意truelove7283159(大头娃娃)。
你需要注册一个属性编辑器。

#10


不研究了,什么都不用注册,直接#pragma link "PropertyUnits.obj"

   TPropertyForm *pForm;       //自己的属性窗口
   pForm =new TPropertyForm(this);
   if (pForm->ShowModal()==mrOk)
   {      
        
   }
   delete pForm;


测试程序通过,控件包编译正常;