Drag and drop a text field to notepad

Hi all, I want to be able to take data from normal text fields of an edit form and drop it into notepad or any other Windows application.

For example: drag the contents of “Company Name” field (data is “Acme Widgets”) and drop it into notepad so that it displays “Acme Widgets” in notepad. I don’t want to use copy and paste if I can help it.

Where do I start?

Hi Don,

Maybe take a look at: Devuna OLE Drag and Drop

Hope it can help you

Regards
Johan de klerk

2 Likes

Many thanks. It looks promising. It refers to some OLE Tutorials on http://www.catch22.net/tuts/win32/drag-and-drop-introduction which I will read before trying the code.

1 Like

Hello,
Curious! Did you manage with Devuna?

I haven’t started using it yet. Still got to get a few puzzle pieces in place. I will report back once I have got to the point of using it.

I was quite impressed with it.
I could even select (ctrl-a) the body of an opened outlook email and drag it to a text box - viola!
Drag & drop files via windows explorer working well also!
So dragging into a Clarion app works well. Hope you find something to drag out of clarion to others…

1 Like

The RTL supports Dropping text onto Clarion controls using DropID(‘~TEXT’) and files with ~FILE:

    TEXT,AT(12,82,223,49),USE(Txt),VSCROLL,DROPID('~TEXT')
    ENTRY(@s255),AT(12,135,223),USE(Ent),DROPID('~TEXT','~FILE')

CASE FIELD()
OF ?Txt
   CASE EVENT()
   OF EVENT:Drop ; Txt=DropID() ; DISPLAY
   END 
OF ?Ent
   CASE EVENT()
   OF EVENT:Drop ; Ent=DropID() ; DISPLAY
   END 
END
2 Likes

Hi,
Using C* ABC,
My problem is that I cannot get the DROPPED embed to fire for any control. I get the + sign to be able to drop, but none of the embeds will fire to accept the drop!
Ron

Hi,
Using C8 ABC.
Ron

I know the code works. Have you tried pasting the below ENTRY into a Window and being sure the EVENT:Drop code is as shown? Be sure the code matches exactly. I think the ~FILE must be UPPER Case.

Make sure the Entry is not on a Tab or in a Group to start. Maybe create a new very basic window with nothing else on it to test it.

Ent  STRING(260)   !put this in Data

ENTRY(@s255),AT(12,135,223),USE(Ent),DROPID('~TEXT','~FILE')

CASE FIELD()
OF ?Ent
   CASE EVENT()
   OF EVENT:Drop 
         Ent=DropID() 
          DISPLAY
          Message('Event Drop ENT = ' & DropID() )
   END 
END

HI Carl,
I took the IMDD example that ships with C8. Plain Vanilla with only the IMDD extension. I created a new window with a string Entry field and the DropID. I get the + when I drop over the entry field but the embeds do not trigger!

THisstring STRING(240) !
QuickWindow WINDOW(‘Window’),AT(,260,235),FONT(‘Microsoft Sans Serif’,8,FONT:regular,CHARSET:DEFAULT), |
RESIZE,CENTER,GRAY,HLP(‘new_window’)
BUTTON(’&OK’),AT(100,180,49,14),USE(?Ok),LEFT,ICON(‘WAOK.ICO’),FLAT,MSG(‘Accept operation’), |
TIP(‘Accept Operation’)
BUTTON(’&Cancel’),AT(162,180,49,14),USE(?Cancel),LEFT,ICON(‘WACANCEL.ICO’),FLAT,MSG(‘Cancel Operation’), |
TIP(‘Cancel Operation’)
BUTTON(’&Help’),AT(209,180,49,14),USE(?Help),LEFT,ICON(‘WAHELP.ICO’),FLAT,MSG(‘See Help Window’), |
STD(STD:Help),TIP(‘See Help Window’)
PROMPT(‘TH isstring:’),AT(64,129),USE(?THisstring:Prompt)
ENTRY(@s240),AT(114,128,60,10),USE(THisstring),DROPID(’~FILE’,’~TEXT’)
END

ThisWindow CLASS(WindowManager)
Init PROCEDURE(),BYTE,PROC,DERIVED
Kill PROCEDURE(),BYTE,PROC,DERIVED
TakeFieldEvent PROCEDURE(),BYTE,PROC,DERIVED
END


ThisWindow.TakeFieldEvent PROCEDURE

ReturnValue BYTE,AUTO

