Page 1 of 1

[SOLVED] Drag'n'Drop and Admin mode

Posted: Tue Mar 19, 2024 8:22 pm
by boddhi
Hello,

Is there a reason why drag'n'drop doesn't work in Admin mode? or bug?
In this mode, the StringGadget doesn't accept drag operation :shock:

Tested with PB 6.03 LTS and PB 6.10b8 x64 on Win 10 x64:

Code: Select all

EnableExplicit

Define.s XMLString

XMLString="<?xml version='1.0' encoding='UTF-16'?>"+Chr(10)+ ;{
          "<dialogs>"+Chr(10)+
          "  <window id='0' name='Window1' text='Test' xpos='0' ypos='0' width='auto' minwidth='200' flags='#PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget|#PB_Window_ScreenCentered'>"+Chr(10)+
          "    <string id='0' name='String1' flags='#PB_String_ReadOnly'/>"+Chr(10)+
          "  </window> "+Chr(10)+
          "</dialogs>" ;}

ParseXML(0,XMLString)
CreateDialog(0)
OpenXMLDialog(0,0,"Window1",0,0,0,0)
EnableGadgetDrop(0,#PB_Drop_Files,#PB_Drag_Copy)
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_GadgetDrop
      Select EventGadget()
        Case 0
          ClearDebugOutput()
          Debug "Hello, I've been here!"
          Debug EventDropFiles()
      EndSelect
  EndSelect
ForEver
 
Thanks.

Re: Drag'n'Drop and Admin mode

Posted: Wed Mar 20, 2024 3:44 am
by RASHAD
Hi
How do you expect the string gadget to accept D&D if it's Read Only

Code: Select all

EnableExplicit

Define.s XMLString

XMLString="<?xml version='1.0' encoding='UTF-16'?>"+Chr(10)+ ;{
          "<dialogs>"+Chr(10)+
          "  <window id='0' name='Window1' text='Test' xpos='0' ypos='0' width='auto' minwidth='200' flags='#PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget|#PB_Window_ScreenCentered'>"+Chr(10)+
          "    <string id='0' name='String1' flags='#PB_String_LowerCase'/>"+Chr(10)+
          "  </window> "+Chr(10)+
          "</dialogs>" ;}

ParseXML(0,XMLString)
CreateDialog(0)
OpenXMLDialog(0,0,"Window1",0,0,0,0)
EnableGadgetDrop(0,#PB_Drop_Text, #PB_Drag_Copy) 
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_GadgetDrop
      Select EventGadget()
        Case 0
          SetGadgetText(0,EventDropText())
      EndSelect
  EndSelect
ForEver

Re: Drag'n'Drop and Admin mode

Posted: Wed Mar 20, 2024 6:00 am
by boddhi
Hi RASHAD,
RASHAD wrote: How do you expect the string gadget to accept D&D if it's Read Only
Thanks for your reply :wink:
But do you have tested my code in both modes, user and admin mode?
If the ReadOnly flag is the problem, why my code works in user mode and not in admin mode?
And I don't understand why this flag would prohibit drag and drop operations?!

I've tested with a TextGadget too and same results... Works in user mode, not in admin mode!

New code with boths gadgets and, here, StingGadget has no flag. See by yourself:

Code: Select all

EnableExplicit

Define.s XMLString
Runtime Enumeration
  #String
  #Text
EndEnumeration

XMLString="<?xml version='1.0' encoding='UTF-16'?>"+Chr(10)+ ;{
          "<dialogs>"+Chr(10)+
          "  <window id='0' name='Window1' text='Test' xpos='0' ypos='0' flags='#PB_Window_SystemMenu|#PB_Window_ScreenCentered'>"+Chr(10)+
          "    <vbox>"+Chr(10)+
          "      <string id='#String' name='String' text='String gadget : Drop file here...' width='400'/>"+Chr(10)+
          "      <text id='#Text' name='Text' text='Text gadget : Drop file here...'/>"+Chr(10)+
          "    </vbox> "+Chr(10)+
          "  </window>"+Chr(10)+
          "</dialogs>" ;}

ParseXML(0,XMLString)
CreateDialog(0)
OpenXMLDialog(0,0,"Window1",0,0,0,0)
EnableGadgetDrop(#String,#PB_Drop_Files,#PB_Drag_Copy)
EnableGadgetDrop(#Text,#PB_Drop_Files,#PB_Drag_Copy)
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_GadgetDrop
      Select EventGadget()
        Case #String,#Text
          SetGadgetText(EventGadget(),StringField(EventDropFiles(),1,Chr(10)))
      EndSelect
  EndSelect
ForEver

Re: Drag'n'Drop and Admin mode

Posted: Wed Mar 20, 2024 9:42 am
by AZJIO
To drag and drop files without problems, you must have both programs running as administrator.

To ensure that drag and drop does not depend on the program's privilege level, add this code.
https://www.purebasic.fr/english/viewto ... 07#p565407
https://www.purebasic.fr/english/viewtopic.php?p=603483
https://www.purebasic.fr/english/viewto ... 93#p574793

Code: Select all

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

Re: Drag'n'Drop and Admin mode

Posted: Wed Mar 20, 2024 11:29 am
by boddhi
Hi AZIJO,

Thanks for your reply.
AZJIO wrote: To drag and drop files without problems, you must have both programs running as administrator.
 
I tried this, with two alternatives. Firstly with gadget, secondly with window:

Code: Select all

EnableExplicit

Define.s XMLString
Runtime Enumeration
  #String
  #Text
EndEnumeration

XMLString="<?xml version='1.0' encoding='UTF-16'?>"+Chr(10)+ ;{
          "<dialogs>"+Chr(10)+
          "  <window id='0' name='Window1' text='Test' xpos='0' ypos='0' flags='#PB_Window_SystemMenu|#PB_Window_ScreenCentered'>"+Chr(10)+
          "    <vbox>"+Chr(10)+
          "      <string id='#String' name='String' text='String gadget : Drop file here...' width='400'/>"+Chr(10)+
          "      <text id='#Text' name='Text' text='Text gadget : Drop file here...'/>"+Chr(10)+
          "    </vbox> "+Chr(10)+
          "  </window>"+Chr(10)+
          "</dialogs>" ;}

ParseXML(0,XMLString)
CreateDialog(0)
OpenXMLDialog(0,0,"Window1",0,0,0,0)
EnableGadgetDrop(#String,#PB_Drop_Files,#PB_Drag_Copy)
EnableGadgetDrop(#Text,#PB_Drop_Files,#PB_Drag_Copy)
ChangeWindowMessageFilter_(#WM_DROPFILES,#MSGFLT_ADD)
ChangeWindowMessageFilter_(#WM_COPYDATA, #MSGFLT_ADD)
ChangeWindowMessageFilter_(73, #MSGFLT_ADD)    
ChangeWindowMessageFilter_(49, #MSGFLT_ADD) ; I don't why but it makes nice! :))
; Alternate this two lines to see
SetWindowLongPtr_(GadgetID(#String),#GWL_EXSTYLE,GetWindowLongPtr_(GadgetID(#String),#GWL_EXSTYLE)|#WS_EX_ACCEPTFILES)
;SetWindowLongPtr_(WindowID(0),#GWL_EXSTYLE,GetWindowLongPtr_(WindowID(0),#GWL_EXSTYLE)|#WS_EX_ACCEPTFILES)

Repeat
  Select WaitWindowEvent()
    Case #WM_DROPFILES
      Debug "Dropfiles"
    Case #WM_COPYDATA
      Debug "copydata"
    Case 73
      Debug "73"
    Case 49
      Debug "49"
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_GadgetDrop
      Select EventGadget()
        Case #String,#Text
          SetGadgetText(EventGadget(),StringField(EventDropFiles(),1,Chr(10)))
      EndSelect
  EndSelect
ForEver
In first case, no change, gadget doesn't still accept drop and, secondary, the window accept but stil not the gadget.
I'm very confused :oops:

And I see too, in MSDN, that ChangeWindowMessageFilter will be deprecated in future...

Re: Drag'n'Drop and Admin mode

Posted: Wed Mar 20, 2024 1:46 pm
by RASHAD
Hi
You can't D&D from lower UAC to higher UAC [ Security issue ]
Workaround :
1- Create a dummy application as user UAC
2- D&D to the dummy
3- Copy from the dummy then paste to the higher one

It's tricky and need some ghost effects to do it :)

Re: Drag'n'Drop and Admin mode

Posted: Wed Mar 20, 2024 3:42 pm
by boddhi
@AZIJO
AZJIO wrote: To ensure that drag and drop does not depend on the program's privilege level, add this code.
Is your example applicable to only one (or several) gadgets or only to the window?

@RASHAD
RASHAD wrote: You can't D&D from lower UAC to higher UAC [ Security issue ] Workaround [...}
Thanks sincerely RASHAD for your suggestion, but it's not a solution I find "ideal".

After further research, with my modest level of computer competences and comprehension, the difficulties of D&D between applications of different security levels are long-standing and very often cause problems for developers. I don't know why MS took this decision, but I hope it was seriously justified. :D

The solution given by AZIJJO is often proposed as a workaround but doesn't seem to work for me (maybe I'm not using it correctly, which is quite possible :mrgreen: ).

It's also often recommended to use ChangeWindowMessageFilterEx instead of ChangeWindowMessageFilter, but this API function is not (yet) implemented in PB if I look at the list provided by the team.

In the meantime, as a famous French humorist once said: "Tell me what you need, and I'll tell you how to get by without it."

I'll wait until there's a solution, if there ever is one!
 

Re: Drag'n'Drop and Admin mode

Posted: Wed Mar 20, 2024 5:28 pm
by boddhi
EUREKA!!! I got the neurons firing! 🤯 But I've finally reached my goal!!!
One small step for the community, one giant leap for me! :mrgreen:

@AZIJO
There was an error in the code for the first link you provided.
The variable Dropped was typed .l instead of .i. On a 32-bit system, no issue, but it didn't work on x64. So I replaced the type with .i (equivalent to .q under x64) and now it works.

Thanks to AZIJO, RASHAD and all those who worked so hard before me to produce code on this subject.

So, below is my working code with detection of the gadget that received the drop action.

Code: Select all

EnableExplicit
;
If OSVersion()<#PB_OS_Windows_Vista
  MessageRequester("","This code only runs on Windows Vista Or above",#PB_MessageRequester_Error)
  End
EndIf

Define.s XMLString
Runtime Enumeration
  #String
  #Text
EndEnumeration
;
XMLString="<?xml version='1.0' encoding='UTF-16'?>"+Chr(10)+ ;{
          "<dialogs>"+Chr(10)+
          "  <window id='0' name='Window1' text='Test' xpos='0' ypos='0' flags='#PB_Window_SystemMenu|#PB_Window_ScreenCentered'>"+Chr(10)+
          "    <vbox>"+Chr(10)+
          "      <string id='#String' name='String' text='String gadget : Drop file here...' width='400'/>"+Chr(10)+
          "      <text id='#Text' name='Text' text='Text gadget : Drop file here...' width='400'/>"+Chr(10)+
          "    </vbox> "+Chr(10)+
          "  </window>"+Chr(10)+
          "</dialogs>" ;}
;
ParseXML(0,XMLString)
CreateDialog(0)
OpenXMLDialog(0,0,"Window1",0,0,0,0)
ChangeWindowMessageFilter_(#WM_DROPFILES,#MSGFLT_ADD)
ChangeWindowMessageFilter_(#WM_COPYDATA, #MSGFLT_ADD)
ChangeWindowMessageFilter_(73, #MSGFLT_ADD)    
SetWindowLongPtr_(GadgetID(#String),#GWL_EXSTYLE,GetWindowLongPtr_(GadgetID(#String),#GWL_EXSTYLE)|#WS_EX_ACCEPTFILES)
SetWindowLongPtr_(GadgetID(#Text),#GWL_EXSTYLE,GetWindowLongPtr_(GadgetID(#Text),#GWL_EXSTYLE)|#WS_EX_ACCEPTFILES)
;
Define.i Dropped,HGadget
Define.l NumberOfFiles,Count,StringLength,GadgetNumber
Define.s FileName,FileNameWanted
Define.POINT PosCursor
;
Repeat
  Select WaitWindowEvent()
    Case #WM_DROPFILES ; Vista and above
      Debug EventGadget()
      GetCursorPos_(@PosCursor)
      HGadget=WindowFromPoint_(PeekQ(@PosCursor))
      GadgetNumber=GetProp_(HGadget,"PB_WindowID")
      Select GadgetNumber
        Case #String:Debug "Gadget #String dropped"
        Case #Text:Debug "Gadget #Text dropped"
      EndSelect
      Dropped=EventwParam()
      NumberOfFiles=DragQueryFile_(Dropped,-1,"",0)
      If NumberOfFiles
        For Count=0 To NumberOfFiles-1
          StringLength=DragQueryFile_(Dropped,Count,0,0)
          FileName=Space(StringLength)
          DragQueryFile_(Dropped,Count,FileName,StringLength+1)
          Debug "File #"+Count+" dropped : "+FileName
          If Count=0 ; I want only the first file for demonstration
            FileNameWanted=FileName
          EndIf
        Next
        DragFinish_(Dropped)
        Debug "File wanted : "+FileNameWanted
        SetGadgetText(GadgetNumber,FileNameWanted)
      EndIf
    Case #PB_Event_CloseWindow
      Break
  EndSelect
ForEver

Re: [SOLVED] Drag'n'Drop and Admin mode

Posted: Wed Mar 20, 2024 5:35 pm
by AZJIO
boddhi
I use this in 3 programs:
ContMenuFiles
SubMenuWin7_10
zRegistration
I use it everywhere to transfer files from a file manager.
Ready example here

Re: [SOLVED] Drag'n'Drop and Admin mode

Posted: Wed Mar 20, 2024 6:19 pm
by boddhi
AZJIO wrote: I use this in 3 programs:
Sorry, I don't really understand the exact reason of your last message.

Your example below don't use API calls so I suppose it works for user mode only?! And I needed a code to run in both modes.
Or if it's because I said there was an error in the code of the first link you gave me, it doesn't work until I change the variable's type... :wink:

Once again, maybe I didn't quite understand your post :mrgreen:

Thanks again for your precious help.

Re: [SOLVED] Drag'n'Drop and Admin mode

Posted: Wed Mar 20, 2024 6:50 pm
by AZJIO
boddhi
I don't have time to study your code, but there are a lot of inconsistencies in it.

Code: Select all

Case #PB_Event_GadgetDrop ; XP

Code: Select all

ChangeWindowMessageFilter_
ChangeWindowMessageFilter_ will not work on WinXP
PB 6.10b8 will not work on WinXP
You use #WS_EX_ACCEPTFILES to assign a drag-and-drop style. But for this there is EnableGadgetDrop()
You're using #WM_DROPFILES, but there's #PB_Event_GadgetDrop for that.
You don't need to get the gadget under the cursor using WindowFromPoint_, there's EventGadget() for that

Re: [SOLVED] Drag'n'Drop and Admin mode

Posted: Thu Mar 21, 2024 12:11 am
by boddhi
AZJIO wrote: ChangeWindowMessageFilter_ will not work on WinXP
You're right and I've modified the code accordingly.
 
AZJIO wrote: PB 6.10b8 will not work on WinXP
That's true too, but maybe it could be useful for others with PB 6.04 and older and Win > XP.
 
 
For the rest, I don't have your programming competences, but what I've noticed is that the DragDrop lib functions don't work when my application is launched in Admin mode (what I need to be able to write to the registry) with other applications launched in User mode.
And as these functions don't work (due to Windows), I haven't found any other way to retrieve the gadget number. But maybe I'm wrong...