Drag n' drop without maxgui

Started by fielder, December 25, 2019, 10:54:00

Previous topic - Next topic

fielder

10 years ago i write a small application for Blitzmax (without maxgui) that was just an empty window...
when dragged a file in to the window, the application can get the path of the file.

i searched all my codes... year for year and i can't find anything like that...

any idea on how to build this? (probably i used appargs... but re-trying now i can't do nothing with drag n drop)

thank you to everyone can help me and merry christmas!

Scaremonger

Appargs might work if you are dropping files onto a desktop icon because they would be passed on launch. I seem to remember you need a registry key to enable it.

If you are dropping into an open application without maxgui, then you were probably hooking into the windows API and registering the Blitzmax window as a drop target using DragAcceptFiles(). After calling this,  you need to hook into the windows message queue to get the WM_DROPFILES event.

You could probably look through the maxgui source for these functions to see how it is done there, but if not you could take a look on MSN:

https://docs.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-dragacceptfiles
https://docs.microsoft.com/en-us/windows/win32/shell/wm-dropfiles


fielder

#2
ok!, thank you, this mean that i need to open a MaxGui window... if i want to be sure that sources are linux/macos compatible.

Hardcoal

This works for me

Const GWL_WNDPROC:Int = -4

Global OldWindowFunc:Int

Global ThisWinAddress:Int
Global ReadDraggedURl_Flg
Global DraggedURL:String

Extern "Win32"
Function SetWindowLong:Int(HWND:Int,nIndex:Int,dwNewLong:Int) = "SetWindowLongA@12"
Function GetWindowLong:Int(HWND:Int,nIndex:Int) = "GetWindowLongA@8"
Function CallWindowProc:Int( prevwndproc:Int, hwnd:Int, DbgMsg:Int, wparam:Int, lparam:Int) = "CallWindowProcA@20"
Function DragAcceptFiles:Int( hwnd:Int, enable:Int)
Function DragQueryFile:Int( hdrop:Int, index:Int, buf:Byte Ptr, sz:Int)
EndExtern

Function SetWindowFunc:Int(hwnd:Int, newfunc:Int(hwnd:Int, DbgMsg:Int, wparam:Int, lparam:Int))
Local oldfunc:Int = GetWindowLong( hwnd, GWL_WNDPROC)
SetWindowLong( hwnd, GWL_WNDPROC, Int(Byte Ptr newfunc))
Return oldfunc
EndFunction

Function DropWindowFunc:Int(hwnd:Int, DbgMsg:Int, wparam:Int, lparam:Int) "Win32"

Select DbgMsg
Case WM_DROPFILES
Local count:Int = DragQueryFile( wparam, -1, Null, 0)

For Local i:Int = 0 Until count
Local sz:Int = DragQueryFile( wparam, i, Null, 0)
Local buf:Byte[sz+1]
DragQueryFile(wparam, i, buf, buf.Length)
DraggedURL = DraggedURL + String.FromBytes(buf, sz)
Next

ReadDraggedURl_Flg = True

Case WM_DESTROY

SetWindowLong( hwnd, GWL_WNDPROC, OldWindowFunc)

EndSelect
Return CallWindowProc( OldWindowFunc, hwnd, DbgMsg, wparam, Int(lparam))
EndFunction

'-------------------------------------------------------------------------------------'

Function PrepareDragFileSys()
ThisWinAddress:Int = GetActiveWindow() 'Use GetBlitzmaxWindow() if you dont use Xors
OldWindowFunc:Int = SetWindowFunc(ThisWinAddress, DropWindowFunc)
DragAcceptFiles(ThisWinAddress, True)
End Function

Function GetDraggedUrl:String()
Local DU:String
If ReadDraggedURl_Flg = True Then
ReadDraggedURl_Flg = False
DU = DraggedURL
DraggedURL = ""
Return DU
End If
End Function
Code

fielder

very thank you!!! this probably was the method i used some years ago' :)

Hardcoal

Code