我们知道:
如Table控件,它有一个组件编辑器(双击弹出)FieldEditor。在FieldEditor中我们可以将选定的字段Drag到窗体上去,IDE将自动创建相应的Data-Aware控件。问题是:
这个功能是如何如何实现的,在VCL哪段代码中实现的?
因为在Design阶段,Form无法接受消息,也就不存在消息处理(对否?请指教...)。
如Table控件,它有一个组件编辑器(双击弹出)FieldEditor。在FieldEditor中我们可以将选定的字段Drag到窗体上去,IDE将自动创建相应的Data-Aware控件。问题是:
这个功能是如何如何实现的,在VCL哪段代码中实现的?
因为在Design阶段,Form无法接受消息,也就不存在消息处理(对否?请指教...)。
解决方案 »
- delphi7 里面没有TEncoding这个类怎么办?
- 我想让RICHEDIT中的第一行文字渐变,下面代码为何只能改变最后一个。谢谢。
- ihtmlinputelement的属性不能赋值,ihtmlformelement的过程不能调用?
- 关于delphi for php 的问题,有兴趣的来
- 请高手提供一个视频采集的思路
- TWebBrowser 无 onMouseDown()事件,怎么捕获鼠标点击事件呢
- delphi的报表预览时会自动新建一窗体,有没有办法指定是在哪一个窗体预览,并且上面有一些控制按钮,我可不可以自己做?
- 对这种字串如何格式化?(见内容)
- 关于datetimepicker控件的显示格式问题^_^
- RichEdit问题
- 这个select怎么写?对我来说有点难?
- 关于新邮件到达判断
不要忘记了,DELPHI本身也是一个程序,虽然它是一个集编辑、编译于一身的程序
设计其间对控件的拖动的相应应该是通过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)));由于水平有限,以上仅提供参考,望高手继续!
http://search.csdn.net/expert/topic/58/5806/2002/4/10/637233.htm
我在晚上找到了一个组件:Greatis Form Designer,与我想要的十分相近,但他没有提供源码和说明,不知道哪位大哥手上有能否提供!不甚感谢!!
基本思路是:自己对消息进行处理(有几个消息被VCL截获后过滤掉了)。谢谢楼上兄弟的无私奉献!!!