-----------50分!!!-----关于编写Component的一些问题,高手请进!-----------------

stanely 2001-08-23 03:26:30
1.在写属性的时候怎样让Inspector里面的属性面板出现类似Font前面的加号,点一下能出来具体的设置?定义属性为struct类型的???
2....怎样出现下拉菜单样式的?用enmu类型的属性?

3.写事件的原理和具体方法我还没有看懂,<<bcb技术内幕>>又买不起,请各位赐教!
最好是能捕捉windows消息的事件,而且是base class里面没有捕捉的消息.
...全文
202 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
wangledong 2001-08-23
  • 打赏
  • 举报
回复
<<bcb技术内幕>>???!!!!好象是110元
Pasp 2001-08-23
  • 打赏
  • 举报
回复
<<bcb技术内幕>>???!!!!有这本书,多钱,谁写的,不可错过
monsterking 2001-08-23
  • 打赏
  • 举报
回复
不够完整??
Jinglihui 2001-08-23
  • 打赏
  • 举报
回复
一、事件是closure
c++ builder 使用closure 实现事件。 closure是种指针类型该类型的指针指向特殊类实例的特殊方法。作为组件开发,你可以把closure 当成占位符处理:检测事件发生,然后调用用户指定的方法,如果有。closure 拥有一个隐藏的、指向类实例的指针。
二、事件是属性
组件使用属性实现它们的事件。与其它属性不同,事件不使用方法实现它们的读写部分。相反事件属性使用与属性同类型的私有数据成员。根据约定,数据成员的名字同属性一样,但有一个F前缀例如:OnClick closure被存储在TNotifyEvent类型的FOnClick数据成员中,OnClick事件属性的声明类似:
class PACKAGE TControl :public TComponent
{
private:
TNotifyEvent FOnClick;
protected:
__roperty TNotifyEvent OnClick={read=FOnClick,write =FOnClick};

}
事件是属性的主要用处在于:组件用户 可以在对象观察器中为事件指定处理程序。
C++ builder的组件均继承了Windows常见事件的事件,即标准事件。但是这些事件均是内置于控件中,为protected类型,因此应用程序开发员无法为它们指定处理程序,我们自己创建控件时,可以决定是否让自己的事件对用户是否可见。TControl 和TWinControl中标准的事件均声明为protected,同它们对应的方法一样。如果我们继承上述抽象类,并且想使事件在设计或运行时可见,应将它们重新声明为public或是published.如
class PACKAGE TMyControl:public TCustomControl
{
__published:
__porperty OnClick;
};


fengerfeifei 2001-08-23
  • 打赏
  • 举报
回复
比较系统的就在你的机器里面,你看看Trayicon.h和trayicon.cpp
luhongjun 2001-08-23
  • 打赏
  • 举报
回复
看这里:
http://www.csdn.net/expert/topic/245/245791.shtm
stanely 2001-08-23
  • 打赏
  • 举报
回复
最好是推荐及本比较系统的介绍这方面技术的书籍,<<bcb技术内幕>>说的并不明白!
stanely 2001-08-23
  • 打赏
  • 举报
回复
各位大侠,能不能给我一个完整一些的,简单一点的example呢?
HEROIN 2001-08-23
  • 打赏
  • 举报
回复
头文件:
bool __fastcall On_EraseBkGnd(TWMEraseBkgnd &msg);


MESSAGE_HANDLER(CM_CLOSE,TMessage,CM_Close)
MESSAGE_HANDLER(WM_ERASEBKGND,TWMEraseBkgnd,On_EraseBkGnd)
END_MESSAGE_MAP(TForm)
捕获WM_ERASEBKGND消息,消息处理程序为On_EraseBkGnd

monsterking 2001-08-23
  • 打赏
  • 举报
回复
1.属性的类型属于集合或结构。
2.只要取值有限(枚举等)或 属性类型是某种类而此类有实例。
3.如下
.h
class PACKAGE a : public b
{
private:
TNotifyEvent FOnVScrolled ;
TNotifyEvent FOnHScrolled ;
protected:
virtual void __fastcall WMVScroll (TMessage &) ;
virtual void __fastcall WMHScroll (TMessage &) ;

BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_VSCROLL,TMessage,WMVScroll)
MESSAGE_HANDLER(WM_HSCROLL,TMessage,WMHScroll)
END_MESSAGE_MAP (TCustomControl) ;
public:
__fastcall a(TComponent* Owner);
__published:
__property TNotifyEvent OnVScrolled = { read=FOnVScrolled,
write=FOnVScrolled} ;
__property TNotifyEvent OnHScrolled = { read=FOnHScrolled,
write=FOnHScrolled} ;
};
.cpp
void __fastcall a::WMVScroll (TMessage &Message)
{
if(FOnVScrolled!=NULL&&Message.WParamLo==SB_ENDSCROLL)
FOnVScrolled(this);
TObject::Dispatch(&Message);
}
//--------
void __fastcall a::WMHScroll (TMessage &Message)
{
if(FOnHScrolled!=NULL&&Message.WParamLo==SB_ENDSCROLL)
FOnHScrolled(this);
TObject::Dispatch(&Message);
}

