Drop file name to a specific row in the List

LOL, you beat me to it!

NOTE: If you’re doing a GET(Q,Pointer), you need to make sure you do something like:

GET(Q,0 + ?YourList{PROPList:MouseUpRow}) or
GET(Q,INT(?YourList{PROPList:MouseUpRow}))

Otherwise, your GET() could give you unexpected results

1 Like

Hi,
Thank you all for your reply.
Sorry I could not explain my case properly.
I already almost reached what I need but I had one problem which I will try to explain this way:
I have this code below; I drag the file name and release the left button over the required record, the issue that I have to press a left click after releasing the mouse button to complete the action. what I need is to complete the action when I release the button instantly.

here the code:

! LOCAL DATA
QQ Queue,PRE(QQ)
F1 CSTRING(30)
END
!---------------------------------------
! WINDOW
Window WINDOW(‘Window’),AT(,150,223),FONT(‘MS Sans Serif’,8,FONT:regular,CHARSET:ANSI),CENTER,SYSTEM
LIST,AT(4,12,140,190),USE(?List),ALRT(MouseLeft),FROM(QQ),DROPID(’~FILE’)
END
!---------------------------------------
! OPEN WINDOW
LOOP I# = 1 TO 100
QQ:F1 = 'RECORD NUMBER ’ & I#
ADD(QQ)
END
display
!---------------------------------------
! LIST ALERT KEY

