DragDrop of Files

Discussion in 'Questions (Windows Mobile)' started by Zenerdiode, May 25, 2015.

  1. Zenerdiode

    Zenerdiode Active Member Licensed User

    I'd like to implement Drag & Drop of files from Explorer to a Multiline TextBox on my form. The DragDrop Event should then fire to grab the FilePath of the file dropped and open it.

    But I'm falling at the first hurdle. I'm getting an error of 'The given key was not present in the dictionary'. This is caused by the DragDrop key. Other TextBox event types work fine in there, such as Click.

    Many Thanks.
     

    Attached Files:

  2. Cableguy

    Cableguy Expert Licensed User

    According to the error message, the method or event is not implemented in the view you are using it with
     
  3. Zenerdiode

    Zenerdiode Active Member Licensed User

    Hello Paulo,

    Long time since I was last here; good to hear from you. I'm puzzled, as the TextBox does support Drag & Drop, I'm just wondering if the Basic4PPC TextBox is a modified control by Erel - and not a native one.
     
  4. Cableguy

    Cableguy Expert Licensed User

    Long time no read!

    I believe you are correct about it being a downsized control... I would suggest either trying using the door lib or, since DLL creating is quite easy with c# and sharp develop, create your own custom control.
     
  5. agraham

    agraham Expert Licensed User

    I don't know why you are getting an error as your code is actually correct. The Basic4ppc TextBox is a standard TextBox and will work as such. In your code the Enter event is being fired but the problem is that you need to tell the souce of the drag that you can accept the data. This is done by examining the Data property of the DragEventArgs to see if it is the type of data that you can accept and if so set the Effect property of DragEventArgs with one or more DragDropEffect flags that the drag source will accept. In this case DragDropEffects.Copy should work. Only if you do this will the cursor change and the Drop event be fired. This should all be possible using Door library Objects but it is non-trivial as Drag and Drop is based on the Clipboard data formats which in turn is based on COM and not .NET so it can seem a bit convoluted in the .NET world.

    Unfortunately I don't have any code already written for this so you will need to read up on Drag and Drop and do some experimenting.
     
    Erel and Cableguy like this.
  6. Cableguy

    Cableguy Expert Licensed User

  7. agraham

    agraham Expert Licensed User

    This works for me but I am using my own Reflection library that is a superset of DoorEx but I think it will work with the Door or DoorEx libraries.

    I haven't posted it as a project as version 6.90 of Basic4ppc would not load it (my personal version is up to 8.00 now! :)) but it should paste into your existing project but will need an ObjectArray or ObjectArrayEx object added.

    There is no data format checking done here as I kept it as simple as possible so you may get odd errors if you drag odd things into the TextBox

    Code:
    Sub Globals
        
    'Declare the global variables here.
        Dim DataFormats(0) AsString
    End Sub

    Sub App_Start
       Obj1.New1
       Obj1.FromControl(
    "TextBox1")
       Obj1.SetProperty(
    "AllowDrop","True")
       Enter.New1(Obj1.Value,
    "DragEnter")
       Drop.New1(Obj1.Value,
    "DragDrop")
       Form1.Show
    End Sub

    Sub Enter_NewEvent
       Obj1.Value = Enter.Data
       Obj1.Value = Obj1.GetProperty(
    "Data")
       
    ' this block of code might work (or not) for you in the IDE but won't compile
       ' DataFormats() = Obj1.RunMethod("GetFormats") ' COM not .NET names of formats
       ' For i = 0 To ArrayLen(DataFormats()) -1
       ' msg = msg & DataFormats(i) & CRLF
       ' Next
       ' Msgbox(msg, ArrayLen(DataFormats()))
       Obj1.Value = Enter.Data
       Obj1.SetProperty(
    "Effect""Copy" )
    End Sub

    Sub Drop_NewEvent
       Obj1.Value = Drop.Data
       Obj1.Value = Obj1.GetProperty(
    "Data")
       ObjArray1.New1(
    0)
       ObjArray1.Value = Obj1.RunMethod2(
    "GetData""FileNameW""System.String")
       data = ObjArray1.Get(
    0)
       
    Msgbox(data)
    End Sub
     
  8. agraham

    agraham Expert Licensed User

    I've installed 6.90 and see the "key not present error". This is because the Door library can only handle a few types of EventHandler.

    In this archive is a 6.90 project using my Reflection library which will cope with any type of EventHandler. Drag and Drop will only work when compiled under 6.90. For some reason the Enter_NewEvent event is not raised in the 6.90 IDE whereas it is in my version of the IDE. I can't remember what I changed that might cause this.
     

    Attached Files:

  9. agraham

    agraham Expert Licensed User

    I missed an obvious bit of checking if something that does not resolve to a valid filename is dropped
    Code:
    If IsNull(ObjArray1.Value) Then
            data = 
    "Invalid filename"
    Else
            data = ObjArray1.Get(
    0)
    End If
     
  10. agraham

    agraham Expert Licensed User

    I now know why the code above doesn't work in the IDE. The property setting in my new Reflection library is not compatible with 6.90. I'll post the reason and a workaround if there is any interest?
     
  11. Zenerdiode

    Zenerdiode Active Member Licensed User

    Most definitely! Thank you for your time Andrew.

    Christopher
     
  12. agraham

    agraham Expert Licensed User

    Basic4ppc, including 6.90, could not pass internal data to a library method with an Object type parameter. It was because of this that the Door and DoorEx libraries had two variants of, say SetProperty, one taking a String as the value parameter and the other taking an Object. The first was used to set data from within Basic4ppc and the other to set "real" Objects from an external library.

    I have changed my own version of Basic4ppc to be able to pass to internal data as String types to Object parameters which let me rewrite the DoorEx library as my new Reflection library and remove the String based duplicated methods. However this means that your Basic4ppc cannot use SetProperty in this library as (despite what the Reflection help might still say) it takes Object type parameters, as do the RunMethod variants.

    The workaround is to use Object.ValueAsString to set the Value of a Reflection Object to the required value as a string and then pass that Value as the value parameter of a Reflection library method. This works for numbers, strings, Booleans and enum names.

    So for your drag and drop this doesn't work passing a String to an Object parameter from inside Basic4pp with the Reflection library.
    Code:
    Obj1.New1
        Obj1.FromControl(
    "TextBox1")
        Obj1.SetProperty(
    "AllowDrop","True")
    Using an intermediate Object does work as the String being passed to an Object parameter is now from outside Basic4ppc which does work.
    Code:
    Obj1.New1
        Obj1.FromControl(
    "TextBox1")
        Obj2.New1
        Obj2.ValueAsString = 
    "True"
        Obj1.SetProperty(
    "AllowDrop",Obj2.Value)
    Attached is a 6.90 project that should work in the IDE as well as when compiled.
     

    Attached Files:

  13. Zenerdiode

    Zenerdiode Active Member Licensed User

    Thank You very much indeed Andrew, does exactly what I want and need. I didn't have a copy of your Reflecton library; but I see you've kindly included one.

    Best-
    Christopher
     
  14. agraham

    agraham Expert Licensed User

    By using "FileDrop" instead of "FileNameW" you can accept a selection of more than one file.
    Code:
    Sub Drop_NewEvent
        Obj1.Value = Drop.Data
        Obj1.Value = Obj1.GetProperty(
    "Data")
        ObjArray1.New1(
    0)
        Obj2.New1
        Obj2.ValueAsString = 
    "FileDrop"   
    ErrorLabel(Error)
        ObjArray1.Value = Obj1.RunMethod2(
    "GetData", Obj2.Value, "System.String")
        Obj1.Value = ObjArray1.Value
        l = Obj1.GetProperty(
    "Length")
        
    For i = 0 To l - 1
            data = data & ObjArray1.Get(i) & 
    CRLF
        
    Next
        TextBox1.Text = data
        
    Return
    Error:
        
    Msgbox("Invalid filename")
    End Sub
     
  15. Zenerdiode

    Zenerdiode Active Member Licensed User

    You're now answering questions before I've even asked:)
    I was wondering about multiple files, together with how to get the size of the ObjectArray with there being no 'ObjArray.Arraylen' property.

    I did try to read up on the subject before posing my question in the first place, but I'm still learning every day. My inspiration was from here:

    https://msdn.microsoft.com/en-us/library/aa289508(v=vs.71).aspx

     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice