I am trying to use the nRow, nCol parameters of bDropOver block when drop occurs on a window.
Naturally I expected that the nRow,nCol refer to the destination window. It is not the case. I found that they are not even Screen Coordinates. On studying the Control.Prg, I observed that the nRow, nCol refer to the position with respect to originating control ( i.e, the Control where the drag began ).
The relevant code from Control.Prg is extracted below:
- Code: Select all Expand view
METHOD LButtonUp( nRow, nCol, nKeyFlags ) CLASS TControl
local aPoint := { nRow, nCol }
::lMouseDown = .f.
if lDragging
lDragging = .f.
ReleaseCapture()
aPoint = ClientToScreen( ::hWnd, aPoint )
if aPoint[ 1 ] > 32768
aPoint[ 1 ] -= 65535
endif
if aPoint[ 2 ] > 32768
aPoint[ 2 ] -= 65535
endif
SendMessage( WindowFromPoint( aPoint[ 2 ], aPoint[ 1 ] ),;
FM_DROPOVER, nKeyFlags, nMakeLong( nRow, nCol ) )
return nil
endif
The destination (dropped) window can not use these nRow,nCol coordinates directly. We have to know the originating window ( the bdropdown does not contain the information, unless we stuff it in the udropinfo). So we have to ascertain the originating window, conver the coordinates to screen from orginating window and then convert again from screen to the destination window.
Kindly confirm if my understanding is correct.
I checked the drag drop programs in the samples folder. They do not contain any sample using the nRow,nCol coordnates in the bDropOver block.
I suggest it would be convenient for us, if the bDropOver is called with nRow,nCol relative to the destination window ( or at least the screen coordinates).
I suggest the following modified code.
- Code: Select all Expand view
METHOD LButtonUp( nRow, nCol, nKeyFlags ) CLASS TControl
local aPoint := { nRow, nCol }
local hDropWnd
::lMouseDown = .f.
if lDragging
lDragging = .f.
ReleaseCapture()
aPoint = ClientToScreen( ::hWnd, aPoint )
if aPoint[ 1 ] > 32768
aPoint[ 1 ] -= 65535
endif
if aPoint[ 2 ] > 32768
aPoint[ 2 ] -= 65535
endif
hDropWnd = WindowFromPoint( aPoint[ 2 ], aPoint[ 1 ] )
aPoint = ScreenToClient( hDropWnd, aPoint )
// do we need to make again any correction for 65535 here also ?
SendMessage( hDropWnd, FM_DROPOVER, nKeyFlags, nMakeLong( aPoint[ 1 ], aPoint[ 2 ] ) )
return nil
endif
With this correction I expect when the drop occurs, the nRow, nCol parameters that the window receives on evaluation of bDropOver block are relative to itself and can straight away use the coordinates.
Is my understanding right ?
With this modification, dropover function can be written something like this
- Code: Select all Expand view
oWnd:bDropOver := { |u,r,c,f| mousedropover( u,r,c,f ) }
//---
func mousedropover( u, nRow, nCol, nFlags )
oWnd:Say ( nRow, nCol, 'Dropped here' )
/*
INSTEAD OF :
LOCAL aPoint
aPoint := ClientToScreen( OrginatingWnd:hWnd, { nRow, nCol } )
// apply 65535 correction
aPoint := ScreenToClient( oThisWnd:hWnd, aPoint )
// i don't know if we again have to apply 65535 correction and if so what it is
nRow := aPoint[ 1 ]
nCol := aPoint[ 2 ]
// now use nRow,nCol
*/
Do other programmers agree with the suggestion?
Request Mr Antonio and other colleagues to advise.