Windows Drag Drop

Just starting out? Need help? Post your questions and find answers here.
SteffenSperling
User
User
Posts: 12
Joined: Tue Mar 27, 2018 6:16 pm

Windows Drag Drop

Post by SteffenSperling »

Hi ALL,

the PureBasic Editor accept text drop, fileDrop

but if I try to use the same future I get only the forbidden cursor.

my Code:

Code: Select all


If OpenWindow(#MainWindow, posX, posY, WindowBreite, WindowHoehe, "1aAppStartmenu", #PB_Window_BorderLess )
	If StickyPos
		StickyWindow(#MainWindow, #True) 	
	EndIf
	
	
	CanvasGadget(#CanvasGadget, 50, 50, CanvasBreite, CanvasHoehe)
	
	hWND = WindowID(#MainWindow)
	
	EnableWindowDrop(#MainWindow, #PB_Drop_Text   , #PB_Drag_Copy )
	EnableWindowDrop(#MainWindow, #PB_Drop_Files   , #PB_Drag_Copy )
    
	ChangeWindowMessageFilter_(#WM_DROPFILES, #MSGFLT_ADD)
	ChangeWindowMessageFilter_(#WM_COPYDATA, #MSGFLT_ADD)
	
	Define WM_COPYGLOBALDATA = Val("$0049")	;73
	ChangeWindowMessageFilter_(73, #MSGFLT_ADD)		    
	
	SetWindowLongPtr_(hWND, #GWL_EXSTYLE, GetWindowLongPtr_(hWND, #GWL_EXSTYLE) | #WS_EX_ACCEPTFILES)			
		
	

Does somebody has any idea?

greetings Steffen
wombats
Enthusiast
Enthusiast
Posts: 664
Joined: Thu Dec 29, 2011 5:03 pm

Re: Windows Drag Drop

Post by wombats »

Is this what you're looking to do?

Code: Select all

Procedure OnFilesDropped()
  Protected files.s, count, i
  files = EventDropFiles()
  count = CountString(files, Chr(10))
  For i = 0 To count
    Debug StringField(files, i + 1, Chr(10))
  Next
EndProcedure

If OpenWindow(0, 0, 0, 350, 250, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  EnableWindowDrop(0, #PB_Drop_Files, #PB_Drag_Copy)
  BindEvent(#PB_Event_WindowDrop, @OnFilesDropped(), 0)
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
SteffenSperling
User
User
Posts: 12
Joined: Tue Mar 27, 2018 6:16 pm

Re: Windows Drag Drop

Post by SteffenSperling »

Thanks but this isnt it:

your example is not working :|

It works only if you drop files inside the application.
If you drop a file from outside e.g. a Desktop item or any other, it doesnt work.
The same with TEXT.


Under win10 you have to register your programm for the DragDrop Messages like I shown in my code.
I have programms which work with this. But in Purebasic it dosnt work.


this is what not work in PureBasic but in VB or PowerBasic:

ChangeWindowMessageFilter_(#WM_DROPFILES, #MSGFLT_ADD) ;Files
ChangeWindowMessageFilter_(#WM_COPYDATA, #MSGFLT_ADD) ;Text

Define WM_COPYGLOBALDATA = Val("$0049") ;73
ChangeWindowMessageFilter_(73, #MSGFLT_ADD) ; for working from outside

As mentioned, it works in the PureBasic Editor but not in my Tests

Does somebody has an idea?

Greeting Steffen
User avatar
chi
Addict
Addict
Posts: 1034
Joined: Sat May 05, 2007 5:31 pm
Location: Linz, Austria

Re: Windows Drag Drop

Post by chi »

I checked on Win7 + Win10 and it works like expected...
FYI: Debug only works with the Debugger enabled within the IDE (or with PureBasic_Compilation?.exe from your %TEMP% folder)

Code: Select all

Procedure OnFilesDropped()
  Protected files.s, count, i
  files = EventDropFiles()
  count = CountString(files, Chr(10))
  ; For i = 0 To count
  ;   Debug StringField(files, i + 1, Chr(10))
  ; Next
  MessageRequester("", files, #PB_MessageRequester_Info)
EndProcedure

If OpenWindow(0, 0, 0, 350, 250, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  EnableWindowDrop(0, #PB_Drop_Files, #PB_Drag_Copy)
  BindEvent(#PB_Event_WindowDrop, @OnFilesDropped(), 0)
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Et cetera is my worst enemy
Marc56us
Addict
Addict
Posts: 1479
Joined: Sat Feb 08, 2014 3:26 pm

Re: Windows Drag Drop

Post by Marc56us »

You do not need to use APIs for drag'n'drop functions in PB. All functions are included in the language.
Try the official example. It shows all the drag'n'drop possibilities from and to the application and host system as well as internally, whether for text, files or images.

Code: Select all

;
; ------------------------------------------------------------
;
;   PureBasic - Drag & Drop
;
;    (c) Fantaisie Software
;
; ------------------------------------------------------------
;

#Window = 0

Enumeration    ; Images
  #ImageSource
  #ImageTarget
EndEnumeration

Enumeration    ; Gadgets
  #SourceText
  #SourceImage
  #SourceFiles
  #SourcePrivate
  #TargetText
  #TargetImage
  #TargetFiles
  #TargetPrivate1
  #TargetPrivate2
EndEnumeration



If OpenWindow(#Window, 0, 0, 760, 310, "Drag & Drop", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  
  ; Create some images for the image demonstration
  ; 
  CreateImage(#ImageSource, 136, 136)
  If StartDrawing(ImageOutput(#ImageSource))
    Box(0, 0, 136, 136, $FFFFFF)
    DrawText(5, 5, "Drag this image", $000000, $FFFFFF)        
    For i = 45 To 1 Step -1
      Circle(70, 80, i, Random($FFFFFF))
    Next i        
    
    StopDrawing()
  EndIf  
  
  CreateImage(#ImageTarget, 136, 136)
  If StartDrawing(ImageOutput(#ImageTarget))
    Box(0, 0, 136, 136, $FFFFFF)
    DrawText(5, 5, "Drop images here", $000000, $FFFFFF)
    StopDrawing()
  EndIf  
  
  
  ; Create and fill the source gadgets
  ;
  ListIconGadget(#SourceText,       10, 10, 140, 140, "Drag Text here", 130)   
  ImageGadget(#SourceImage,        160, 10, 140, 140, ImageID(#ImageSource), #PB_Image_Border) 
  ExplorerListGadget(#SourceFiles, 310, 10, 290, 140, GetHomeDirectory(), #PB_Explorer_MultiSelect)
  ListIconGadget(#SourcePrivate,   610, 10, 140, 140, "Drag private stuff here", 260)
     
  AddGadgetItem(#SourceText, -1, "hello world")
  AddGadgetItem(#SourceText, -1, "The quick brown fox jumped over the lazy dog")
  AddGadgetItem(#SourceText, -1, "abcdefg")
  AddGadgetItem(#SourceText, -1, "123456789")
  
  AddGadgetItem(#SourcePrivate, -1, "Private type 1")
  AddGadgetItem(#SourcePrivate, -1, "Private type 2")
  

  ; Create the target gadgets
  ;
  ListIconGadget(#TargetText,  10, 160, 140, 140, "Drop Text here", 130)
  ImageGadget(#TargetImage,    160, 160, 140, 140, ImageID(#ImageTarget), #PB_Image_Border) 
  ListIconGadget(#TargetFiles, 310, 160, 140, 140, "Drop Files here", 130)
  ListIconGadget(#TargetPrivate1, 460, 160, 140, 140, "Drop Private Type 1 here", 130)
  ListIconGadget(#TargetPrivate2, 610, 160, 140, 140, "Drop Private Type 2 here", 130)

  
  ; Now enable the dropping on the target gadgets
  ;
  EnableGadgetDrop(#TargetText,     #PB_Drop_Text,    #PB_Drag_Copy)
  EnableGadgetDrop(#TargetImage,    #PB_Drop_Image,   #PB_Drag_Copy)
  EnableGadgetDrop(#TargetFiles,    #PB_Drop_Files,   #PB_Drag_Copy)
  EnableGadgetDrop(#TargetPrivate1, #PB_Drop_Private, #PB_Drag_Copy, 1)
  EnableGadgetDrop(#TargetPrivate2, #PB_Drop_Private, #PB_Drag_Copy, 2)

  Repeat
    Event = WaitWindowEvent()
    
    ; DragStart event on the source gadgets, initiate a drag & drop
    ;
    If Event = #PB_Event_Gadget And EventType() = #PB_EventType_DragStart
      Select EventGadget()
      
        Case #SourceText
          Text$ = GetGadgetItemText(#SourceText, GetGadgetState(#SourceText))
          DragText(Text$)
        
        Case #SourceImage
          DragImage(ImageID(#ImageSource))
        
        Case #SourceFiles
          Files$ = ""       
          For i = 0 To CountGadgetItems(#SourceFiles)-1
            If GetGadgetItemState(#SourceFiles, i) & #PB_Explorer_Selected
              Files$ + GetGadgetText(#SourceFiles) + GetGadgetItemText(#SourceFiles, i) + Chr(10)
            EndIf
          Next i 
          If Files$ <> ""
            DragFiles(Files$)
          EndIf
        
        ; "Private" Drags only work within the program, everything else
        ; also works with other applications (Explorer, Word, etc)
        ;
        Case #SourcePrivate
          If GetGadgetState(#SourcePrivate) = 0
            DragPrivate(1)
          Else
            DragPrivate(2)
          EndIf
              
      EndSelect
    
    ; Drop event on the target gadgets, receive the dropped data
    ;
    ElseIf Event = #PB_Event_GadgetDrop
      Select EventGadget()
      
        Case #TargetText
          AddGadgetItem(#TargetText, -1, EventDropText())
        
        Case #TargetImage
          If EventDropImage(#ImageTarget)
            SetGadgetState(#TargetImage, ImageID(#ImageTarget))
          EndIf
        
        Case #TargetFiles
          Files$ = EventDropFiles()
          Count  = CountString(Files$, Chr(10)) + 1
          For i = 1 To Count
            AddGadgetItem(#TargetFiles, -1, StringField(Files$, i, Chr(10)))
          Next i
        
        Case #TargetPrivate1
          AddGadgetItem(#TargetPrivate1, -1, "Private type 1 dropped")
                
        Case #TargetPrivate2
          AddGadgetItem(#TargetPrivate2, -1, "Private type 2 dropped")
        
      EndSelect
    
    EndIf
    
  Until Event = #PB_Event_CloseWindow
EndIf

End
Source: https://www.purebasic.com/documentation ... op.pb.html

:wink:
SteffenSperling
User
User
Posts: 12
Joined: Tue Mar 27, 2018 6:16 pm

Re: Windows Drag Drop

Post by SteffenSperling »

Good morning and thanks for the answers,
but it doesn't work.

I have tryed ALL theese code befor, but none of them works for me.


I have tested it on 3 Windows PCs, ALL the same

here photos taken with my Phone. The cursor is "forbidden" exept on the IDE.


Image

Image

Image
User avatar
Bisonte
Addict
Addict
Posts: 1232
Joined: Tue Oct 09, 2007 2:15 am

Re: Windows Drag Drop

Post by Bisonte »

to drop file on your own window, only one EnableWindowDrop is needed.
No API....

Code: Select all

EnableWindowDrop(#Window, #PB_Drop_Files, #PB_Drag_Copy)
The example is show drag and drop between special gadgets, so it's right, that it shows a "forbidden" icon.
PureBasic 6.10 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
English is not my native language... (I often use DeepL to translate my texts.)
SteffenSperling
User
User
Posts: 12
Joined: Tue Mar 27, 2018 6:16 pm

Re: Windows Drag Drop

Post by SteffenSperling »

.. yes but it doesn't work on my 3 PCs !!

what you've written is the example of the 2. post. I tryed it.
you can see the result in my 2. picture
SteffenSperling
User
User
Posts: 12
Joined: Tue Mar 27, 2018 6:16 pm

Re: Windows Drag Drop

Post by SteffenSperling »

OK I found the problem but not the solution.

if I run the Programm as an ADMIN (Compiler Options or manually) I can'T drop any from outside.
If not => it works.

@Bisonte: the Gadgets also works from outside.


But now starts my Problem again. to fix it earlier e.g. in PowerBasic or VB I have Register the prog for Messages with:
PowerBasic Code:
----------------------------------------------------------------------------------------------------------------------------
' Only if vista or newer
hLib = LoadLibrary("user32.dll")
IF hLib THEN
hProc = GetProcAddress(hLib, "ChangeWindowMessageFilter") 'bei xp gibts das nicht
IF hProc THEN 'Succeded
'bei der Verwendung von Using muss die Funktion oben DEklariert werden !!
CALL DWORD hProc USING ChangeWindowMessageFilter(%WM_DROPFILES, 1) TO RetVal
CALL DWORD hProc USING ChangeWindowMessageFilter(%WM_COPYDATA, 1) TO RetVal
CALL DWORD hProc USING ChangeWindowMessageFilter(&H0049, 1) TO RetVal
END IF
hLib = FreeLibrary(hLib)
END IF
----------------------------------------------------------------------------------------------------------------------------
PureBasic Code:
ChangeWindowMessageFilter_(#WM_DROPFILES, #MSGFLT_ADD) ;Files
ChangeWindowMessageFilter_(#WM_COPYDATA, #MSGFLT_ADD)

Define WM_COPYGLOBALDATA = Val("$0049") ;73
ChangeWindowMessageFilter_(73, #MSGFLT_ADD) ; for from Outside
----------------------------------------------------------------------------------------------------------------------------

has no effect. but in PowerBasic / VB it works
Marc56us
Addict
Addict
Posts: 1479
Joined: Sat Feb 08, 2014 3:26 pm

Re: Windows Drag Drop

Post by Marc56us »

If I run the Programm as an ADMIN (Compiler Options or manually) I can'T drop any from outside.
If not => it works.
:arrow: So this is not a PureBasic problem, but an OS problem (user rights?)

Other possibility:
:idea: Windows 10 have problems on some configuration, search "windows 10 drag and drop problem"
Be sure to have the latest updates
Under win10 you have to register your programm for the DragDrop Messages like I shown in my code.
No. No needed special API call in PureBasic: EnableGadgetDrop and EnableWindowDrop do it for you.

I've been using (and I'm not the only one) drag and drop functions with PureBasic in many programs for years and on several Windows versions (XP, Vista, 7, 10) without API call without problems.
All commands you need are in library DragDrop

:wink:
User avatar
Bisonte
Addict
Addict
Posts: 1232
Joined: Tue Oct 09, 2007 2:15 am

Re: Windows Drag Drop

Post by Bisonte »

Marc56us wrote:
I've been using (and I'm not the only one) drag and drop functions with PureBasic in many programs for years and on several Windows versions (XP, Vista, 7, 10) without API call without problems.
All commands you need are in library DragDrop
Yes. I also use only PB commands and it works (Linux & Windows) :!:
PureBasic 6.10 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
English is not my native language... (I often use DeepL to translate my texts.)
SteffenSperling
User
User
Posts: 12
Joined: Tue Mar 27, 2018 6:16 pm

Re: Windows Drag Drop

Post by SteffenSperling »

Good Morning ALL again,

Please do not be angry about my next Question:


Dit you try to run the code as ADMIN and dropd a file on it?

If I run the PureBasic IDE as admin = >I can't drop files on it. Ist the same!

Please tell me the result.

https://www.google.de/search?num=100&ne ... BP6A95GOE0

https://social.msdn.microsoft.com/Forum ... evelopment

https://tutel.me/c/programming/question ... admin+mode

as mentioned above I solved the problem earlier, but in purebasic the solution is not working
User avatar
HeX0R
Addict
Addict
Posts: 992
Joined: Mon Sep 20, 2004 7:12 am
Location: Hell

Re: Windows Drag Drop

Post by HeX0R »

If you would run the Purebasic IDE as admin, you would see that this also won't work any longer.
See here:
https://social.technet.microsoft.com/Fo ... rosecurity

Out of curiosity:
Why does your program need admin rights?
SteffenSperling
User
User
Posts: 12
Joined: Tue Mar 27, 2018 6:16 pm

Re: Windows Drag Drop

Post by SteffenSperling »

Hi ALL,

@HeX0RYou are the first one who has recognized the Problem. Thank You

now can my Question starts again:

Why in PureBasic this WorkArround dos not work, what in Powerbasic or VB6 works?

Does someone has any idea?
Out of curiosity:
Why does your program need admin rights?
It's for restarting services and get access to some registry Keys to watch whats happends.
fluent
User
User
Posts: 68
Joined: Sun Jan 24, 2021 10:57 am

Re: Windows Drag Drop

Post by fluent »

Better late than never... This should do what you want:
(Using API, as PB commands don't seem to support this particular use case)

Code: Select all

#MainWindow = 0
#CanvasGadget = 1

OpenWindow(#MainWindow, 40, 40, 500, 400, "1aAppStartmenu" )  ;; , #PB_Window_BorderLess


CanvasGadget(#CanvasGadget, 50, 50, 300, 300)

hWND = WindowID(#MainWindow)


ChangeWindowMessageFilter_(#WM_DROPFILES, #MSGFLT_ADD)
ChangeWindowMessageFilter_(#WM_COPYDATA, #MSGFLT_ADD)
ChangeWindowMessageFilter_(73, #MSGFLT_ADD)          


SetWindowLongPtr_(hWND, #GWL_EXSTYLE, GetWindowLongPtr_(hWND, #GWL_EXSTYLE) | #WS_EX_ACCEPTFILES)    


Repeat
  e = WaitWindowEvent()
  Select e
    Case  #WM_DROPFILES 
      Define Dropped.l, Num.l, Index.l, Size.l, FileName.s
      Define PhraseFilename.s = ""
      
      Dropped.l = EventwParam()
      Num.l = DragQueryFile_(Dropped, - 1, "", 0)
      
      For Index = 0 To Num - 1
        
        Size.l = DragQueryFile_(Dropped, Index, 0, 0)
        FileName.s = Space(Size)
        DragQueryFile_(dropped, Index, FileName, Size + 1)
        MessageRequester("", "File ''" + FileName + "'' Dropped")
        
      Next
      
      DragFinish_(Dropped)
      
    Case  #PB_Event_CloseWindow : End
  EndSelect
Forever
Post Reply