fengerfeifei 2001-08-23
  • 打赏
  • 举报
回复
声明
protected:
virtual void __fastcall DoMessage(TMessage &Message);

消息处理
void __fastcall TTrayIcon::DoMessage(TMessage &Message)
{
TPoint point;
TShiftState shift;

switch(Message.Msg)
{
case WM_QUERYENDSESSION:
Message.Result = 1;
break;

case WM_ENDSESSION:
EndSession();
break;

case WM_SYSTEM_TRAY_NOTIFY:
switch(Message.LParam)
{
case WM_MOUSEMOVE:
if (FOnClick)
{
shift = ShiftState();
GetCursorPos(&point);
DoMouseMove(shift, point.x, point.y);
}
break;

case WM_LBUTTONDOWN:
shift = ShiftState();
shift << ssLeft;
GetCursorPos(&point);
DoMouseDown(mbLeft, shift, point.x, point.y);
FIsClicked = true;
break;

case WM_LBUTTONUP:
shift = ShiftState();
shift << ssLeft;
GetCursorPos(&point);

if (FOnClick)
DoClick();

DoMouseUp(mbLeft, shift, point.x, point.y);

if (FAppRestore == imLeftClickUp)
Restore();
if (FPopupMenuShow == imLeftClickUp)
ShowMenu();
break;

case WM_LBUTTONDBLCLK:
DoDblClick();

if (FAppRestore == imLeftDoubleClick)
Restore();
if (FPopupMenuShow == imLeftDoubleClick)
ShowMenu();
break;

case WM_RBUTTONDOWN:
shift = ShiftState();
shift << ssRight;
GetCursorPos(&point);
DoMouseDown(mbRight, shift, point.x, point.y);
break;

case WM_RBUTTONUP:
shift = ShiftState();
shift << ssRight;
GetCursorPos(&point);

DoMouseUp(mbRight, shift, point.x, point.y);

if (FAppRestore == imRightClickUp)
Restore();
if (FPopupMenuShow == imRightClickUp)
ShowMenu();
break;

case WM_RBUTTONDBLCLK:
DoDblClick();

if (FAppRestore == imRightDoubleClick)
Restore();
if (FPopupMenuShow == imRightDoubleClick)
ShowMenu();
break;

case WM_MBUTTONDOWN:
shift = ShiftState();
shift << ssMiddle;
GetCursorPos(&point);

DoMouseDown(mbMiddle, shift, point.x, point.y);
break;

case WM_MBUTTONUP:
shift = ShiftState();
shift << ssMiddle;
GetCursorPos(&point);
DoMouseUp(mbMiddle, shift, point.x, point.y);
break;

case WM_MBUTTONDBLCLK:
DoDblClick();
break;
}
}

TComponent::Dispatch(&Message);
}
stanely 2001-08-23
  • 打赏
  • 举报
回复
拦截windows消息在哪里拦截???
stanely 2001-08-23
  • 打赏
  • 举报
回复
virtual void __fastcall DoMessage(TMessage &Message);
写在哪里?
在Form的声明里面不是可以写
BEGIN_MESSAGE_MAP

END_MESSAGE_MAP
么?
这个怎么用呢?
fengerfeifei 2001-08-23
  • 打赏
  • 举报
回复
可以参考Trayicon.h和trayicon.cpp两个文件的,文件不大很好理解
fengerfeifei 2001-08-23
  • 打赏
  • 举报
回复
1.你定义的属性为枚举类型就行了就有列表每个你都能false或true

2.你定义的属性是bool型或一个class就会有下啦菜单
3.先声明你的消息类型
比如class中这样声明的
Classes

typedef void __fastcall (__closure *TNotifyEvent)(System::TObject* Sender);

然后你申明消息时就可用这个消息类型了比如

__property Classes::TNotifyEvent OnCreate = {read=FOnCreate, write
=FOnCreate};

之后你还要为它写两个私有方法比如
FOnCreate
如果不处理消息的花好说,就在FOnCreate中写

如果要处理消息的花建议再做一个消息拦截的方法比如
virtual void __fastcall DoMessage(TMessage &Message);
然后在其中判断不同的消息而执行不同的方法
比如有个消息要运行OnCreate 啦
那么你就执行FOnCreate方法

stanely 2001-08-23
  • 打赏
  • 举报
回复
?
书生 2001-08-23
  • 打赏
  • 举报
回复
关注~收藏先

13,825

社区成员

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

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