Drag & drop folder

Post Reply
User avatar
Otto
Posts: 4470
Joined: Fri Oct 07, 2005 7:07 pm
Contact:

Drag & drop folder

Post by Otto »

Why does oFld:bDropOver return a different value for nCol if you drop on the same point depending from nLeft of the object (here from xBrowse) you drag from?
How could I find out on what folder you drop?

oFld:bDropOver = { |uDropInfo,nRow,nCol,nKeyFlags| msginfo(nCol) }

oxBrwFolio1:nLeft := 0
Image
oxBrwFolio1:nLeft := 10

Image
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Otto,

This is a working sample that shows the right way to do it:

Code: Select all

#include "FiveWin.ch"

//----------------------------------------------------------------------------//

function Main()

   local oDlg, oFld
   LOCAL oBrw1
   LOCAL oBrw2
   local oCursor


   DEFINE CURSOR oCursor HAND

   USE customer New

   DEFINE DIALOG oDlg TITLE "FiveWin Dynamic folders" ;
      FROM 5, 5 TO 40, 150

   @ 0.5, 10 FOLDER oFld PROMPT "&xBase", "&And OOP", "&Power" ;
      OF oDlg SIZE 160, 90

        @ 1, 1 LISTBOX oBrw1 FIELDs  (field->first) ;
            HEADERS "Name"  ;
            FIELDSIZES 140                                           ;
            SIZE       140, 60  ;
  OF oFld:aDialogs[ 1 ]


        @ 1, 10 LISTBOX oBrw2 FIELDs  (field->first) ;
            HEADERS "Name"  ;
            FIELDSIZES 140                                           ;
            SIZE       140, 60  ;
  OF oFld:aDialogs[ 2 ]

oBrw1:oDragCursor  := oCursor
oBrw2:oDragCursor  := oCursor


   oFld:bDropOver = { | uDropInfo, nRow, nCol, nKeyFlags | ShowPos( nRow, nCol, oFld ) }

   ACTIVATE DIALOG oDlg CENTERED

return nil

//----------------------------------------------------------------------------//

function ShowPos( nRow, nCol, oFld )

   local aPoint
   
   if nRow > 32000
      nRow = - ( 65535 - nRow )
   endif    

   if nCol > 32000
      nCol = - ( 65535 - nCol )
   endif    
   
   aPoint = { nRow, nCol }
   
   aPoint = ClientToScreen( GetFocus(), aPoint )
   ScreenToClient( oFld:hWnd, aPoint )
   
   MsgInfo( "Row: " + Str( aPoint[ 1 ] ) + ", Col: " + Str( aPoint[ 2 ] ) )
   
return nil   

//----------------------------------------------------------------------------//
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Otto
Posts: 4470
Joined: Fri Oct 07, 2005 7:07 pm
Contact:

Post by Otto »

Hello Antonio,
could you please show the right way how to detect the drop folder?

I tried with this function but I always get different results depending on the length of the folder caption.
Regards,
Otto

while nCol > (nPos + (nTabSize := GetTextWidth( 0, Right(oFld:aPrompts[n],len(oFld:aPrompts[n])-1), oFld:oFont) + iif(n=1,5,5)) ) .and. n < Len(oFld:aPrompts)
nPos += nTabSize
n++
end




*******************Test.prg

#include "FiveWin.ch"

//----------------------------------------------------------------------------//

function Main()

local oDlg, oFld
LOCAL oBrw1
LOCAL oBrw2
local oCursor


DEFINE CURSOR oCursor HAND

USE fivetest New

DEFINE DIALOG oDlg TITLE "FiveWin Dynamic folders" ;
FROM 5, 5 TO 40, 150

@ 0.5, 10 FOLDER oFld PROMPT "&xBase Test drag position how to find", "&And OOP", "&Power" ;
OF oDlg SIZE 160, 90

@ 1, 1 LISTBOX oBrw1 FIELDs (fivetest->first) ;
HEADERS "Name" ;
FIELDSIZES 140 ;
SIZE 140, 60 ;
OF oFld:aDialogs[ 1 ]


@ 1, 10 LISTBOX oBrw2 FIELDs (fivetest->first) ;
HEADERS "Name" ;
FIELDSIZES 140 ;
SIZE 140, 60 ;
OF oFld:aDialogs[ 2 ]

oBrw1:oDragCursor := oCursor
oBrw2:oDragCursor := oCursor

oFld:bDropOver = { |uDropInfo,nRow,nCol,nKeyFlags|ShowPos( nRow, nCol, oFld ) }

ACTIVATE DIALOG oDlg CENTERED

return nil

//----------------------------------------------------------------------------//


func ShowPos( nRow, nCol, oFld )
local nFolioNo
local cChk, n, cOrgChk
local nAmt
LOCAL cBezeichnung := ""
local nSatzNr := recno()
local aPoint

nFolioNo := oFld:nOption
cOrgChk := str(oFld:nOption)
cChk := ''



if nRow > 32000
nRow = - ( 65535 - nRow )
endif

if nCol > 32000
nCol = - ( 65535 - nCol )
endif

aPoint = { nRow, nCol }

aPoint = ClientToScreen( GetFocus(), aPoint )
ScreenToClient( oFld:hWnd, aPoint )


cChk := str(TabChk( aPoint[ 2 ],oFld ),1)

return

*---------------------*
Function TabChk( nCol,oFld )
local n := 1, nPos := 0
local nTabSize := 0

while nCol > (nPos + (nTabSize := GetTextWidth( 0, Right(oFld:aPrompts[n],len(oFld:aPrompts[n])-1), oFld:oFont) + iif(n=1,5,5)) ) .and. n < Len(oFld:aPrompts)

