Page 1 of 2

Getting the html link when dropping an image from a website

Posted: Tue Sep 27, 2016 9:17 pm
by Andre
Like the topic says, anyone knows the correct to get the complete html link when dragging an image from a website (e.g. Wikipedia) to an ImageGadget or CanvasGadget?

It should work cross-plattform (for me at least on Windows + MacOS).

Based on the regular Drag & Drop example code in the help it's no problem to get the correct file-path (on the current OS) when an image is dragged from a file commander etc.
But when dragging an image directly from an website I would like the complete html address (e.g. "www.server.com/image.png") instead of e.g. the file-path of the image in the temporary folder...

Thank you for any example / help!

Re: Getting the html link when dropping an image from a webs

Posted: Wed Sep 28, 2016 4:08 am
by RASHAD
Hi Andre
Sorry I can do it only for Windows
Maybe Shardik can do it for cross platform
You can get any Link :)

Code: Select all

Prototype.l AccessibleObjectFromPoint(x,y,*ia,*var)
Global AccessibleObjectFromPoint.AccessibleObjectFromPoint,Value.string, vt.VARIANT,*pIAcc.IAccessible,Text$

Olelib = OpenLibrary(#PB_Any,"Oleacc.dll")
AccessibleObjectFromPoint=GetFunction(Olelib,"AccessibleObjectFromPoint")

Procedure ObjectFromPoint( *Value.String,x,y)
  If AccessibleObjectFromPoint(x,y,@*pIAcc,@vt)=#S_OK
    *Value\s=""
    If *pIAcc\get_accValue(vt, @pName) = #S_OK
      Len = SysStringLen_(pName)
      *Value\s = Space(Len)      
      WideCharToMultiByte_(#CP_ACP, 0,pName, -1, @*Value\s, len, 0, 0)
      CompilerIf #PB_Compiler_Unicode 
        value\s = PeekS(@*Value\s,len,#PB_UTF8)
      CompilerEndIf      
      SysFreeString_(pName)
    EndIf
    *pIAcc\Release()
  EndIf
  ProcedureReturn #True
EndProcedure

LoadFont(0,"Georgia",12) 

OpenWindow(0, 0, 0, 800, 600, "WebGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
WebGadget(0, 0, 0, 400, 600 ,"http://www.purebasic.com")
ImageGadget(1,400,0,400,300,0)
EditorGadget(2 ,400,300,400,300)
SetGadgetFont(2,FontID(0)) 

EnableGadgetDrop(1,    #PB_Drop_Image,   #PB_Drag_Copy) 
EnableGadgetDrop(2,    #PB_Drop_Text,   #PB_Drag_Copy)     
    
Repeat
  Select WaitWindowEvent()
      
      Case #PB_Event_CloseWindow
          Quit = 1            
            
      Case #WM_LBUTTONDOWN
          GetCursorPos_ (@p.POINT)
          ObjectFromPoint(@value,p\x,p\y)
          Text$ = value\s          
           
      Case #PB_Event_GadgetDrop
        Select EventGadget()          
          Case 1
            If EventDropImage(1)
              SetGadgetState(1,ImageID(1))                          
              AddGadgetItem(2,-1,Text$+#CRLF$)
            EndIf
            
          Case 2
            If  EventDropText()                         
              AddGadgetItem(2,-1,Text$+#CRLF$)
            EndIf
      EndSelect
 ;
  EndSelect 

Until Quit = 1

CloseLibrary(Olelib) 

Re: Getting the html link when dropping an image from a webs

Posted: Wed Sep 28, 2016 9:06 pm
by Shardik
This is an example for MacOS (tested successfully on Snow Leopard and El Capitan with PB 5.43 x86 and x64 in both ASCII and Unicode mode):

Code: Select all

EnableExplicit

Define SubclassedImageGadget.I

Procedure SubclassGadget(GadgetID.I, NewClassName.S)
  Protected GadgetClass.I = CocoaMessage(0, GadgetID(GadgetID), "class")
  Protected NewGadgetClass.I

  NewGadgetClass = objc_allocateClassPair_(GadgetClass, NewClassName, 0)
  objc_registerClassPair_(NewGadgetClass)
  object_setClass_(GadgetID(GadgetID), NewGadgetClass)

  ProcedureReturn NewGadgetClass
EndProcedure

ProcedureC PrepareForDragOperation(Object.I, Selector.I, Sender.I)
  Protected Pasteboard.I
  Protected ImagePath.S
  Protected URL.I

  Pasteboard = CocoaMessage(0, Sender, "draggingPasteboard")
  URL = CocoaMessage(0, 0, "NSURL URLFromPasteboard:", Pasteboard)

  If URL
    ImagePath = PeekS(CocoaMessage(0, CocoaMessage(0, URL, "absoluteString"),
      "UTF8String"), -1, #PB_UTF8)
    AddGadgetItem(2, -1, ImagePath + #CR$)
  EndIf

  ProcedureReturn #True
EndProcedure

OpenWindow(0, 270, 100, 800, 600,
  "Drag the PureBasic logo onto the right ImageGadget")
WebGadget(0, 0, 0, 400, 600 ,"http://www.purebasic.com")
ImageGadget(1, 400, 0, 400, 300, 0)
EditorGadget(2, 400, 300, 400, 300)

EnableGadgetDrop(1, #PB_Drop_Image, #PB_Drag_Copy)

SubclassedImageGadget = SubclassGadget(1, "SubclassedImageGadget")
class_addMethod_(SubclassedImageGadget,
  sel_registerName_("prepareForDragOperation:"),
  @PrepareForDragOperation(), "v@:@")

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_GadgetDrop
      Select EventGadget()
        Case 1
          If EventDropImage(0)
            SetGadgetState(1, ImageID(0))
          EndIf
      EndSelect
  EndSelect
ForEver

Re: Getting the html link when dropping an image from a webs

Posted: Wed Sep 28, 2016 10:29 pm
by Andre
Hi RASHAD and Shardik,
thank you very much for your fast help!

While I couldn't test the code example on MacOS yet, I tried the Windows example.
Unfortunately I got an "Invalid memory access. (Write error on address 477)" at the line

Code: Select all

  If AccessibleObjectFromPoint(x,y,@*pIAcc,@vt)=#S_OK
Any ideas?

Re: Getting the html link when dropping an image from a webs

Posted: Wed Sep 28, 2016 10:53 pm
by RASHAD
Hi Andre
Make sure the library is opened
BTW what is your system configuration ?

Code: Select all

Olelib = OpenLibrary(#PB_Any,"Oleacc.dll")
If Olelib
  AccessibleObjectFromPoint=GetFunction(Olelib,"AccessibleObjectFromPoint")
Else
  MessageRequester("Error","Could't load the library",#MB_ICONERROR)
  End
EndIf

Re: Getting the html link when dropping an image from a webs

Posted: Wed Sep 28, 2016 11:13 pm
by Andre
Hi RASHAD,

the library is correctly opened, no error here.

The window with the embedded WebGadget is also correctly displayed.
Just after clicking on the image (which should be dragged to the ImageGadget) on the PureBasic.com website I get the error noted above.

I have tested on Windows 10 x64, using PB5.50 x64.

Re: Getting the html link when dropping an image from a webs

Posted: Wed Sep 28, 2016 11:25 pm
by Andre
Hi Shardik,
I couldn't wait, so just tested your MacOS code too :D
And it works like charm (tested on MacOS 10.6.8 with PB 5.42 LTS).
So thank you very much!


PS: If there is a Linux solution too (I don't need it), maybe a cross-platform solution (using a Module and/or some CompilerIf's) is possible too... :wink:

Re: Getting the html link when dropping an image from a webs

Posted: Wed Sep 28, 2016 11:27 pm
by RASHAD
Yes it did not work with PB x64 but it works fine with PB x86
Let me see what is going on

Re: Getting the html link when dropping an image from a webs

Posted: Wed Sep 28, 2016 11:31 pm
by Andre
RASHAD wrote:Yes it did not work with PB x64 but it works fine with PB x86
Let me see what is going on
Ok, thanks :)

Re: Getting the html link when dropping an image from a webs

Posted: Thu Sep 29, 2016 12:41 am
by RASHAD
Hi Andre
Please check
x86 - x64 Ascii & Unicode

Code: Select all

CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
  Prototype AccessibleObjectFromPoint(x,y,*ia,*var)
CompilerElse
  Prototype AccessibleObjectFromPoint(x,*ia,*var)
CompilerEndIf
  
Global AccessibleObjectFromPoint.AccessibleObjectFromPoint,Value.string, vt.VARIANT,*pIAcc.IAccessible,Text$

Olelib = OpenLibrary(#PB_Any,"Oleacc.dll")
If Olelib
  AccessibleObjectFromPoint=GetFunction(Olelib,"AccessibleObjectFromPoint")
Else
  MessageRequester("Error","Could't load the library",#MB_ICONERROR)
  End
EndIf

Procedure ObjectFromPoint( *Value.String,x,y)
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
    If AccessibleObjectFromPoint(x,y,@*pIAcc,@vt)=#S_OK
  CompilerElse
    If AccessibleObjectFromPoint(y<<32+x,@*pIAcc,@vt)=#S_OK
  CompilerEndIf
    *Value\s=""
    If *pIAcc\get_accValue(vt, @pName) = #S_OK
      Len = SysStringLen_(pName)
      *Value\s = Space(Len)     
      WideCharToMultiByte_(#CP_ACP, 0,pName, -1, @*Value\s, len, 0, 0)
      CompilerIf #PB_Compiler_Unicode
        value\s = PeekS(@*Value\s,len,#PB_UTF8)
      CompilerEndIf     
      SysFreeString_(pName)
    EndIf
    *pIAcc\Release()
  EndIf
  ProcedureReturn #True
EndProcedure

LoadFont(0,"Georgia",12)

OpenWindow(0, 0, 0, 800, 600, "WebGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
WebGadget(0, 0, 0, 400, 600 ,"http://www.purebasic.com")
ImageGadget(1,400,0,400,300,0)
EditorGadget(2 ,400,300,400,300)
SetGadgetFont(2,FontID(0))

EnableGadgetDrop(1,    #PB_Drop_Image,   #PB_Drag_Copy)
EnableGadgetDrop(2,    #PB_Drop_Text,   #PB_Drag_Copy)     
   
Repeat
  Select WaitWindowEvent()
     
      Case #PB_Event_CloseWindow
          Quit = 1           
           
      Case #WM_LBUTTONDOWN
          GetCursorPos_ (@p.POINT)
          ObjectFromPoint(@value,p\x,p\y)
          Text$ = value\s         
           
      Case #PB_Event_GadgetDrop
        Select EventGadget()         
          Case 1
            If EventDropImage(1)
              SetGadgetState(1,ImageID(1))                         
              AddGadgetItem(2,-1,Text$+#CRLF$)
            EndIf
           
          Case 2
            If  EventDropText()                         
              AddGadgetItem(2,-1,Text$+#CRLF$)
            EndIf
      EndSelect
 ;
  EndSelect

Until Quit = 1

CloseLibrary(Olelib) 

Re: Getting the html link when dropping an image from a webs

Posted: Thu Sep 29, 2016 11:28 am
by Shardik
This is an example for Linux (tested successfully on Linux Mint 18 "Sarah" x86 with Cinnamon using PB 5.43 x86 in ASCII and Unicode mode and PB 5.50 x86 with both GTK 2 and GTK 3):

Code: Select all

EnableExplicit

Define ImagePath.S

ProcedureC DragDataCallback(*Widget.GtkWidget,
  *DragContext.GdkDragContext, x.I, y.I, *Data.GtkSelectionData, Info.I,
  Time.i, *UserData)
  Shared ImagePath.S

  If *Data
    If ImagePath = ""
      ImagePath = PeekS(gtk_selection_data_get_text_(*Data), -1, #PB_UTF8)
    EndIf
  EndIf
EndProcedure

OpenWindow(0, 100, 100, 800, 600,
  "Drag the PureBasic logo onto the right ImageGadget")
WebGadget(0, 10, 10, 380, 580 ,"http://www.purebasic.com")
ImageGadget(1, 400, 10, 390, 290, 0, #PB_Image_Border)
EditorGadget(2, 400, 300, 390, 290)

EnableGadgetDrop(1, #PB_Drop_Image, #PB_Drag_Copy)

g_signal_connect_(GadgetID(0), "drag-data-received", @DragDataCallback(), 0)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_GadgetDrop
      Select EventGadget()
        Case 1
          If EventDropImage(0)
            SetGadgetState(1, ImageID(0))
            AddGadgetItem(2, -1, ImagePath)
            ImagePath = ""
          EndIf
      EndSelect
  EndSelect
ForEver

Re: Getting the html link when dropping an image from a webs

Posted: Thu Sep 29, 2016 2:35 pm
by Shardik
This is a cross-platform example for Linux, MacOS and Windows which I tested successfully on
  1. - Lubuntu 16.04 x86 with LXDE using PB 5.43 x86 with both GTK 2 and GTK 3 and in ASCII and Unicode mode
    - Linux Mint 18 x86 "Sarah" with Cinnamon using PB 5.43 x86 with both GTK 2 and GTK 3 and in ASCII and Unicode mode
    - Windows XP SP3 Professional with PB 5.43 x86 in ASCII and Unicode mode
    - Windows 8.1 x64 with PB 5.43 x86 and x64 in both ASCII and Unicode mode

Code: Select all

EnableExplicit

Define ImagePath.S

OpenWindow(0, 100, 100, 800, 600,
  "Drag the PureBasic logo onto the right ImageGadget")
WebGadget(0, 10, 10, 380, 580 ,"http://www.purebasic.com")
ImageGadget(1, 400, 10, 390, 290, 0, #PB_Image_Border)
EditorGadget(2, 400, 300, 390, 290)

EnableGadgetDrop(1, #PB_Drop_Image, #PB_Drag_Copy)

CompilerSelect #PB_Compiler_OS
  CompilerCase #PB_OS_Linux ; -------------------------------------------------
    ProcedureC DragDataCallback(*Widget.GtkWidget,
      *DragContext.GdkDragContext, x.I, y.I, *Data.GtkSelectionData, Info.I,
      Time.i, *UserData)
      Shared ImagePath.S

      If *Data
        If ImagePath = ""
          ImagePath = PeekS(gtk_selection_data_get_text_(*Data), -1, #PB_UTF8)
        EndIf
      EndIf
    EndProcedure

    g_signal_connect_(GadgetID(0), "drag-data-received", @DragDataCallback(), 0)
  CompilerCase #PB_OS_MacOS ; -------------------------------------------------
    Define SubclassedImageGadget.I

    Procedure SubclassGadget(GadgetID.I, NewClassName.S)
      Protected GadgetClass.I = CocoaMessage(0, GadgetID(GadgetID), "class")
      Protected NewGadgetClass.I

      NewGadgetClass = objc_allocateClassPair_(GadgetClass, NewClassName, 0)
      objc_registerClassPair_(NewGadgetClass)
      object_setClass_(GadgetID(GadgetID), NewGadgetClass)

      ProcedureReturn NewGadgetClass
    EndProcedure
    
    ProcedureC PrepareForDragOperation(Object.I, Selector.I, Sender.I)
      Shared ImagePath.S

      Protected Pasteboard.I
      Protected URL.I
      
      Pasteboard = CocoaMessage(0, Sender, "draggingPasteboard")
      URL = CocoaMessage(0, 0, "NSURL URLFromPasteboard:", Pasteboard)

      If URL
        ImagePath = PeekS(CocoaMessage(0,
          CocoaMessage(0, URL, "absoluteString"),
          "UTF8String"), -1, #PB_UTF8)
      EndIf

      ProcedureReturn #True
    EndProcedure

    SubclassedImageGadget = SubclassGadget(1, "SubclassedImageGadget")
    class_addMethod_(SubclassedImageGadget,
      sel_registerName_("prepareForDragOperation:"),
      @PrepareForDragOperation(), "v@:@")
  CompilerCase #PB_OS_Windows ; -----------------------------------------------
    Prototype AccessibleObjectFromPoint(Point.Q, *IAccessable, *VarChild)

    Define AccessibleObject.AccessibleObjectFromPoint
    Define CursorPos.POINT
    Define OLELib.I
    
    OLELib = OpenLibrary(#PB_Any,"OLEAcc.DLL")

    If OLELib
      AccessibleObject = GetFunction(OLELib, "AccessibleObjectFromPoint")
    Else
      MessageRequester("Error", "Loading of library OLEAcc.DLL failed!",
        #MB_ICONERROR)
      End
    EndIf
    
    Procedure ObjectFromPoint(x, y)
      Shared AccessibleObject.AccessibleObjectFromPoint
      Shared ImagePath.S

      Protected Name.I
      Protected *IAcc.IAccessible
      Protected Length.I
      Protected Path.S
      Protected VT.VARIANT

      If AccessibleObject(y << 32 | x, @*IAcc, @VT) = #S_OK
        If *IAcc\get_accValue(VT, @Name) = #S_OK
          Length = SysStringLen_(Name)
          Path = Space(Length)
          WideCharToMultiByte_(#CP_ACP, 0, Name, -1, @Path, Length, 0, 0)
          ImagePath = PeekS(@Path, Length, #PB_UTF8)
          SysFreeString_(Name)
        EndIf

        *IAcc\Release()
      EndIf

      ProcedureReturn #True
    EndProcedure
  CompilerEndSelect ; ---------------------------------------------------------

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    CompilerIf #PB_Compiler_OS = #PB_OS_Windows
      Case #WM_LBUTTONDOWN
        GetCursorPos_(@CursorPos.POINT)
        ObjectFromPoint(CursorPos\x, CursorPos\y)
    CompilerEndIf
    Case #PB_Event_GadgetDrop
      Select EventGadget()
        Case 1
          If EventDropImage(0)
            SetGadgetState(1, ImageID(0))
            AddGadgetItem(2, -1, ImagePath)
            ImagePath = ""
          EndIf
      EndSelect
  EndSelect
ForEver

CompilerIf #PB_Compiler_OS = #PB_OS_Windows
  CloseLibrary(OLELib)
CompilerEndIf

Re: Getting the html link when dropping an image from a webs

Posted: Thu Sep 29, 2016 10:38 pm
by Andre
Thanks a lot, guys! :mrgreen:

Both your latest examples work here on Windows x64.

Now I have a final wish: while embedding the WebGadget in the application is one site, it's also possible to get the html link of the image when dropping it from the website displayed in an external WebBrowser (e.g. FireFox)?

Re: Getting the html link when dropping an image from a webs

Posted: Fri Sep 30, 2016 5:24 am
by RASHAD
Hi Andre
It seems that we spent a lot of time while it is so simple :)
Cross platform PB x86,x64 Firefox v48
I just used PB WebGadget to display any image format no need to image decoder

Code: Select all

LoadFont(0,"Georgia",12)
If OpenWindow(0,0,0,800,600,"Drag with image!",#PB_Window_ScreenCentered|#PB_Window_SystemMenu) 
  WebGadget(0,10,10,450,580,"")
  EditorGadget(1,470,10,320,580)
  SetGadgetFont(1,FontID(0))
  AddGadgetItem(1,-1,"Drop here V :"+#CRLF$)
  
  EnableGadgetDrop(1,#PB_Drop_Text, #PB_Drag_Copy)
  Repeat 
    eventID = WaitWindowEvent() 
    Select eventID 
      Case #PB_Event_GadgetDrop 
        If EventGadget() = 1
          AddGadgetItem(1,-1,EventDropText())
          SetGadgetText(0, EventDropText())
        EndIf

  EndSelect 
  Until eventID = #PB_Event_CloseWindow 
EndIf
For your first request :P
Fred and freak now are laughing hard :wink:
No problem

Code: Select all

LoadFont(0,"Georgia",12)
If OpenWindow(0,0,0,800,600,"Drag with image!",#PB_Window_ScreenCentered|#PB_Window_SystemMenu) 
  WebGadget(0,10,10,300,580,"http://www.purebasic.com")
  EditorGadget(1,320,10,300,580)
  SetGadgetFont(1,FontID(0))
  AddGadgetItem(1,-1,"Drop here V :"+#CRLF$)
  
  WebGadget(2,620,20,160,580,"")
  
  EnableGadgetDrop(1,#PB_Drop_Text, #PB_Drag_Copy) 
  Repeat 
    eventID = WaitWindowEvent() 
    Select eventID 
      Case #PB_Event_GadgetDrop 
        If EventGadget() = 1
          AddGadgetItem(1,-1,EventDropText())
          SetGadgetText(2, EventDropText())
        EndIf

  EndSelect 
  Until eventID = #PB_Event_CloseWindow 
EndIf

Re: Getting the html link when dropping an image from a webs

Posted: Fri Sep 30, 2016 8:45 am
by Marc56us
Great! and simple :o I like! 8)

Juste need a way in sample 1 to avoid auto open filerequester "save/open image as/with" when drop :?: