我想在应用程序启动后使用自己定制的Hint,那么我先试着把这样写代码:
unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;type
  TForm1 = class(TForm)
  ...
  private
  ...
  public
    procedure DrawHint(Sender:TObject);
end;
var
  ...
implementation
{$R *.dfm}procedure TForm1.DrawHint(Sender:TObject);
begin
  ...
end;
procedure TForm1.FormCreate(Sender:TObject);
begin
  application.onhint:=DrawHint;
end;结果运行是正常的,达到了我预期的效果,那么我又把代码改成下面的样子:
unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;type
  TForm1 = class(TForm)
  ...
  private
  ...
  public
    
end;
var
  ...
procedure DrawHint;   //注意,声明放在了单元的全局变量部分
implementation
{$R *.dfm}procedure DrawHint;
begin
  ...
end;
procedure TForm1.FormCreate(Sender:TObject);
begin
  application.onhint:=DrawHint;
end;这样程序就无法编译通过了,为什么呢?包括我在运行时动态生成的菜单项等等的事件都必须在主窗体的成员部分声明才可以关联执行?

解决方案 »

  1.   

    我帮你顶呀。
    以为Application.OnHint是一个方法指针
    property OnHint: TNotifyEvent read FOnHint write FOnHint;
    TNotifyEvent = procedure(Sender: TObject) of object;
    而你的第二种方法是一个过程
      

  2.   

    因为Application的OnHint事件的定义是一个TNotify,而TNotify的定义如下:
      type TNotifyEvent = procedure (Sender: TObject) ofobject;
    后面的of object就是表示处理这个事件的过程应该是一个对象的方法。因为事件是属于对象的,所以处理事件的过程应该也是对象的方法才对。所以不能用单元的全局过程来作。
    我理解你的想法,大概是觉得处理整个程序的事件的代码不适合写在某个窗体里。如果你想要把相关代码整理在一起,可以单独写一个对象包含所有的处理工程事件的代码即可,不需要一定是窗口的方法。
    另外你可以用Applications控件放在一个DataModule中处理工程事件,可以不用自己写那些事件的关联代码。
      

  3.   

    谁能给我讲讲property OnHint: TNotifyEvent read FOnHint write FOnHint;里面的read/write 还有FOnHint都是什么意思?
      

  4.   

    如果我定义一个过程procedure Myproc;然后申明一个变量var P: Myproc;那么P是作为一个指针指向过程Myproc呢还是作为过程的一个实例?
      

  5.   

    那么这样呢?
    type
      TMyDrawHint=procedure (Sender:TObject) of object;
    var
      MyDrawHint:TMyDrawHint;
    procedure TForm1.Oncreate(Sender:TObject);
    begin
      application.onhint:=MyDrawHint;
    end;
    end;
    这样编译不出错了,但是事件永远不会发生,为什么呢?
      

  6.   

    MyDrawHint:TMyDrawHint;
    只是声明
    MyDrawHint是一个空值 
    建议多看以下书
      

  7.   

    你把几个问题混在一起来看,所以就复杂了。每个分开解释吧。
    1,事件是一个指向方法的指针,也就是说实现它的应该是类的一个方法。这个上面已经解释的比较清楚了。
    2,property是定义属性的语句,property的具体写法和含义,看看帮助应该就可以明白了。或者查一下论坛,最近还有讨论的帖子。在这里你可以认为事件属性就是一个指针值即可。
    3,函数指针的概念。不清楚你对指针是否明白。函数指针和一般的指针基本类似,只不过不能通过New来给指针创建实例,只能把已有的函数实体附给它。如:
      type
        MyPoc = procedure(var I: Integer);
      procedure add(var I: Integer);
      begin
        I := I + 1;
      end;
      procedure Sub(var I: Integer);
      begin
        I := I - 1;
      end
    var
      p: MyPoc;
      i: Integer;
    begin
      i := 1;
      p(i);     //出错,调用空指针
      p = Add;
      p(i);     //add(i);
      p = Sub;
      p(i);     //Sub(i);
    end;
    现在回头看你刚才问的问题,你不过是把一个指针指向另一个指针的地址,但是另一个指针还是空指针,所有不会执行(不出错是因为代码中会先判断指针不为空才调用)。另一方面我觉得你的问题问的很奇怪啊。根本就没有处理事件的代码,你希望会发生什么呢?
      

  8.   

    我学习delphi基本上是所谓“快速原型法”试验出来的,凭着以前pascal的一点点基础摸爬滚打,对于OOP的原理思想并不清楚。
      

  9.   

    学习Delphi其实就按你的办法就很好了,我当初也是整天看着帮助,还有就是拖一个控件到窗口上,挨个看它的属性和方法一点点学会的。其实只要你的基础较好,学Delphi应该是很容易的。因为,Delphi设计的非常清晰简便,一般的功能开发都可以较快的掌握;而且Delphi的体系十分合理一致,基本上掌握了一种类的使用方法就可以类推出很多别的类,所有的问题都可以找出个道理来,不像有些工具,有很多莫名其妙的特殊情况;另外,VCL的整个代码都是可以查看的,很多不清楚的问题都可以通过看源代码来了解,而且也可以从VCL的代码中学到很多面向对象方面的知识。
    书籍方面,推荐Delphi5(6)开发人员指南,全面又不失深度,相当的不错。
    至于OOP编程思想,这个和是不是用Delphi没有太大关系,应该阅读相关书籍来掌握。这方面书籍很多,针对的层面也不相同,《面向对象软件开发教程》似乎不错,李维将要出版的《Inside VCL》应该也很值得期待。