msginfo(str(nCol)+ " " +str(n) +" "+oFld:aPrompts[n] + str(GetTextWidth( 0, Right(oFld:aPrompts[n],len(oFld:aPrompts[n])-1), oFld:oFont))+" - "+str(nPos) )


nPos += nTabSize
n++
end
msginfo("Drop to "+oFld:aPrompts[n])
return n
************************************************************
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Otto,

This one seems good enough:

Code: Select all

Function TabChk( nCol, oFld ) 
   
   local n := 1, nPos := 0 

   while nPos < nCol .and. n <= Len( oFld:aPrompts )
      nPos += GetTextWidth( 0, oFld:aPrompts[ n++ ], oFld:oFont:hFont ) + 5
   end
   
   msginfo( "Drop to " + oFld:aPrompts[--n]) 

return n 
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Otto
Posts: 4470
Joined: Fri Oct 07, 2005 7:07 pm
Contact:

Post by Otto »

Hello Antonio,
thank you very much for your help. Now I get the right folder.
Regards,
Otto
User avatar
Otto
Posts: 4470
Joined: Fri Oct 07, 2005 7:07 pm
Contact:

Post by Otto »

Antonio, if you change the folder caption to

@ 0.5, 10 FOLDER oFld PROMPT "Hotel","Kasse","Telefon","Diverse","frei" ;
OF oDlg SIZE 160, 90
then you get wrong folders back.
Regards,
Otto




#include "FiveWin.ch"

//----------------------------------------------------------------------------//

function Main()

local oDlg, oFld
LOCAL oBrw1
LOCAL oBrw2
local oCursor


DEFINE CURSOR oCursor HAND

USE fivetest New

DEFINE DIALOG oDlg TITLE "FiveWin Dynamic folders" ;
FROM 5, 5 TO 40, 150

@ 0.5, 10 FOLDER oFld PROMPT "Hotel","Kasse","Telefon","Diverse","frei" ;
OF oDlg SIZE 160, 90


@ 1, 1 LISTBOX oBrw1 FIELDs (fivetest->first) ;
HEADERS "Name" ;
FIELDSIZES 140 ;
SIZE 140, 60 ;
OF oFld:aDialogs[ 1 ]


@ 1, 10 LISTBOX oBrw2 FIELDs (fivetest->first) ;
HEADERS "Name" ;
FIELDSIZES 140 ;
SIZE 140, 60 ;
OF oFld:aDialogs[ 2 ]

oBrw1:oDragCursor := oCursor
oBrw2:oDragCursor := oCursor

oFld:bDropOver = { |uDropInfo,nRow,nCol,nKeyFlags|ShowPos( nRow, nCol, oFld ) }

ACTIVATE DIALOG oDlg CENTERED

return nil

//----------------------------------------------------------------------------//


func ShowPos( nRow, nCol, oFld )
local nFolioNo
local cChk, n, cOrgChk
local nAmt
LOCAL cBezeichnung := ""
local nSatzNr := recno()
local aPoint

nFolioNo := oFld:nOption
cOrgChk := str(oFld:nOption)
cChk := ''



if nRow > 32000
nRow = - ( 65535 - nRow )
endif

if nCol > 32000
nCol = - ( 65535 - nCol )
endif

aPoint = { nRow, nCol }

aPoint = ClientToScreen( GetFocus(), aPoint )
ScreenToClient( oFld:hWnd, aPoint )


cChk := str(TabChk( aPoint[ 2 ],oFld ),1)

return

************************************************************
Function TabChk( nCol, oFld )

local n := 1, nPos := 0

while nPos < nCol .and. n <= Len( oFld:aPrompts )
nPos += GetTextWidth( 0, oFld:aPrompts[ n++ ], oFld:oFont:hFont ) + 5
end

msginfo( "Drop to " + oFld:aPrompts[--n])

return n
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Otto,

Try with different values instead of + 5 in TabChk()
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Otto
Posts: 4470
Joined: Fri Oct 07, 2005 7:07 pm
Contact:

Post by Otto »

Thank you Antonio,
I can hardcode the values. But this syntax is not dbase-like.
Regards,
Otto
User avatar
Otto
Posts: 4470
Joined: Fri Oct 07, 2005 7:07 pm
Contact:

Post by Otto »

Antonio, I can’t belief that you find with
GetTextWidth( 0, oFld:aPrompts[ 1 ], oFld:oFont:hFont )
the right folder.

Regards,
Otto
nCol values is the borderline between folders
Image
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Otto,

Please notice that when you use short prompts, Windows keep using a min width for the prompts, so you have to modify it to use a Max() value.

Similar to this:

Code: Select all

Function TabChk( nCol, oFld ) 

   local n := 1, nPos := 0 

   while nPos < nCol .and. n <= Len( oFld:aPrompts ) 
      nPos += Max( GetTextWidth( 0, oFld:aPrompts[ n++ ], oFld:oFont:hFont ), <try some values here> ) + 5 
   end 

msginfo( "Drop to " + oFld:aPrompts[--n]) 

return n
Anyhow, let me tell you that this is the first time that I see such desired behavior in Windows. I guess that no other software uses what you are trying to implement
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Otto
Posts: 4470
Joined: Fri Oct 07, 2005 7:07 pm
Contact:

Post by Otto »

What about
n = TabCtrl_HitTest( oFld:hWnd ) + 1

Regards,

Otto
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Otto,

Yes! very good solution! :-) I forgot it,

Is it working fine ?
regards, saludos

Antonio Linares
www.fivetechsoft.com
Post Reply