Looped BYTE
CODE
LOOP ! This method receives all field specific events
IF Looped
RETURN Level:Notify
ELSE
Looped = 1
END
ReturnValue = PARENT.TakeFieldEvent()
CASE FIELD()
OF ?THisstring
CASE EVENT()
OF EVENT:Drop
THisstring=DropID()
DISPLAY
Message('Event Drop ENT = ’ & DropID() )
END
END
RETURN ReturnValue
END
ReturnValue = Level:Fatal
RETURN ReturnValue

Plain and simple - but just does not trigger the embed code!
Ron

I recall that C9 Drop was broken for Controls but worked on the WINDOW.

I checked some old C9 code and it had DROP(’~FILE’) on the Window. It also had it on SHEET so that may also work.

So with DROP(’~FILE’) on the Window you’ll get a Window Event:Drop. If you have more than one control you wish to drop on you’ll need to check FOCUS().

Using the attached DROP example project I tested it in 9.1 and Every Control worked plus the Window. I don’t have 8 or 9 running.

DropTest.zip (1.4 KB)

Here’s the Source. To test use the attachment.

DropTest  PROCEDURE    
Txt STRING(500)
Ent STRING(260)

Window WINDOW('Drop Test - Window has DROP(~FILE)'),AT(,,229,187),CENTER,GRAY,SYSTEM, |
            FONT('Segoe UI',9),DROPID('~FILE'),RESIZE
        STRING('Version'),AT(2,2),USE(?ClaVersion)
        ENTRY(@s255),AT(2,15,223),USE(Ent),TIP('ENTRY with Drop ~FILE'), |
                DROPID('~FILE')
        TEXT,AT(2,31,223,49),USE(Txt),VSCROLL,TIP('TEXT with Drop ~FILE'), |
                DROPID('~FILE','~TEXT')
        PROMPT('Drop Window appears here'),AT(3,140,221,31),USE(?DropWindow)
        SHEET,AT(2,84,223,50),USE(?SHEET1),DROPID('~FILE')
            TAB('Drop ~FILE'),USE(?TAB1),TIP('SHEET with Drop ~FILE')
                PROMPT('Drop Sheet appears here'),AT(7,102,211,25),USE(?DropSheet)
            END
        END
    END

    code
    OPEN(window)
    ?ClaVersion{PROP:text}='Clarion Library Version: ' & system{PROP:LibVersion,2} &'.'& system{PROP:LibVersion,3}
    accept
        case event()
        end
        case accepted()
        end

        CASE FIELD()
        OF 0                !Window No Control 
           CASE EVENT()
           OF EVENT:Drop ; ?DropWindow{PROP:Text}='Drop Window:' & FORMAT(CLOCK(),@t6) & |
                           '<13,10>' & DropID() ; DISPLAY
           END 

        OF ?Txt
           CASE EVENT()
           OF EVENT:Drop ; Txt='Drop Text:' & FORMAT(CLOCK(),@t6) & |
                           '<13,10>' & DropID() ; DISPLAY
           END 
        OF ?Ent
           CASE EVENT()
           OF EVENT:Drop ; Ent=DropID() ; DISPLAY
           END 

        OF ?SHEET1
           CASE EVENT()
           OF EVENT:Drop ; ?DropSheet{PROP:Text}='Drop Sheet:' & FORMAT(CLOCK(),@t6) & |
                           '<13,10>' & DropID() ; DISPLAY
           END 

        END     
    end !Accept

Example posted in Comp.Lang.Clarion by Koen Tjoa that tests fine in 9.1:

  !Drop Example posted by  Koen Tjoa  in Comp.lang.clarion 
  PROGRAM
  MAP
  END
Txt                 STRING(1000)
Ent                 STRING(250)
RegionString        STRING(255)
Window WINDOW('Test drag and drop'),AT(,,455,191),CENTER,GRAY,SYSTEM, |
            FONT('Segoe UI',9)
        TEXT,AT(10,14,436,66),USE(Txt),VSCROLL,DROPID('~TEXT')
        PROMPT('Ent:'),AT(12,87),USE(?Ent:Prompt)
        ENTRY(@s250),AT(28,87,418,10),USE(Ent),DROPID('~TEXT','~FILE')
        REGION,AT(10,110,114,72),USE(?DropRegion),COLOR(COLOR:Black), |
                DROPID('~TEXT','~FILE')
    END
  CODE
  OPEN(Window)   
  0{PROP:text}=0{PROP:text}&' - Library Version: ' & system{PROP:LibVersion,2} &'.'& system{PROP:LibVersion,3}
  SETTARGET(window)
  ACCEPT
    CASE EVENT()
    OF EVENT:Drop
      CASE FIELD()
      OF ?Txt     ; Txt=DropID() ; DISPLAY
      OF ?Ent     ; Ent=DropID() ; DISPLAY
      OF ?DropRegion
        RegionString=DropID()
        MESSAGE(RegionString)
      END 
    END
  END
  CLOSE(Window)
1 Like

@CarlBarnes Do you know how to get the position on the text control where the drop occurs? I want to be able to add the dragged text to the text control where it was dropped.

I don’t know of a way.

Clarion TEXT is a Windows EDIT Control so I would look at the API and Messages that offers. I see EM_CHARFROMPOS that looks promising to translate Mouse X/Y to Character.

Quick search shows you don’t have to subclass, you can SendMessage() like:

!turn Mouse X/Y into Point ... relative to text control?
TextIndex = SendMessage(?Text{PROP:Handle}, EM_CHARFROMPOS, 0, MousePoint)

Some VB.net code I found that calls the API to get Text pos on a drop

Function TextBoxCursorPos converts the mouse’s coordinates from screen coordinates to the TextBox’s coordinate system (both are in pixels). It then sends the EM_CHARFROMPOS message to the TextBox to get the position within the TextBox corresponding to the mouse’s position. sends the Text

Private Const EM_CHARFROMPOS As Int32 = &HD7
Private Structure POINTAPI
    Public X As Integer
    Public Y As Integer
End Structure

Private Declare Function SendMessageLong Lib "user32" Alias "SendMessageA" _
     (ByVal hWnd As IntPtr, ByVal wMsg As Int32, _
      ByVal wParam As Int32, ByVal lParam As Int32) As Long

' Return the character position under the mouse.
Public Function TextBoxCursorPos(ByVal txt As TextBox, _
                ByVal X As Single, ByVal Y As Single) As Long
    ' Convert screen coordinates into control coordinates.
    Dim pt As Point = TextBox1.PointToClient(New Point(X,Y))

    ' Get the character number
    TextBoxCursorPos = SendMessageLong(txt.Handle, _
        EM_CHARFROMPOS, 0&, CLng(pt.X + pt.Y * &H10000)) And &HFFFF&
End Function
1 Like