MMIde.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:14k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. unit MMIDE;
  2. {$I COMPILER.INC}
  3. interface
  4. uses
  5. {$IFDEF WIN32}
  6.   Windows,
  7. {$ELSE}
  8.   WinProcs,
  9.   WinTypes,
  10. {$ENDIF}
  11. {$IFDEF DELPHI6}
  12.   DesignIntf,
  13.   DesignEditors,
  14. {$ELSE}
  15.   DsgnIntf,
  16. {$ENDIF}
  17.   SysUtils,
  18.   Classes,
  19.   Graphics,
  20.   Forms,
  21.   Messages,
  22.   MMDesign,
  23.   MMUtils;
  24. type
  25.     {-- TMMDesignerEditor -----------------------------------------------------}
  26.     TMMDesignerEditor = class(TComponentEditor)
  27.     public
  28.        procedure Edit; override;
  29.        function  GetVerbCount: integer; override;
  30.        function  GetVerb(Index: integer): string; override;
  31.        procedure ExecuteVerb(Index: integer); override;
  32.     end;
  33. procedure RegisterProperty(PropType: TPropType; const PropGroup: string; ClassFrom: TClass;
  34.                            const PropName: string; ClassTo: TClass;
  35.                            CheckProc: TConnectCheck);
  36. procedure RegisterPropertyException(PropType: TPropType; const PropGroup: string; ClassFrom: TClass;
  37.                                     const PropName: string; ClassTo: TClass;
  38.                                     CheckProc: TConnectCheck);
  39. implementation
  40. {== Service routines ====================================================}
  41. {------------------------------------------------------------------------}
  42. procedure RegisterProperty(PropType: TPropType; const PropGroup: string; ClassFrom: TClass;
  43.                            const PropName: string; ClassTo: TClass;
  44.                            CheckProc: TConnectCheck);
  45. begin
  46.    PropList.Add(TPropRec.Create(PropType,PropGroup,ClassFrom,PropName,ClassTo,CheckProc));
  47. end;
  48. {------------------------------------------------------------------------}
  49. procedure RegisterPropertyException(PropType: TPropType; const PropGroup: string; ClassFrom: TClass;
  50.                                     const PropName: string; ClassTo: TClass;
  51.                                     CheckProc: TConnectCheck);
  52. begin
  53.    ExcPropList.Add(TPropRec.Create(PropType,PropGroup,ClassFrom,PropName,ClassTo,CheckProc));
  54. end;
  55. {------------------------------------------------------------------------}
  56. function FindDesignerForWindow(Wnd: HWND): TMMDesigner;
  57. var
  58.     i : Integer;
  59. begin
  60.    { It is no sense to have multiple different designers for one window }
  61.    if (ControlList <> nil) and (ControlList.Count > 0) then
  62.    for i := 0 to ControlList.Count-1 do
  63.    begin
  64.       with TMMDesigner(ControlList.Items[i]) do
  65.       if Active and ((ParentForm.Handle = Wnd) or
  66.          IsChild(ParentForm.Handle, Wnd)) then
  67.       begin
  68.          Result := TMMDesigner(ControlList.Items[i]);
  69.          Exit;
  70.       end;
  71.    end;
  72.    Result := nil;
  73. end;
  74. {------------------------------------------------------------------------}
  75. procedure RedrawTrack(Show: Boolean);
  76. begin
  77.    if (DragDesigner <> nil) and (TrackVisible <> Show) then
  78.    {$IFDEF BUILD_ACTIVEX}
  79.    begin
  80.       DrawRubberLine(DragDesigner.ParentForm,
  81.                      Rect(DragOrigin.X,DragOrigin.Y,
  82.                           DragPoint.X,DragPoint.Y));
  83.    end;
  84.    {$ELSE}
  85.    with DragDesigner.ParentForm,DragDesigner.ParentForm.Canvas do
  86.    begin
  87.       Pen.Color := clWhite;
  88.       Pen.Mode := pmXor;
  89.       if Adjusting then
  90.       begin
  91.          Pen.Width := 2;
  92.          MoveTo(0,DragPoint.Y);
  93.          LineTo(Width,DragPoint.Y);
  94.          Pen.Width := 1;
  95.       end
  96.       else
  97.       begin
  98.          MoveTo(DragOrigin.X,DragOrigin.Y);
  99.          LineTo(DragPoint.X,DragPoint.Y);
  100.       end;
  101.       Pen.Mode := pmCopy;
  102.    end;
  103.    {$ENDIF}
  104.    TrackVisible := Show;
  105. end;
  106. {------------------------------------------------------------------------}
  107. function GetMsgProc(Code: Integer; WParam: Word; LParam: Longint): LongInt;
  108. export;{$IFDEF WIN32}stdcall;{$ENDIF}
  109. var
  110.    Msg: ^TMsg;
  111.    Pt: TPoint;
  112.    Rect: TRect;
  113.    WndDesigner: TMMDesigner;
  114.    Target: TComponent;
  115.    TargetType: TPropType;
  116.    {$IFDEF DELPHI4}
  117.    Unknown: IUnknown;
  118.    {$ENDIF}
  119.    {$IFDEF DELPHI6}
  120.    RealDesigner: IDesigner;
  121.    {$ENDIF}
  122. begin
  123.    Result := 0;
  124.    try
  125.       Msg := Pointer(LParam);
  126.       if (Msg^.message = WM_PAINT) and not MMDesign.Dragging then
  127.       begin
  128.          WndDesigner := FindDesignerForWindow(Msg^.HWND);
  129.          if (WndDesigner <> nil) and WndDesigner.Visible then
  130.          begin
  131.             if Adjusting and not PaintOK then RedrawTrack(False);
  132.             PaintOk := True;
  133.          end;
  134.       end;
  135.       if (Msg^.message = WM_RBUTTONDOWN) and not MMDesign.Dragging and not Deconnect then
  136.       begin
  137.          if Adjusting then
  138.          begin
  139.             Msg^.HWND := 0;
  140.          end
  141.          else
  142.          begin
  143.             WndDesigner := FindDesignerForWindow(Msg^.HWND);
  144.             if (WndDesigner <> nil) and WndDesigner.Visible then
  145.             with WndDesigner, ParentForm do
  146.             begin
  147.                DragSource := nil;
  148.                DragDest := nil;
  149.                Pt := SmallPointToPoint(TSmallPoint(Msg^.Lparam));
  150.                Target := FindTarget(ParentForm, Msg^.HWND, Pt, TargetType, Rect);
  151.                if Target <> nil then
  152.                begin
  153.                   if TargetType = ptOutput then
  154.                      Deconnect := RemoveOutput(Target)
  155.                   else
  156.                      Deconnect := RemoveInput(Target);
  157.                   Msg^.HWND   := 0;
  158.                   if Deconnect then
  159.                   begin
  160.                      PaintOK := True;
  161.                      DrawPaintBox;
  162.                      BeepSound(MB_ICONHAND);
  163.                      if (Designer <> nil) then
  164.                          Designer.Modified;
  165.                   end;
  166.                end;
  167.             end;
  168.          end;
  169.       end;
  170.       if (Msg^.message = WM_RBUTTONUP) then
  171.       begin
  172.          if Deconnect and not MMDesign.Dragging or Adjusting then
  173.          begin
  174.             Msg^.HWND := 0;
  175.             Deconnect := False;
  176.          end;
  177.       end;
  178.       if (Msg^.message = WM_LBUTTONDOWN) and not MMDesign.Dragging then
  179.       begin
  180.          if Adjusting then
  181.          with DragDesigner do
  182.          begin
  183.             DoneDragging;
  184.             BeepSound(MB_OK);
  185.             Pt := SmallPointToPoint(TSmallPoint(Msg^.Lparam));
  186.             MapWindowPoints(Msg^.HWND,ParentForm.Handle,pt,1);
  187.             RunTimeHeight := pt.Y;
  188.             DragDesigner := nil;
  189.             ClipCursor(nil);
  190.             Msg^.HWND := 0;
  191.          end
  192.          else
  193.          begin
  194.             WndDesigner := FindDesignerForWindow(Msg^.HWND);
  195.             if (WndDesigner <> nil) and WndDesigner.Visible then
  196.             with WndDesigner,ParentForm do
  197.             begin
  198.                DragSource:= nil;
  199.                DragDest := nil;
  200.                Pt := SmallPointToPoint(TSmallPoint(Msg^.Lparam));
  201.                Target := FindTarget(ParentForm, Msg^.HWND, Pt, TargetType, Rect);
  202.                if Target <> nil then
  203.                begin
  204.                   Msg^.HWND := 0;
  205.                   DragDesigner    := WndDesigner;
  206.                   DragInput       := TargetType = ptInput;
  207.                   DragSource      := Target;
  208.                   OffsetRect(Rect, Griff div 2, Griff div 2);
  209.                   DragOrigin      := Rect.TopLeft;
  210.                   DragPoint       := DragOrigin;
  211.                   Rect            := ParentForm.ClientRect;
  212.                   MapWindowPoints(ParentForm.Handle,0,Rect,2);
  213.                   ClipCursor(@Rect);
  214.                   {$IFDEF WIN32}
  215.                   {$IFDEF DELPHI6}
  216.                   if (Designer.QueryInterface(IDesigner,RealDesigner) = S_OK) then
  217.                   begin
  218.                      RealDesigner.SelectComponent(nil);
  219.                   {$ELSE}
  220.                   {$IFDEF DELPHI4}
  221.                   if Designer.QueryInterface(IFormDesigner, Unknown) = S_OK then
  222.                   begin
  223.                      IFormDesigner(Designer).SelectComponent(nil);
  224.                   {$ELSE}
  225.                   if (Designer is TFormDesigner) then
  226.                   begin
  227.                      TFormDesigner(Designer).SelectComponent(nil);
  228.                   {$ENDIF}
  229.                   {$ENDIF}
  230.                   {$ELSE}
  231.                   begin
  232.                      {CompLib.GetActiveForm.SetSelection(FParentForm.Name);}
  233.                   {$ENDIF}
  234.                       PaintOK := True;
  235.                       DrawPaintBox;
  236.                       BeepSound(MB_OK);
  237.                   end;
  238.                   MMDesign.Dragging := True;
  239.                end;
  240.             end;
  241.          end;
  242.       end;
  243.       if (Msg^.message = WM_LBUTTONUP) and MMDesign.Dragging then
  244.       begin
  245.          DoneDragging;
  246.          if (DragSource <> nil) then
  247.          begin
  248.             if (DragDest <> nil) and (DragSource <> DragDest) then
  249.             begin
  250.                 if DragInput then
  251.                    DragDesigner.Connect(DragDest,DragSource)
  252.                 else
  253.                    DragDesigner.Connect(DragSource,DragDest);
  254.                 PaintOK := True;
  255.                 DragDesigner.DrawPaintBox;
  256.                 DragDesigner.BeepSound(MB_OK);
  257.                 if (DragDesigner.ParentForm.Designer <> nil) then
  258.                    DragDesigner.ParentForm.Designer.Modified;
  259.             end
  260.             else
  261.                 DragDesigner.BeepSound(MB_ICONHAND);
  262.          end;
  263.          Msg^.HWND := 0;
  264.       end;
  265.       if (Msg^.message = WM_MOUSEMOVE) then
  266.       begin
  267.          if Adjusting then
  268.          with DragDesigner.ParentForm do
  269.          begin
  270.             if not PaintOK then
  271.             begin
  272.                RedrawTrack(False);
  273.                Pt := SmallPointToPoint(TSmallPoint(Msg^.Lparam));
  274.                MapWindowPoints(Msg^.HWND,Handle,Pt,1);
  275.                DragPoint := Pt;
  276.                RedrawTrack(True);
  277.             end;
  278.             Msg^.HWND := 0;
  279.          end
  280.          else if MMDesign.Dragging then
  281.          with DragDesigner.ParentForm do
  282.          begin
  283.             Pt := SmallPointToPoint(TSmallPoint(Msg^.Lparam));
  284.             MapWindowPoints(Msg^.HWND,Handle,Pt,1);
  285.             if (DragDest = nil) or not PtInRect(DragRect, Pt) then
  286.             begin
  287.                DragDest := nil;
  288.                RedrawTrack(False);
  289.                MapWindowPoints(Handle,Msg^.HWND,Pt,1);
  290.                Target := DragDesigner.FindTarget(DragDesigner.ParentForm, Msg^.HWND, Pt, TargetType, Rect);
  291.                DragPoint := Pt;
  292.                RedrawTrack(True);
  293.                if Target <> nil then
  294.                begin
  295.                   if (DragInput and (TargetType = ptOutput) and DragDesigner.CanConnect(Target,DragSource)) or
  296.                      (not DragInput and (TargetType = ptInput) and DragDesigner.CanConnect(DragSource,Target)) then
  297.                   begin
  298.                      DragDesigner.BeepSound(MB_OK);
  299.                      DragDest := Target;
  300.                      DragRect := Rect;
  301.                      InflateRect(DragRect, Griff, Griff);
  302.                      OffsetRect(Rect, Griff div 2, Griff div 2);
  303.                      RedrawTrack(False);
  304.                      DragPoint := Rect.TopLeft;
  305.                      RedrawTrack(True);
  306.                      DragDesigner.BeepSound(MB_OK);
  307.                   end;
  308.                end;
  309.                Canvas.Pen.Mode := pmCopy;
  310.             end;
  311.             Msg^.HWND := 0;
  312.          end;
  313.       end;
  314.       if (Result = 0) then
  315.          Result := CallNextHookEx(GetMsgHook, Code, WParam, LParam);
  316.    except
  317.       Application.HandleException(nil);
  318.    end;
  319. end;
  320. {------------------------------------------------------------------------}
  321. procedure AddDesigner(Designer: TMMDesigner);
  322. begin
  323.    inc(CreateCount);
  324.    if (CreateCount = 1) then
  325.    begin
  326.       ControlList := TList.Create;
  327.       { install Windows-Message-Hook }
  328.       {$IFDEF WIN32}
  329.       GetMsgHook    := SetWindowsHookEx(WH_GETMESSAGE, @GetMsgProc, 0, GetCurrentThreadID);
  330.       {$ELSE}
  331.       GetMsgHook    := SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, GetInstanceModule(HInstance), GetCurrentTask);
  332.       {$ENDIF}
  333.       { load Bitmap for Caption Button }
  334.       DesignBitmap := LoadBitmap(HInstance,'BTN_DESIGNER');
  335.       GetBitmapSize(DesignBitmap, BitmapWidth, BitmapHeight);
  336.    end;
  337.    ControlList.Add(Designer);
  338. end;
  339. {------------------------------------------------------------------------}
  340. procedure RemoveDesigner(Designer: TMMDesigner);
  341. begin
  342.    ControlList.Remove(Designer);
  343.    ControlList.Pack;
  344.    dec(CreateCount);
  345.    if (CreateCount = 0) then
  346.    begin
  347.       if GetMsgHook <> 0 then UnhookWindowsHookEx(GetMsgHook);
  348.       ControlList.Free;
  349.       ControlList := nil;
  350.       DeleteObject(DesignBitmap);
  351.       DesignBitmap := 0;
  352.    end;
  353. end;
  354. {== TMMDesignerEditor =========================================================}
  355. function TMMDesignerEditor.GetVerbCount: integer;
  356. begin
  357.    GetVerbCount := 1;
  358. end;
  359. {-- TMMDesignerEditor ---------------------------------------------------------}
  360. function TMMDesignerEditor.GetVerb(Index: integer): string;
  361. begin
  362.    GetVerb := '&Update Connections';
  363. end;
  364. {-- TMMDesignerEditor ---------------------------------------------------------}
  365. procedure TMMDesignerEditor.ExecuteVerb(Index: integer);
  366. begin
  367.    if (Component is TMMDesigner) then
  368.       (Component as TMMDesigner).Update := True;
  369. end;
  370. {-- TMMDesignerEditor ---------------------------------------------------------}
  371. procedure TMMDesignerEditor.Edit;
  372. begin
  373.    if (Component is TMMDesigner) then
  374.    begin
  375.       if (Component as TMMDesigner).Active then
  376.          (Component as TMMDesigner).Active := False
  377.       else
  378.          (Component as TMMDesigner).Active := True;
  379.    end;
  380.    if (Designer <> nil) then Designer.Modified;
  381. end;
  382. initialization
  383.    // we need to avoid references from the designtime to the runtime code, so if
  384.    // we are in designmode we supply the functions needed to do the trick....
  385.    // cant believe what a shit the Borland guys did in Delphi 6....
  386.    _FindDesignerForWindow := FindDesignerForWindow;
  387.    _AddDesigner           := AddDesigner;
  388.    _RemoveDesigner        := RemoveDesigner;
  389.    _RedrawTrack           := RedrawTrack;
  390. finalization
  391. end.