Drag and Drop in admin mode question

Windows specific forum
User avatar
Dreamland Fantasy
Enthusiast
Enthusiast
Posts: 335
Joined: Fri Jun 11, 2004 9:35 pm
Location: Glasgow, UK
Contact:

Drag and Drop in admin mode question

Post by Dreamland Fantasy »

Hi there,

I am looking to be able to drag and drop a file from the Windows desktop onto a gadget and get the filename. The problem is that the program needs to be able to run in admin mode, but the drag and drop does not work in this case using PureBasic's inbuilt commands.

I saw that there was a discussion here regarding this, but the solution given makes the whole window the drop zone instead of a single gadget.

I've provided some example code below that I would like to be able to work in admin mode.

Code: Select all

OpenWindow(0, 0, 0, 640, 480, "Drag and Drop Test Window", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)

CreateImage(0, 600, 440, 32, #PB_Image_Transparent)
ImageGadget(0, 20, 20, 600, 440, ImageID(0), #PB_Image_Border)

EnableGadgetDrop(0, #PB_Drop_Files, #PB_Drag_Copy)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_GadgetDrop
      Debug EventDropFiles()
    Case #PB_Event_CloseWindow
      ExitProgram = 1
  EndSelect
Until ExitProgram = 1
Kind regards,

Francis
BarryG
Addict
Addict
Posts: 4173
Joined: Thu Apr 18, 2019 8:17 am

Re: Drag and Drop in admin mode question

Post by BarryG »

Dreamland Fantasy wrote: Fri Oct 07, 2022 10:12 pmI saw that there was a discussion here regarding this, but the solution given makes the whole window the drop zone instead of a single gadget.
You just have to change the SetWindowLongPtr_() line in that post to use GadgetID(#CanvasGadget) instead of "hWND".

I updated that post for you -> viewtopic.php?p=590043#p590043
User avatar
Dreamland Fantasy
Enthusiast
Enthusiast
Posts: 335
Joined: Fri Jun 11, 2004 9:35 pm
Location: Glasgow, UK
Contact:

Re: Drag and Drop in admin mode question

Post by Dreamland Fantasy »

BarryG wrote: Sat Oct 08, 2022 3:06 amYou just have to change the SetWindowLongPtr_() line in that post to use GadgetID(#CanvasGadget) instead of "hWND".

I updated that post for you -> viewtopic.php?p=590043#p590043
Thanks BarryG. That worked, although when I plugged it into my program, it still didn't work.

After some investigating, it appears that the drag and drop for the gadget is being blocked by being inside a frame. The only way I can get it to work is if I set the drag and drop up for the frame itself:

Code: Select all

Procedure EnableGadgetFileDropAdmin(Gadget.i)
  ChangeWindowMessageFilter_(#WM_DROPFILES, #MSGFLT_ADD)
  ChangeWindowMessageFilter_(#WM_COPYDATA, #MSGFLT_ADD)
  ChangeWindowMessageFilter_(73, #MSGFLT_ADD)          
  SetWindowLongPtr_(GadgetID(Gadget), #GWL_EXSTYLE, GetWindowLongPtr_(GadgetID(Gadget), #GWL_EXSTYLE) | #WS_EX_ACCEPTFILES)
EndProcedure

Procedure.s GetDroppedFile()

  Protected.l Dropped, Num, Index, Size
  Protected FileName$, PhraseFilename$ = ""
  
  Dropped = EventwParam()
  Num = DragQueryFile_(Dropped, - 1, "", 0) - 1
  
  For Index = 0 To Num
    Size = DragQueryFile_(Dropped, Index, 0, 0)
    FileName$ = Space(Size)
    DragQueryFile_(Dropped, Index, FileName$, Size + 1)
    Debug "File ''" + FileName$ + "'' Dropped"
  Next
  
  DragFinish_(Dropped)
  
  ProcedureReturn FileName$
  
EndProcedure

Enumeration
  #FrameGadget
  #ImageGadget
EndEnumeration

OpenWindow(0, 0, 0, 640, 480, "Drag and Drop Test Window", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)

CreateImage(0, 600, 440, 32, #PB_Image_Transparent)

FrameGadget(#FrameGadget, 5, 5, 630, 470, "Frame")
ImageGadget(#ImageGadget, 20, 20, 600, 440, ImageID(0), #PB_Image_Border)

EnableGadgetFileDropAdmin(#FrameGadget) ; <- If changed to #ImageGadget, it doesn't work

Repeat
  Select WaitWindowEvent()
    Case #WM_DROPFILES
      GetDroppedFile()
    Case #PB_Event_CloseWindow
      ExitProgram = 1
  EndSelect
Until ExitProgram = 1
Although better, it's still not ideal as the frame in the program I'm working on is a larger area than the gadget I'm trying to set up for the drag and drop.

Kind regards,

Francis
User avatar
Dreamland Fantasy
Enthusiast
Enthusiast
Posts: 335
Joined: Fri Jun 11, 2004 9:35 pm
Location: Glasgow, UK
Contact:

Re: Drag and Drop in admin mode question

Post by Dreamland Fantasy »

I found a solution here for this very issue. Using BringWindowToTop_() to bring the gadget to the top works:

Code: Select all

Procedure EnableGadgetFileDropAdmin(Gadget.i)
  ChangeWindowMessageFilter_(#WM_DROPFILES, #MSGFLT_ADD)
  ChangeWindowMessageFilter_(#WM_COPYDATA, #MSGFLT_ADD)
  ChangeWindowMessageFilter_(73, #MSGFLT_ADD)          
  SetWindowLongPtr_(GadgetID(Gadget), #GWL_EXSTYLE, GetWindowLongPtr_(GadgetID(Gadget), #GWL_EXSTYLE) | #WS_EX_ACCEPTFILES)
EndProcedure

Procedure.s GetDroppedFile()

  Protected.l Dropped, Num, Index, Size
  Protected FileName$, PhraseFilename$ = ""
  
  Dropped = EventwParam()
  Num = DragQueryFile_(Dropped, - 1, "", 0) - 1
  
  For Index = 0 To Num
    Size = DragQueryFile_(Dropped, Index, 0, 0)
    FileName$ = Space(Size)
    DragQueryFile_(Dropped, Index, FileName$, Size + 1)
    Debug "File ''" + FileName$ + "'' Dropped"
  Next
  
  DragFinish_(Dropped)
  
  ProcedureReturn FileName$
  
EndProcedure

Enumeration
  #FrameGadget
  #ImageGadget
EndEnumeration

OpenWindow(0, 0, 0, 640, 480, "Drag and Drop Test Window", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)

CreateImage(0, 600, 440, 32, #PB_Image_Transparent)

FrameGadget(#FrameGadget, 5, 5, 630, 470, "Frame")
ImageGadget(#ImageGadget, 20, 20, 600, 440, ImageID(0), #PB_Image_Border)

EnableGadgetFileDropAdmin(#ImageGadget)

BringWindowToTop_(GadgetID(#ImageGadget))

Repeat
  Select WaitWindowEvent()
    Case #WM_DROPFILES
      GetDroppedFile()
    Case #PB_Event_CloseWindow
      ExitProgram = 1
  EndSelect
Until ExitProgram = 1
Kind regards,

Francis
Post Reply