mainwndproc 是protected方法,你的form实例之所以能访问到这个方法是因为你的当前单元中包含了form的子类的定义,所以才能访问到 mainwndproc 这个受保护的方法。比如
type
  TMyWinCtl = class(TWinControl); // 继承TWinControl的一个子类,什么也不做。
  TForm1 = class(TForm)
    btn1: TButton; // 一个按钮
    procedure btn1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  Form1: TForm1; { 在当前单元(文件)中,定义了一个Tform1 的子类,继承自TFoem 
   所以此时当前单元就相当于进入了tform 定义所在的 FORMS 单元,
   DELPHI 中,同一个单元内的所有类及它的成员的可见性都是PLUBLIC的,
   所以你才可以访问到tform1的受保护的mainwndproc 方法
  
 当前上下文中,如果想要按钮btn1也能访问mainwndproc这个受保护的方法,你可以: 
 TWinControl(btn1).mainwndproc .... 即可,
 这样相当于TWinControl定义所在的单元controls被"inline"到了本单元了一样,
 就的吟哦上面讲过同个单元内的各个类的成员都是可见的。 要明确的是,不应该通过实例来调用mainwndproc及其他的任何受保护的方法,这破坏了封装性
}
   
 // 烂键盘打字太痛苦了,新买的键盘送到时都不想打字了。

解决方案 »

  1.   

    发现上面错字一堆
    继上面说的, 如果你要 btn1 也能访问 mainwndproc 方法,就用上面那个 TMyWinCtl 强类型转换一下
    type
      TMyWinCtl = class(TWinControl); // 继承TWinControl的一个子类,什么也不做。
      TForm1 = class(TForm)
        btn1: TButton; // 一个按钮
        procedure btn1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    var
      Form1: TForm1;implementation....
    var
     m:tmeesage;
    begin
     TMyWinCtl(btn1).mainwndproc(m);
    end;
      

  2.   

     // 这也一样,其他控件也同理TMyBTN = class(TButton);var
     m:tmeesage;
    begin
     TMyBTN (btn1).mainwndproc(m); 
    end;
      

  3.   

    俺买了dll的了之前也是用dll的,现在暂时用的是个该死的联想键盘是笔记本外接型的键盘,五官都挤一块,还带个恶心的FN键,切换中英文时极度痛苦
      

  4.   

    今晚 3:45 欧冠,曼城 VS 巴萨 ,阿森纳 VS 拜仁 
      

  5.   

    那我再问一下,比如一个Button是继承自TWinControl,虽然我们在实例化对象里面无法引用MainWndProc,但是在处理消息的时候,如果推倒TWinControl这一级的时候,会不会也会处理MainWndProc这个过程?
      

  6.   


    type
      TForm1 = class(TForm)
        Edit1: TEdit;
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;  TWinControlB=class(TWinControl)
      protected
        procedure ShowMessageB;
      end;var
      Form1: TForm1;
      WinControlA:TWinControlA ;
      WinControlB:TWinControlB;
    implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
    begin
      WinControlB.ShowMessageB;
      WinControlB.MainWndProc()
    end;上面是我刚才些的一个类,我发现WinControlB这个对象可以直接调用MainWndProC是因为TWinControl出现在使用的类对象里面吗?
      

  7.   

    2.protected 用于表示对象方法和字段具有有限的可见性,只能被当前的类和他的子类访问,只用同一个单元中的类,子类和任何代码可以访问protected成员;
      

  8.   

    上面是我看到的一段Protected的解释,TWinControl的子类是TScrollingWinControl ,而不是TFrom啊,为什么能访问呢
      

  9.   

    所以我上面不是说了么,可能说得不太好理解。其实就跟我上面说的一样
    TMyWinCtl = class(TWinControl); // 继承TWinControl的一个子类,什么也不做。你这个就相当于上面
     TWinControlB=class(TWinControl) 只要存在一个继承类的定义代码出现,那么这个被继承的基类(这里你是TWinControl)所在的单元(control)
    就可以被当前所在单元(这里是unit1)所见,所以就能访问到control单元里所有类中定义的代码如果,你仅仅声明一个变量,而没有一个继承的代码定义,被继承的基类所在的单元就不会被访问到
    // TWinControlB=class(TWinControl)  注释掉这行
    WinControl:TWinControl ; // 改直接定义一个TWinControl的变量,这样也不能访问到private、protected
    WinCOntrol.MainProc... // 错误
    同理,因为 TForm1 = class(TForm) ,
    var
     Form1:TForm1; Form1.MainProc... // 有效
      

  10.   

    注意这是DELPHI的特性,跟面向对象无关
    由于这种特性有可能破坏OOP的封装性,所以D2009后就加入了一个新关键字 strict
    strict 可以严格规范对象成员的可见性type 
     MyClass = class(TBassClass)
     strict protected
       .....
     
      

  11.   


    type
      TMyClass = class
       strict protected // 严格域
        procedure func;
      end;var
      o:tmyclass;
    begin
      o:=tmyclass.Create;
      o.func; // 错误,即便代码都在同一个单元内
    end;
    你在VCL源码中找到Control单元,在TControl类的protected 前加上 strict 关键字,
    然后重新编译Control单元生成新的dcp后,以后任何Control单元内之外的地方都不能访问到protected的成员了,
    不过最好不要这样做,官方也没有这样做的原因可能就是为了兼容以前的代码
      

  12.   

    按钮也是windows的窗口,也有句柄也有窗口函数的。