QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3459|回复: 3
打印 上一主题 下一主题

在C++ Builder中定义事件

[复制链接]
字体大小: 正常 放大
xShandow        

43

主题

1

听众

385

积分

升级  28.33%

该用户从未签到

国际赛参赛者

新人进步奖

跳转到指定楼层
1#
发表于 2004-11-17 19:28 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
<><FONT face=宋体 color=#113dee>在C++ BUILDER中,事件是一种委托模型,它是对消息的封装。如果你用过VC,你就知道在VC中并不存在什么事件,而只有消息处理函数,而在C++ BUILDER中则是由事件处理函数来负责响应消息。同是,事件本身也是一指针,它是一个闭包,通常在C++ BUILDER中有两种事件:通知类型事件(即TNOTIFYEVENT,对WINDOWS消息的封装)和自定义事件。除此之外,我们也知道事件是通过一个虚拟函数来点燃的,比如说ONEXIT事件是由DOEXIT虚拟函数点燃的,下面我写一个自定义事件,很明显以下我写的代码中的事件将是对WM_MYMESSAGE消息的封装.. D! ?/ p' g8 J  V+ u" d
.h File2 Z* F% L2 n; k4 c+ h8 _
#include &lt;....&gt;
* F% \$ C  T) _0 J# y% g.....2 l' z) c% T' p) a. f- P
#define WM_MYMESSAGE WM_USER+100
* }. Z$ I; s6 W) B0 dtypedef void __fastcall (__closure *TMyEvent)(TObject *Sender,Param1,Param2,......);</FONT></P>$ l2 |- H1 w5 F2 n$ P( c
<><FONT face=宋体 color=#113dee>class TMyControl:public TWinControl# P- n9 N/ k6 B  l& A
{3 n4 i* s  F0 U5 K+ n/ r
private:
! F) ?  g: n* E# A: B! {   TMyEvent FOnMyEvent;//保存指向事件的指针.2 p6 c: m- [  n" h- y+ ?
   void __fastcall DoSomething(TMessage &amp;Message);. X& F# o; Q( X; Q3 D; j
public:3 K. v. X. g7 |% M* ~" a1 _- `8 w
   BEGIN_MESSAGE_MAP
$ s% N9 N% r' l: X; t# q* O      VCL_MESSAGE_HANDLER(WM_MYMESSAGE,TMessage,DoSomething);) x0 ?) X+ y4 h2 G
   END_MESSAGE_MAP(TControl);   
: v, o3 ~/ J5 {protected:
1 R: B7 D' ]; T8 [6 b& b$ R# G- P   virtual void __fastcall DoMyEvent(Param1,........);//由这个虚拟函数来触发事件- I; h: _, d3 S- ?
   virtual void __fastcall WndProc(TMessage &amp;Message);
2 K8 N: o# I; h/ G' w6 K__published:+ \3 i# S4 s2 w* z/ \* Z. e( i
    .........   
" s% {+ W1 c8 }9 I  W# E    __property TMyEvent OnMyEvent={read=FOnMyEvent,write=FOnMyEvent};
: ^% @# ^6 E5 J9 ]! c, m4 H    .....   
- }8 m- b9 x6 h/ n' y- i};</FONT></P>; I( C1 V' j* [3 D) H
<><FONT face=宋体 color=#113dee>.cpp File</FONT></P>- w. _; ~' n3 S# z
<><FONT face=宋体 color=#113dee>//Omiting constructor and deconstructor, C% N; {7 }8 d* u+ i) }, ^. l
//Virtual function,which will spring the event:TMyEvent
/ s" S  L& }: o$ u5 y3 R' hvoid __fastcall TMyControl:oMyEvent(Param1,.....)
8 o- ]. g  G- @{
  B/ s; T, g% K6 W# Q$ h   if(FOnMyEvent), Z# ?; S, R2 ^6 p
   {6 W2 G; ^# y" W- K6 k! A2 [$ c6 @
       FOnMyEvent(this,Param1,Param2,.....Paramn);
" W) i& d1 @; G! ]+ r; y( S   }1 W) V5 t* M9 r4 d. |5 V1 V
}
" H, T9 x% Q) n! u//Message Handler- n& O; L+ j  A9 |' t6 A
void __fastcall TMyControl:oSomething
, \5 Z+ ]2 @& ], S8 _' w7 K{# ]! k- d) k8 u& N4 Q4 o3 V
  //TODAdd your code here....( U3 ^, r! r! v
}6 b- x. E! A1 s3 u) L
void __fastcall TMyControl::WndProc(TMessage &amp;Message)
0 I- c' z+ n7 A4 f2 }: |( @5 f{$ m8 }2 j% ~- f* w
    if(Message.Msg==WM_MYMESSAGE)
