我们知道:
    如Table控件,它有一个组件编辑器(双击弹出)FieldEditor。在FieldEditor中我们可以将选定的字段Drag到窗体上去,IDE将自动创建相应的Data-Aware控件。问题是:
    这个功能是如何如何实现的,在VCL哪段代码中实现的?
    因为在Design阶段,Form无法接受消息,也就不存在消息处理(对否?请指教...)。

解决方案 »

  1.   

    虽然FORM是无法接受消息,但DELPHI的IDE还是可以处理消息的呀
    不要忘记了,DELPHI本身也是一个程序,虽然它是一个集编辑、编译于一身的程序
      

  2.   

    问题在于:它是如何处理的,在VCL中的哪段代码中实现,谢谢!
      

  3.   

    不知道我说的是否正确:
    设计其间对控件的拖动的相应应该是通过perform()来实现的,先看一下perform()的说明:
    VCL的Perform( )方法适用于所有的TControl派生对象。Perform( )可以向任何一个窗体或控件发送消息,只需要知道窗体或控件的实例。Perform( )需要传递3个参数:消息标识符、wParam和l Param。Perform( )是这样声明的:
      functiong TControl.perform(Msg : Cardinal;WParam,LParam : Longint); Longint;
    要给一个窗体或控件发送一个消息,可以参照下面的代码: 
      Retval := ControlName.Perform(MessageID,WParam,LParam);
    调用了Perform( )后,它要等消息得到处理后才返回。Perform( )把3个参数组装成TMessage记录,
    然后调用Dispatch( )方法把消息传递给Windows的消息系统。
    例如:  Perform(WM_NEXTDLGCTL,0,0);  //把焦点设给下一个控件。我们知道,如果控件不是从Twincontrol继承的,就没有窗口handle,不能接受消息,可以跟踪drag,发现Twincontrol有过程
    procedure CMDrag(var Message: TCMDrag); message CM_DRAG;
    源代码如下:
    procedure TWinControl.CMDrag(var Message: TCMDrag);
    begin
      with Message, DragRec^ do
        case DragMessage of
          dmDragEnter, dmDragLeave, dmDragMove, dmDragDrop:
            if Target <> nil then TControl(Target).DoDragMsg(Message);
          dmFindTarget:
            begin
              Result := Longint(ControlAtPos(ScreenToClient(Pos), False));
              if Result = 0 then Result := Longint(Self);
            end;
        end;
    end;
    然后再跟踪ControlAtPos,如下:
    function TWinControl.ControlAtPos(const Pos: TPoint; AllowDisabled,
      AllowWinControls: Boolean): TControl;
    var
      I: Integer;
      P: TPoint;
      LControl: TControl;
      function GetControlAtPos(AControl: TControl): Boolean;
      begin
        with AControl do
        begin
          P := Point(Pos.X - Left, Pos.Y - Top);
          Result := PtInRect(ClientRect, P) and
                    ((csDesigning in ComponentState) and (Visible or
                    not (csNoDesignVisible in ControlStyle)) or
                    (Visible and (Enabled or AllowDisabled) and
                    (Perform(CM_HITTEST, 0, Longint(PointToSmallPoint(P))) <> 0)));
          if Result then
            LControl := AControl;
        end;
      end;
    begin
      LControl := nil;
      if AllowWinControls and
         (FWinControls <> nil) then
        for I := FWinControls.Count - 1 downto 0 do
          if GetControlAtPos(FWinControls[I]) then
            Break;
      if (FControls <> nil) and
         (LControl = nil) then
        for I := FControls.Count - 1 downto 0 do
          if GetControlAtPos(FControls[I]) then
            Break;
      Result := LControl;
    end;
    估计玄机就在这一句了:      Result := PtInRect(ClientRect, P) and
                    ((csDesigning in ComponentState) and (Visible or
                    not (csNoDesignVisible in ControlStyle)) or
                    (Visible and (Enabled or AllowDisabled) and
                    (Perform(CM_HITTEST, 0, Longint(PointToSmallPoint(P))) <> 0)));由于水平有限,以上仅提供参考,望高手继续!
      

  4.   

    楼主可以参考这个贴子:
    http://search.csdn.net/expert/topic/58/5806/2002/4/10/637233.htm
      

  5.   

    谢谢楼上各位兄弟的大力帮助,对我很有启发!!!
    我在晚上找到了一个组件:Greatis Form Designer,与我想要的十分相近,但他没有提供源码和说明,不知道哪位大哥手上有能否提供!不甚感谢!!
      

  6.   

    终于在国外的站点上找到了一点启发,有一些突破,但还没有完全成功。
    基本思路是:自己对消息进行处理(有几个消息被VCL截获后过滤掉了)。谢谢楼上兄弟的无私奉献!!!