[vwnc] Drag & Drop

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

[vwnc] Drag & Drop

Steffen Märcker
Hi,

I want to drag a file (from e.g. Windows Explorer) onto my application window in order to get it's path. Is that possible or does Sam Shuster's negative statement on this hold still true? If possible, how? I've configuered the dragDrop messages in my application class but they are never called.

Greetings, Steffen

__________________________________________________________________________
Verschicken Sie SMS direkt vom Postfach aus - in alle deutschen und viele
ausländische Netze zum gleichen Preis!
https://produkte.web.de/webde_sms/sms




_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] Drag & Drop

James Robertson-7
There's an example of doing this for the old File Browser that should  
be something you could move forward.  We are working on 64 bit, yes

James Robertson
Cincom Smalltalk Product Evangelist
http://www.cincomsmalltalk.com/blog/blogView
Talk Small and Carry a Big Class Library




On May 5, 2009, at 4:44 AM, Steffen Märcker wrote:

> Hi,
>
> I want to drag a file (from e.g. Windows Explorer) onto my  
> application window in order to get it's path. Is that possible or  
> does Sam Shuster's negative statement on this hold still true? If  
> possible, how? I've configuered the dragDrop messages in my  
> application class but they are never called.
>
> Greetings, Steffen
>
> __________________________________________________________________________
> Verschicken Sie SMS direkt vom Postfach aus - in alle deutschen und  
> viele
> ausländische Netze zum gleichen Preis!
> https://produkte.web.de/webde_sms/sms
>
>
>
>
> _______________________________________________
> vwnc mailing list
> [hidden email]
> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>


_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] Drag & Drop

Paul-404
In reply to this post by Steffen Märcker
Hi Steffen,

It is easy when you tell Windows that you're interested in this event.
The following code is a bit of a hack and can be improved a lot. It
probably works only on 32-bit windows as well.
Please let me know if you find a better solution.

Paul Weustink


I assume that you derived a class from ApplicationModel, add these
methods there:

registerExplorerDragDrop
    "are we alive?"
    | aHandle anInterface aBlock |
    (self builder isNil or: [self builder window isNil]) ifTrue: [^self].

    "get the window handle"
    aHandle := self builder window windowHandle.
    aHandle isNil ifTrue: [^self].

    "get the shell interface of the explorer"
    anInterface := WinInterface new.

    "tell the explorer that we support this"
    anInterface DragAcceptFiles: aHandle with: 1.

    "and tell my window that I will do something with the unknown events"
    aBlock := [:anEvent | self unknownEvent: anEvent].
    self builder window unknownEventBlock: aBlock.

unregisterExplorerDragDrop
    | aHandle anInterface |

    "are we alive?"
    (self builder isNil or: [self builder window isNil]) ifTrue: [^self].

    "get the window handle"
    aHandle := self builder window windowHandle.
    aHandle isNil ifTrue: [^self].

    "get the shell interface of the explorer"
    anInterface := WinInterface new.

    "tell the explorer that we're no longer interested in this"
    anInterface DragAcceptFiles: aHandle with: 0.

    "and tell my window that to skip the unknown events"
    self builder window unknownEventBlock: nil.

Do the register and deregister for instance in your postOpen: and
closeRequest methods.
The unknownEventBlock is stored in an added instance variable to
ApplicationWindow and is called from the handler in ApplicationWindow:

unknownEvent: anEvent

    unknownEventBlock isNil
        ifTrue:
            [super unknownEvent: anEvent.
            self reportWindowEvent: #eventUnknown with: anEvent.
            ^nil].
    unknownEventBlock value: anEvent.
    ^self

This could be improved a lot by using the reportWindowEvent mechanism,
instead of overriding existing methods like I did, since overriding is
never a good idea. The following method is then called in your application:

unknownEvent: anEvent
    "called from the ApplicationWindow (on request)"

    | aHostEvent aMessage |

    "get the data of the unknown event"
    aHostEvent := anEvent at: 10.

    "translate this data into somethng usefull specific for Windows
platform"
    "aKind := aHostEvent longAt: 1."
    "aWindowHandle := aHostEvent longAt: 5."
    aMessage := aHostEvent longAt: 9.
    "aWParam := aHostEvent longAt: 13."
    "aLParam := aHostEvent unsignedLongAt: 17."

    "see C:\Program Files\Microsoft Visual Studio\VC98\Include\WINUSER.H
     for the values of the messages that you might be interested in"

    "Explorer drag-drop?                 #define WM_DROPFILES   0x0233"
    (aMessage = 16r0233) ifTrue: [^self wmDropFilesEvent: anEvent].

And finally the message is dispatched here:

wmDropFilesEvent: anEvent
    "called from the ApplicationWindow (on request)"

    | aHostEvent aKind aMessage aWParam aLParam aWindowHandle
aDropHandle anInterface anAmount aBuffer aCollection |

    "get the data of the unknown event"
    aHostEvent := anEvent at: 10.

    "translate this data into something usefull specific for Windows
platform"
    aKind := aHostEvent longAt: 1.
    aWindowHandle := aHostEvent longAt: 5.
    aMessage := aHostEvent longAt: 9.
    aWParam := aHostEvent longAt: 13.
    aLParam := aHostEvent unsignedLongAt: 17.

    "see C:\Program Files\Microsoft Visual Studio\VC98\Include\WINUSER.H
     for the values of the messages that you might be interested in"

    "Explorer drag-drop                 #define WM_DROPFILES   0x0233"

        "bingo, the drop handle to use is the WParam field"
        aDropHandle := aWParam.
       
        "get the amount of files that are dropped"
        anInterface := WinInterface new.
        anAmount := anInterface DragQueryFile: aDropHandle with: -1
with: nil with:0.

        "allocate some buffer to store the string in (check the size)"
        aBuffer := (ByteString new: 16384) copyToHeap.

        "for all the files that we have"
        aCollection := OrderedCollection new.
        1 to: anAmount do: [:anIndex |
            "get the name of the dropped file"
            anInterface DragQueryFile: aDropHandle with: (anIndex - 1)
with: aBuffer with: 16384.

            "and remember it"
            aCollection addLast: (aBuffer copyCStringFromHeap).
        ].

        "deallocate the buffer"
        aBuffer free.

        "finish the drop"
        anInterface DragFinish: aDropHandle.  

        "return and use the collection"
        aCollection isEmpty ifFalse: [self loadFile: aCollection first].
        ^self.

> Hi,
>
> I want to drag a file (from e.g. Windows Explorer) onto my application window in order to get it's path. Is that possible or does Sam Shuster's negative statement on this hold still true? If possible, how? I've configuered the dragDrop messages in my application class but they are never called.
>
> Greetings, Steffen

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc