VCL控件,事件指定的问题

wg961423 2012-08-15 01:47:50
如题,按老妖的文章:如何自画ListView的Item(XP效果) http://www.ccrun.com/article.asp?i=656&d=qdc7kg 上的,可以指定,但当CrnDrawListViewItem定义为全局时(因为有好多Form和Frame都要用到这个),却无法通过编译,这是为什么啊?

Unit1.h:

void __fastcall CrnDrawListViewItem(TCustomListView *Sender,
TListItem *Item, TRect &Rect, TOwnerDrawState State)
{
//老妖的文章里是定义在TForm1的private里的
//void __fastcall TForm1::CrnDrawListViewItem(TCustomListView *Sender,TListItem *Item, TRect &Rect, TOwnerDrawState State)
}


Unit1.cpp

__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
ListView1->OwnerDraw = true;
ListView1->RowSelect = true;
ListView1->ReadOnly = true;
ListView1->OnDrawItem =(TLVDrawItemEvent)&CrnDrawListViewItem;
}

报错内容为:
[BCC32 Error] Unit1.cpp(18): E2031 Cannot cast from 'void (_fastcall *)(TCustomListView *,TListItem *,TRect &,TOwnerDrawState)' to 'TLVDrawItemEvent'
Full parser context
Unit1.cpp(13): parsing: _fastcall TForm1::TForm1(TComponent *)
...全文
160 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
ccrun.com 2012-08-15
  • 打赏
  • 举报
回复
最简单的方法就是我在7楼说的,将函数放在一个DataModule中即可,其他单元共用这个数据模块。
ccrun.com 2012-08-15
  • 打赏
  • 举报
回复
myevent需要在.h文件中用extern声明,然后在.cpp中定义就可以了。
wg961423 2012-08-15
  • 打赏
  • 举报
回复
又试了一下,把struct TMyevent myevent;移到unit1去,就可以了
wg961423 2012-08-15
  • 打赏
  • 举报
回复
用ksrsoft的方法可以实现,但在2010里会报下面的警告,这个要如何解决呢?

[ILINK32 Warning] Warning: Public symbol '_myevent' defined in both module E:\PROJECTS\DEBUG\UNIT1.OBJ and E:\PROJECTS\DEBUG\UNIT2.OBJ
缘中人 2012-08-15
  • 打赏
  • 举报
回复
新建一个单元文件,写上类和函数的定义,然后其他单元引用此即可。其他单元进行赋值,
看这个例子
unit2是公共单元

---h文件
#ifndef Unit2H
#define Unit2H
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Dialogs.hpp>
//---------------------------------------------------------------------------
struct TMyevent
{
public:
int a;
void __fastcall Button1Click(TObject *Sender);

};

struct TMyevent myevent;
#endif

----cpp文件


#pragma hdrstop

#include "Unit2.h"

#pragma package(smart_init)

void __fastcall TMyevent::Button1Click(TObject *Sender)
{
ShowMessage("hellO");
}



unit1调用


#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include "Unit2.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}

void __fastcall TForm1::FormCreate(TObject *Sender)
{
Button1->OnClick = myevent.Button1Click;
}
ccrun.com 2012-08-15
  • 打赏
  • 举报
回复
VCL的事件处理函数必须是一个类成员函数。楼主可以考虑把绘制的函数放在一个DataModule的public中,然后各个Form包含了DataModule的头文件以后,就可以使用这个事件处理函数了。
wg961423 2012-08-15
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]

引用 2 楼 的回复:

我是直接写在.h里的,但引用时报错。

不是把事件函数定义成全局函数,而是在每个事件函数引用全局函数
[/Quote]

有N多个Form,每个Form里有1到2个ListView啊,这要改死了啊。
wg961423 2012-08-15
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]

先放到TForm1的public里试试。
因为public所以外部也可以访问到。
赋值的时候
....=Form1->CrnDrawListViewItem;
[/Quote]

目前的情况是:程序改为了EXE+BPL的方式,所以CrnDrawListViewItem是写在公共BPL包里的,公共BPL包里全是全局定义,没有Form,所以。。。
dataxdata 2012-08-15
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

我是直接写在.h里的,但引用时报错。
[/Quote]
不是把事件函数定义成全局函数,而是在每个事件函数引用全局函数
缘中人 2012-08-15
  • 打赏
  • 举报
回复
先放到TForm1的public里试试。
因为public所以外部也可以访问到。
赋值的时候
....=Form1->CrnDrawListViewItem;
wg961423 2012-08-15
  • 打赏
  • 举报
回复
我是直接写在.h里的,但引用时报错。
dataxdata 2012-08-15
  • 打赏
  • 举报
回复
当需要共享一个函数的时候,可以定义一个全局函数,然后在每个相关控件的事件函数中引用这个函数

13,870

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