R#= ?List{PROPList:MouseDownRow}
get(QQ,R#)

STOP(DROPID() & ‘<13>’ & QQ:F1)
!---------------------------------------

Regards

  1. ALRT on the LIST control is not required for drag-n-drop
  2. You use PROPLIST:MouseDownRow instead of correct PROPLIST:MouseUpRow

Sorry but I tested all the scenarios and the attached pdf has the results. the only test which is returning the correct selection is PROPLIST:MouseDownRow and alert key which require left mouse click. may I ask you to create test the sample I send to see if you get a different result.

Thank you.

drop event.pdf (93.4 KB)

The problem is that the list doesn’t follow the mouse pointer selecting rows when droping on the list, on approach could be to calculate with MOUSEY()

Here is an example based on yours one:

  PROGRAM
                    MAP
                    END
! LOCAL DATA
QQ Queue,PRE(QQ)
F1 CSTRING(30)
END
!---------------------------------------
! WINDOW
Window WINDOW('Window'),AT(,150,223),FONT('MS Sans Serif',8,FONT:regular,CHARSET:ANSI),CENTER,SYSTEM
 LIST,AT(4,12,140,190),USE(?List),FROM(QQ),DROPID('~FILE')
        END
    CODE
        open(Window)
!---------------------------------------
! OPEN WINDOW
 LOOP I# = 1 TO 100

       QQ:F1 = 'RECORD NUMBER ' & I#
  ADD(QQ)
 END
 display
!---------------------------------------
! LIST ALERT KEY
        ACCEPT
            CASE EVENT()
            OF EVENT:DROP
!   R#= ?List{PROPList:MousedOWNRow}
!   get(QQ,R#)
!
!                STOP(DRAGID() & '<13>' & DROPID() & '<13>' & QQ:F1)
                R# = ?LIST{PROP:YORIGIN} + (MOUSEY() - ?LIST{PROP:YPOS}) / ?LIST{PROP:LINEHEIGHT}
!                get(QQ,R#)
!                MESSAGE('DRAGID():'                   & DRAGID() & |
!                    '|DROPID():'                      & DROPID() & | 
!                    '|?List{{PROPList:MouseDownRow}:' & ?List{PROPList:MouseDownRow} & |
!                    '|?List{{PROPList:MouseUpRow}:'   & ?List{PROPList:MouseUpRow} & |
!                    '|CHOICE(?LIST):'                 & CHOICE(?LIST)  & |
!                    '|MOUSEY():'                      & MOUSEY() & |
!                    '|?LIST{{PROP:YPOS}:'             & ?LIST{PROP:YPOS} & |
!                    '|?LIST{{PROP:HEIGHT}:'           & ?LIST{PROP:HEIGHT} & |
!                    '|?LIST{{PROP:LINEHEIGHT}:'       & ?LIST{PROP:LINEHEIGHT} & |
!                    '|?LIST{{PROP:YORIGIN}:'          & ?LIST{PROP:YORIGIN} & |
!                    '|?LIST{{PROP:ITEMS}:'            & ?LIST{PROP:ITEMS} & |
!                    '|?LIST{{PROP:LINECOUNT}:'        & ?LIST{PROP:LINECOUNT}& |
!                    '|?LIST{{PROP:VSCROLLPOS}:'       & ?LIST{PROP:VSCROLLPOS}& |
!                    '|CALCULATED ROW:'                & R# & ' ' & QQ:F1)
                
                SELECT(?LIST,R#)
            END
        END

But you would need to test it in C6 and in different combinations of windows/MDI/TOOLBARs/Docked windows/windows partial off-screen/Multi-monitors/etc

2 Likes

it working so nicely.

thanks a lot and best regards

Also, it’s need to take into account value returned by ?List{PROP:YOrigin} property - 1-based index of the first visible row in the list content source.

There is a problem with the value returned by PROPLIST:MouseUpRow on dropping because the mouse is captured by the program where you’re dragging files from. It’s possible to use PROPLIST:MouseMoveRow property instead. This property will return the row where the mouse movement has been detected before dropping. Though mouse is captured by another program, windows under mouse pointer receive messages which goal is to determine a possible drop target. The RTL updates last known mouse pointer position inside the LIST control on processing these messages.

You are welcome, I’m glad it helped.

Likewise, be alert in case there is another solution without performing the calculations and that does not require further testing.

Yes the PROP:YORIGIN is 1 based, but there is no need to substract 1 in that example as the other part of the calculation is zero based: (MOUSEY-YPOS)/LINEHEIGHT as the fraction part is dropped on the integer variable.

Good find. Although it doesn’t work very well, I mean, trying with that same example but considering PROPLIST:MouseMoveRow, if you drag with a certain speed and drop on the list, many times it doesn’t update its value, if instead, before releasing the click, you moves on the row a little or stay longer, it does update. Perhaps it can be made more precise, by adjusting the RTL or setting some Windows parameter.

It reminds me of a conversation a few years ago on the newsgroup about setting the mouse wheel to follow the window it’s positioned on or the window with focus using SPI_SETMOUSEWHEELROUTING, perhaps one of the other parameters can help improve its accuracy:

PROPLIST:MouseMoveRow works for me with any speed of the mouse movement before drop. And I do not se the difference with the row calculated from the MOUSEY() value.
test.clw (1.9 KB)

Hi, here it doesn’t work most of the times, tested in C10 and C11.0 on W11, build on Debug and Release configuration. Can somebody else test this example too? What else could be in play to behave differently?

Sk2107, even using MOUSEY, you may want to look at the example, it adds other steps to enforce good calculation, using APIs, considering the listbox header size (on the previous example it didn’t have a header), considering if the calculated value fall off the list items (although I think YORIGIN could be added too), other consideration could be if the Queue has less rows than the listbox (row1<=RECORDS(Q) (or ?L{PROP:LineCount}).

Steps I performed

1 opened test.clw in notepad
2 opened Clarion Ide and started a new Win32 exe project
3 overwrote default clw content with the content of test.clw opened in step 1 (with copy/paste)
4 compiled and ran
5 took the test app window to the right and a Windows Explorer window to the left
6 dragged several times individual files to specific rows of the list in the test app with different speeds, with these results:
1st time dropped on 7th row: row1 = 17 row2 = 7
2nd time dropped on 22nd row: row1 = 14 row2 = 22
3rd time dropped on 10th row: row1 = 22 row2 = 10
(and so several times with similar results)

I use PropList:MouseMoveRow for my logic to determine the row the drop occurs on. Don’t forget that value will be 0 if dropped on the header or -1 if dropped below the last row in the list.

I cannot get that property to return the correct row in WIN11, the same .exe (and clarun.dll) on WINXP it does.

If this is so, the OLE-based implementation of drag-n-drop (see OLE-based drag-n-drop in Windows 11 is broken. If a Clarion control or window has the DROPID attribute with a signature beginning with ~, the Clarion RTL creates for this control or window an object implementing the IDropTarget interface described in Windows documentation and calls the RegisterDragDrop API function to bind the object and control/window. On dragging Windows must check whether something under mouse pointer has association with the IDropTarget object. If yes, methods of this interface are invoking. Particularly, IDropTarget::DragEnter is invoking when mouse crosses the control/window bound, IDropTarget::DragOver is invoking while mouse is moving inside control/window client area, etc.

Implementation of the IDropTarget interface created by the RTL notifies the control/window it is bound to about events corresponding to invoked methods and passes the mouse position passed to these methods. This allows, if the drop target is LIST, to set row, column and zone values for moving mouse. OLE must call IDropTarget::DragOver every time the position of the mouse pointer inside the target’s client area changed.

It’s not working on my Win11 either.

But if I change the GET(Q, row1) to GET(Q, row2) on line 82, it seems to work every time.

I think, PROPLIST:MouseMoveRow can work on Windows 11 too if to update mouse position in IDropTarget::Drop before performing drop actions. Somebody could point RZ to this thread.

1 Like

I can record a PTSS report attaching your example clw and pointing here.

Thanks Jeff for testing and confirming the behavior seen. I tested on a W11 21H2 and a Win10 21H2 x64 and it failed too, while on a Win10 PE x64 and a WinXP 32 it worked.

Edit. PTSS 43357