0

In short, I need to base some window behavior on the type of object a control is dropped on, after being dragged. This is all well and good as long as the target control at the destination is a column, but not if it is any other object.

Assume I have a datawindow with two columns, and a rectangle. Let's call them c_1, c_2, and r_1, respectively.

I drag c_1 and drop it on c_2:

dwo.name = c_2
dwo.type = column

This is fine, and exactly the behavior I expect.

I drag c_1 and drop it on r_1:

dwo.name = datawindow
dwo.type = datawindow

A reference to the datawindow itself is returned. This is too broad to use as a basis for building anything meaningful, at least in my case.

In testing, it seems that I can't make dragdrop return a reference to the control at the drop location unless it is a column. Is this intended, or is something going wrong in my environment? How can I work around this if I need to base window behavior on the value of dwo.type or dwo.name?

Trashface
  • 27
  • 4

2 Answers2

1

Use the function GetObjectAtPointer

It will allow you to know exactly what object the user dropped something onto.

It returns a string of the form objectname~trow that you have to parse to identify what you need.

  • This did it. I've been cooking my brain so hard trying to figure out this weird dragdrop event behavior that I never even thought to check for a datawindow method that essentially does the same thing. I guess I just assumed it wouldn't work? Anyway, thanks. – Trashface Mar 11 '19 at 17:57
0

One approach would be to check the X and Y coordinates of the pointer against the array of controls within the datawindow.

Within an event on the datawindow you could get the list of objects like this:

is_selected_controls = is_null //both of these are string arrays
ls_objects = this.Describe( 'DataWindow.Objects')
ls_objects = ls_objects + '~t'
ll_pos = pos(ls_objects, '~t')
ll_orig_pos = 1

Then loop through the array and get each controls X, W, Width, Height

DO WHILE ll_pos > 0
    ls_object = mid(ls_objects, ll_orig_pos, ll_pos -ll_orig_pos)
    IF describe(ls_object + '.type') = 'line' THEN
        ls_x = this.Describe(ls_object + '.X1')
        ls_y = this.Describe(ls_object + '.Y1')
        ls_h = this.Describe(ls_object + '.Y2')
        ls_w = this.Describe(ls_object + '.X2')

    ELSE
        ls_x = this.Describe(ls_object + '.X')
        ls_y = this.Describe(ls_object + '.Y')
        ls_h = this.Describe(ls_object + '.height')
        ls_w = this.Describe(ls_object + '.width')
    END IF
    // compare the X,Y of the pointer to control position to see if it's
    // on the control, if it is exit the loop and do whatever...

    ll_orig_pos = ll_pos + 1
    ll_pos = pos(ls_objects, '~t', ll_orig_pos)
LOOP
Matt Balent
  • 2,337
  • 2
  • 20
  • 23
  • This would be a perfectly sensible approach for a normal datawindow whose control positions are difficult to determine using standard techniques. I probably should have mentioned that the datawindow in question is a house of cards that requires very gentle handling. Comparing coordinates actually works here in many cases, but is hilariously broken in others. It makes sense, but it doesn't quite work for me. Thanks anyway. – Trashface Mar 11 '19 at 18:32