dragdrop UserControl

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Kate

    dragdrop UserControl

    Hi:

    I have a form with a picture box and some command buttons to make
    certain shapes appear in the picture box. The shapes are drawn on
    blank UserControls added like this:

    'at top of form module
    Dim WithEvents tc As testControl

    'button1_click (for example)
    Set tc = Controls.Add("t estproj.testCon trol", "tc[index]",
    Form1.Picture1)

    (then shapes are drawn on the control and it's added to a collection
    of like shapes)


    My idea was to have these UserControls store internally some data that
    would enable them to interact, most importantly to implement dragdrop
    operations so that one control dragged over a "hot spot" in another
    control would site itself at that spot, after some validation.

    Here's where I'm stuck: I've found example after example explaining
    how to convert a point on one object to a point in its container, but
    none of them have worked so far. I'm wondering if this is a result of
    creating the UserControls at run-time? Specifically, here is what I
    would like to happen, but can't pull it off:

    When the shapes are drawn on the control, certain points are captured
    as hot spots and stored in a read-only array. These coordinates remain
    in the control's own scale and are not converted.

    When one control is dropped onto another, the dragdrop event fires,
    and I can confirm the source is at a point inside the target control.
    I want to compare this point to the internally stored points of target
    and select the closest hot point. Then I need to convert that hot
    point to the picture1 coordinates and move the source control there.

    This seems like it should be a piece of cake, but it's been driving me
    crazy for almost a day now. Any help would be appreciated, thanks in
    advance.
  • J French

    #2
    Re: dragdrop UserControl

    On 9 Nov 2003 16:54:23 -0800, kate@curio.com (Kate) wrote:
    [color=blue]
    >Hi:
    >
    >I have a form with a picture box and some command buttons to make
    >certain shapes appear in the picture box. The shapes are drawn on
    >blank UserControls added like this:
    >
    >'at top of form module
    >Dim WithEvents tc As testControl
    >
    >'button1_cli ck (for example)
    >Set tc = Controls.Add("t estproj.testCon trol", "tc[index]",
    >Form1.Picture1 )
    >
    >(then shapes are drawn on the control and it's added to a collection
    >of like shapes)
    >
    >
    >My idea was to have these UserControls store internally some data that
    >would enable them to interact, most importantly to implement dragdrop
    >operations so that one control dragged over a "hot spot" in another
    >control would site itself at that spot, after some validation.
    >
    >Here's where I'm stuck: I've found example after example explaining
    >how to convert a point on one object to a point in its container, but
    >none of them have worked so far. I'm wondering if this is a result of
    >creating the UserControls at run-time?[/color]

    Definitely not - not a chance
    [color=blue]
    >Specifically , here is what I
    >would like to happen, but can't pull it off:
    >
    >When the shapes are drawn on the control, certain points are captured
    >as hot spots and stored in a read-only array. These coordinates remain
    >in the control's own scale and are not converted.[/color]
    Ok, so you have an array of points in the ClientArea[color=blue]
    >
    >When one control is dropped onto another, the dragdrop event fires,
    >and I can confirm the source is at a point inside the target control.[/color]
    because you have the X and Y coordinates ...[color=blue]
    >I want to compare this point to the internally stored points of target
    >and select the closest hot point. Then I need to convert that hot
    >point to the picture1 coordinates and move the source control there.[/color]
    So you have points stored INSIDE a usercontrol, that you wish to
    convert into points inside its parent - the Picturebox

    Have you looked at the Extender properties of a Usercontrol ?

    eg: UserControl.Ext ender.Left[color=blue]
    >
    >This seems like it should be a piece of cake, but it's been driving me
    >crazy for almost a day now. Any help would be appreciated, thanks in
    >advance.[/color]
    I'm not totally sure what you are up to ...

    Another thing that could help is the ClientToScreen API
    - and the ScreenToClient API


    Comment

    • Kate

      #3
      Re: dragdrop UserControl

      erewhon@nowhere .com (J French) wrote in message news:<3faf5e6e. 350837760@news. btclick.com>...[color=blue]
      > On 9 Nov 2003 16:54:23 -0800, kate@curio.com (Kate) wrote:
      >[color=green]
      > >Here's where I'm stuck: I've found example after example explaining
      > >how to convert a point on one object to a point in its container, but
      > >none of them have worked so far. I'm wondering if this is a result of
      > >creating the UserControls at run-time?[/color]
      >
      > Definitely not - not a chance
      >[color=green]
      > >Specifically , here is what I
      > >would like to happen, but can't pull it off:
      > >[/color]
      > Have you looked at the Extender properties of a Usercontrol ?
      > eg: UserControl.Ext ender.Left[/color]
      A bit..I know I want most of the code eventually inside the
      UserControl module, but an early roadblock was that I cannot get the
      dragdrop event inside the UserControl to fire--only the dragdrop event
      of the run-time instance (and isn't it the Extender that provides
      this...?) And as long as I'm stuck for the moment using the available
      event, I want to at least figure out how to position a control where I
      want it inside the picture control:

      //pt is a POINTAPI, initially contains one of the hotspots inside
      UserControl tc
      pt.X = ScaleX(pt.X, vbTwips, vbPixels)
      pt.Y = ScaleY(pt.Y, vbTwips, vbPixels)

      //get the screen position of this point
      ClientToScreen tc.GetHWnd, pt

      //move the dragdrop source to the desired point on the target
      Source.Move pt.X * Screen.TwipsPer PixelX - Picture1.Left, pt.Y * _
      Screen.TwipsPer PixelY - Picture1.Top

      Source just disappears, somewhere outside the picture box boundaries.

      Comment

      • J French

        #4
        Re: dragdrop UserControl

        On 10 Nov 2003 06:26:48 -0800, kate@curio.com (Kate) wrote:

        <snip>[color=blue][color=green]
        >> Have you looked at the Extender properties of a Usercontrol ?
        >> eg: UserControl.Ext ender.Left[/color]
        >A bit..I know I want most of the code eventually inside the
        >UserControl module, but an early roadblock was that I cannot get the
        >dragdrop event inside the UserControl to fire--only the dragdrop event
        >of the run-time instance[/color]
        I do not understand
        - what is a run-time instance ?
        .... you cannot have tried to 'fake' the recipient of an event (?)[color=blue]
        >(and isn't it the Extender that provides
        >this...?)[/color]
        No, the Extender knows about its environment
        - that is subtly different from what I think you are talking about[color=blue]
        > And as long as I'm stuck for the moment using the available
        >event, I want to at least figure out how to position a control where I
        >want it inside the picture control:
        >
        >//pt is a POINTAPI, initially contains one of the hotspots inside
        >UserControl tc
        >pt.X = ScaleX(pt.X, vbTwips, vbPixels)
        >pt.Y = ScaleY(pt.Y, vbTwips, vbPixels)
        >
        >//get the screen position of this point
        >ClientToScre en tc.GetHWnd, pt
        >
        >//move the dragdrop source to the desired point on the target
        >Source.Move pt.X * Screen.TwipsPer PixelX - Picture1.Left, pt.Y * _
        >Screen.TwipsPe rPixelY - Picture1.Top
        >
        >Source just disappears, somewhere outside the picture box boundaries.[/color]

        Probably because it is way outside the boundaries

        Why not just trace where it is ?

        Comment

        • Kate

          #5
          Re: dragdrop UserControl

          erewhon@nowhere .com (J French) wrote in message news:<3fafaae0. 370411559@news. btclick.com>...[color=blue]
          > On 10 Nov 2003 06:26:48 -0800, kate@curio.com (Kate) wrote:
          >
          > <snip>[color=green][color=darkred]
          > >> Have you looked at the Extender properties of a Usercontrol ?
          > >> eg: UserControl.Ext ender.Left[/color]
          > >A bit..I know I want most of the code eventually inside the
          > >UserControl module, but an early roadblock was that I cannot get the
          > >dragdrop event inside the UserControl to fire--only the dragdrop event
          > >of the run-time instance[/color]
          > I do not understand
          > - what is a run-time instance ?
          > ... you cannot have tried to 'fake' the recipient of an event (?)[/color]
          Well, it's like this. I was working through the tutorial on creating
          activeX control and want to see if control will support what I want to
          do (create blank controls at runtime, draw on them as user dictates,
          and allow user to site controls by dragging and dropping them). So I
          have a control project and a test project to work with the control.

          In the test project, events like click, mousedown, mouseup don't
          appear in the pull-down procedure list unless I raise them in the
          control project, but dragdrop appears automatically, and this is the
          only dragdrop event that responds to my code (e.g., I deleted all
          dragdrop code in the test project and put msgbox in control project
          dragdrop--nothing happens when I drop onto an instance of my control
          in this case. If I put the msgbox back into test project dragdrop, I
          get the message.)

          [color=blue][color=green]
          > >(and isn't it the Extender that provides
          > >this...?)[/color]
          > No, the Extender knows about its environment
          > - that is subtly different from what I think you are talking about[/color]
          Just received my book on COM/ActiveX, maybe that will clear things up.
          Thanks--

          Comment

          • Steve Gerrard

            #6
            Re: dragdrop UserControl


            "Kate" <kate@curio.com > wrote in message
            news:2cb4c040.0 311101043.63853 d95@posting.goo gle.com...[color=blue]
            > erewhon@nowhere .com (J French) wrote in message[/color]
            news:<3fafaae0. 370411559@news. btclick.com>...[color=blue][color=green]
            > > On 10 Nov 2003 06:26:48 -0800, kate@curio.com (Kate) wrote:
            > >
            > > <snip>[/color]
            >
            > In the test project, events like click, mousedown, mouseup don't
            > appear in the pull-down procedure list unless I raise them in the
            > control project, but dragdrop appears automatically, and this is the
            > only dragdrop event that responds to my code (e.g., I deleted all
            > dragdrop code in the test project and put msgbox in control project
            > dragdrop--nothing happens when I drop onto an instance of my control
            > in this case. If I put the msgbox back into test project dragdrop, I
            > get the message.)
            >
            >[/color]
            I found the same result. The DragDrop event does not seem to fire inside the
            UserControl code module - presumably it is preset to just raise the event
            instead. However, the OleDragDrop event will fire there. If you change your test
            project to use the Ole DragDrop events instead, you can probably make it work.


            Comment

            • Steve Gerrard

              #7
              Re: dragdrop UserControl


              "Kate" <kate@curio.com > wrote in message
              news:2cb4c040.0 311100626.76bf0 7ac@posting.goo gle.com...[color=blue]
              > erewhon@nowhere .com (J French) wrote in message[/color]
              news:<3faf5e6e. 350837760@news. btclick.com>...[color=blue][color=green]
              > > On 9 Nov 2003 16:54:23 -0800, kate@curio.com (Kate) wrote:
              > >[/color]
              >
              > //pt is a POINTAPI, initially contains one of the hotspots inside
              > UserControl tc
              > pt.X = ScaleX(pt.X, vbTwips, vbPixels)
              > pt.Y = ScaleY(pt.Y, vbTwips, vbPixels)
              >
              > //get the screen position of this point
              > ClientToScreen tc.GetHWnd, pt
              >
              > //move the dragdrop source to the desired point on the target
              > Source.Move pt.X * Screen.TwipsPer PixelX - Picture1.Left, pt.Y * _
              > Screen.TwipsPer PixelY - Picture1.Top
              >[/color]

              I think you should try
              Source.Move pt.X, pt.Y

              without any scaling. You are 1) converting X to pixels, 2) converting it to
              screen position, 3) converting pixels back to Twips, and 4) offsetting that
              amount not from the left edge of the screen, but from the left edge of Picture1.
              You could similarly convert Picture1.Left to screen twips, and then offset from
              that instead, but I think all the conversions cancel each other. You wind up the
              original Pt.X twips from Picture1.Left.



              Comment

              • J French

                #8
                Re: dragdrop UserControl

                On 10 Nov 2003 10:43:39 -0800, kate@curio.com (Kate) wrote:
                [color=blue]
                >erewhon@nowher e.com (J French) wrote in message news:<3fafaae0. 370411559@news. btclick.com>...[color=green]
                >> On 10 Nov 2003 06:26:48 -0800, kate@curio.com (Kate) wrote:
                >>[/color][/color]
                <snip>[color=blue]
                >In the test project, events like click, mousedown, mouseup don't
                >appear in the pull-down procedure list unless I raise them in the
                >control project, but dragdrop appears automatically, and this is the
                >only dragdrop event that responds to my code (e.g., I deleted all
                >dragdrop code in the test project and put msgbox in control project
                >dragdrop--nothing happens when I drop onto an instance of my control
                >in this case. If I put the msgbox back into test project dragdrop, I
                >get the message.)[/color]

                Here is an alternative :-

                Option Explicit

                ' Add a Textbox
                ' Move Form or Textbox on MouseDown & Drag

                Private Declare Function ReleaseCapture _
                Lib "user32" () As Long
                Private Declare Function SendMessage _
                Lib "user32" _
                Alias "SendMessag eA" _
                (ByVal hwnd As Long, _
                ByVal wMsg As Long, _
                ByVal wParam As Long, _
                ByVal lParam As Any) As Integer
                Const WM_NCLBUTTONDOW N = &HA1
                Const HTCAPTION = 2

                Public Sub MoveObject(hwnd As Long)
                ReleaseCapture
                SendMessage hwnd, WM_NCLBUTTONDOW N, HTCAPTION, 0&
                End Sub

                Private Sub Form_MouseDown( Button As Integer, _
                Shift As Integer, _
                X As Single, _
                Y As Single)
                MoveObject Me.hwnd
                End Sub


                Private Sub Text1_MouseDown (Button As Integer, _
                Shift As Integer, _
                X As Single, _
                Y As Single)
                MoveObject Text1.hwnd
                End Sub

                Comment

                Working...