9 w- \3 I$ `( j8 E/ Y2 w. t+ u    {
, p! T; L# E9 Q! u          DoMyEvent(Message.WParam,.....);
: Y4 z+ m* p) A    }
  X& G) q2 w- r5 h4 ]. \0 W    ......& ^) b2 O: d% ^9 r# i' N0 S  S' I
}
" C$ f, i3 ~; E- [* ^* ^9 I0 z按照上而的代码,我们就会在OBJECT INSPECTOR中看到一个ONMYEVENT事件,和其它事件一样,用户只要将代码写到这里来就可以响应消息并根据应用的需求来给出这个事件触发时的行为,上面代码是随手写的,请各位自已加以调整.</FONT></P>
/ H6 E- @6 K/ k; q# @<><FONT face=宋体 color=#113dee></FONT> </P># e; W. N3 I5 r; C- L1 d* T# ~4 i
<><FONT face=宋体 color=#113dee>__closure是一个很奇妙的东西!很不错,很可惜,VC不支持!目前也只有Borland的编译器支持.</FONT></P>
zan
转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
madio        

3万

主题

1310

听众

5万

积分

  • TA的每日心情
    奋斗
    2024-7-1 22:21
  • 签到天数: 2014 天

    [LV.Master]伴坛终老

    自我介绍
    数学中国站长

    社区QQ达人 邮箱绑定达人 优秀斑竹奖 发帖功臣 风雨历程奖 新人进步奖 最具活力勋章

    群组数学建模培训课堂1

    群组数学中国美赛辅助报名

    群组Matlab讨论组

    群组2013认证赛A题讨论群组

    群组2013认证赛C题讨论群组

    <><FONT color=#113dee>__closure是一个很奇妙的东西!很不错,很可惜,VC不支持!目前也只有Borland的编译器支持</FONT></P><><FONT color=#113dee>能不能说说奇妙之处呀!</FONT></P>
    数学建模社会化
    回复

    使用道具 举报

    xShandow        

    43

    主题

    1

    听众

    385

    积分

    升级  28.33%

    该用户从未签到

    国际赛参赛者

    新人进步奖

    <>说一个不是太标准的吧,他可以当成一个函数指针来使用.</P><>我就拿C++Builder里的帮助给你看看吧.</P><>__closure</P><>The __closure keyword is used to declare a special type of pointer to a member function. In standard C++, the only way to get a pointer to a member function is to use the fully qualified member name, as shown in the following example: </P><>class base</P><>{1 w2 Y8 Z! h- ?/ ^( ?  C" S6 y+ z
      public:0 ^" u6 R* L$ P8 c  I
        void func(int x) { };8 _3 A( t4 R* k- e) H$ G4 e4 @
    };
    . l+ B) ?; z7 o2 k' Q* itypedef void (base::* pBaseMember)(int);
    " l* q8 i: [  _int main(int argc, char* argv[])5 K6 I; i3 j1 q+ H8 {5 i
    {
    ( @6 S5 r9 u$ G+ J$ J/ S' C  base        baseObject;
    . ?: X0 T+ x! c  pBaseMember m = &amp;base::func; // Get pointer to member 'func'
    3 C  l& S" U( U7 T; e' S+ g  // Call 'func' through the pointer to member  U" \' n  n: c% y; t& J( p+ o
      (baseObject.*m)(17);
    : i& u0 @$ ~2 R( f  return 0;
    # R0 L4 W! a" s* Q9 S; J}</P><>However, you cannot assign a pointer to a member of a derived class to a pointer to a member of a base class. This rule (called contravariance) is illustrated in the following example:</P><>class derived: public base</P><>{
    9 w+ a8 A- H7 X  public:
    ) O0 j* o8 R( b" N4 l) I0 R& [& T1 t    void new_func(int i) { };$ b  L3 U% \$ V3 I+ e* D: Y
    };8 d& s$ s% w# o4 u( A4 d# w% T
    int main(int argc, char* argv[])
    " V. F, E8 l9 }0 u# `0 ]{& `/ j) I4 |- U# y
      derived         derivedObject;( K4 f, h; y2 I' i
      pBaseMember m = &amp;derived::new_func; // ILLEGAL8 q5 Q! L, a1 l0 K1 s5 V6 p6 F& G" H
      return 0;+ ^( Y0 g5 x$ U6 ]$ F
    }</P><>The __closure keyword extension allows you to skirt this limitation, and more. Using a closure, you can get a pointer to member function for an object (i.e. a particular instance of a class). The object can be any object, regardless of its inheritance hierarchy. The object抯 this pointer is automatically used when calling the member function through the closure. The following example shows how to declare and use a closure. The base and derived classes provided earlier are assumed to be defined.</P><>int main(int argc, char* argv[])</P><>{) `/ x% X6 P/ ?3 V4 J) K
      derived         derivedObject;
    - w- C6 p3 c: T7 A' `1 Z. P/ c  void (__closure *derivedClosure)(int);
    2 g+ n  x5 `+ U. z3 j  B, a4 x     derivedClosure = derivedObject.new_func; // Get a pointer to the 'new_func' member.
    0 {, ?/ g3 K  z8 r  X- x! S                                              // Note the closure is associated with the
    5 R! p! j& [$ |! L- n0 R$ y                                              // particular object, 'derivedObject'.
    8 J' E/ G8 E0 G2 o. u% t     derivedClosure(3);  // Call 'new_func' through the closure.6 M5 t& H+ U; p, i6 [4 z9 \
         return 0;
    0 n% H% ]" C7 y+ x- t}</P><>Closures also work with pointers to objects, as illustrated in this example:</P><>void func1(base *pObj)</P><>{& d6 t: A# z7 k& \  o
      // A closure taking an int argument and returning void./ U* `2 ]' h/ X- ^* y
      void ( __closure *myClosure )(int);</P><>  // Initialize the closure.</P><>  myClosure = pObj-&gt;func;</P><>  // Use the closure to call the member function.</P><>  myClosure(1);% N, W1 p  p* F' t' Y
      return;
    5 L& s/ a  b1 `: R6 p( b+ h}</P><>int main(int argc, char* argv[])</P><>{
    $ r+ K4 f$ [5 e  derived         derivedObject;6 O* s; W" q3 F, ~1 o- |% k
      void (__closure *derivedClosure)(int);
    ; h1 L5 n1 B. X+ w1 K- c; I     derivedClosure = derivedObject.new_func; // Same as before...7 Y* Y$ H+ N  j; `; W4 y
         derivedClosure(3);  0 |0 J" S  N- z( d* |0 c
         // We can use pointers to initialize a closure, too.
    ) |# @& _3 t4 R  Y4 L+ A     // We can also get a pointer to the 'func' member function
    2 T6 m$ E' _) C; A& l# k7 {! k. B# o; D     // in the base class.
    ) f- m6 Q7 l! b2 s5 _) ]4 p     func1(&amp;derivedObject);5 a6 X5 J7 Z, {5 O( f/ a9 Z
         return 0;. s8 h1 v9 t. c3 P2 O+ g/ _# I7 j6 d
    }</P><>Notice that we are passing a pointer to an instance of the derived class, and we are using it to get a pointer to a member function in the base class - something standard C++ does not allow us to do.$ c% C6 D( Q, e4 h
    Closures are a key part of the C++ Builder RAD environment. They give us the ability to assign an event handler in the Object Inspector. For example, a TButton object has an event called OnClick. In the TButton class, the OnClick event is a property that uses the __closure keyword extension in its declaration. The __closure keyword allows us to assign a member function of another class (typically a member function in a TForm object) to the property. When you place a TButton object on a form, and then create a handler for the button抯 OnClick event, C++ Builder creates a member function in the button抯 TForm parent, and assigns that member function to the OnClick event of TButton. This way, the event handler is associated with that particular instance of TButton, and no other. </P>
    回复

    使用道具 举报

    xShandow        

    43

    主题

    1

    听众

    385

    积分

    升级  28.33%

    该用户从未签到

    国际赛参赛者

    新人进步奖

    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2025-5-11 18:09 , Processed in 0.578434 second(s), 67 queries .

    回顶部