• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 338
  • Last Modified:

Can't get a drop target to accept drag-and-drop from Opera browser

Opera supports drag-and-drop of URLs from the address bar to the desktop. I have not been able to build an app that works as a drop target for drag-and-drop from Opera. Code that works for IE and Firefox doesn't work for Opera.

Among other things, I have tried using the open source utility ClipSpy (http://www.codeproject.com/clipboard/clipspy.asp) which does work as a drop target for IE and Firefox, but shows a "disallowed" cursor (barred circle) when you try to drop a URL from Opera on its target panel.

At minimum, I need an explanation of why I'm seeing this behavior. Ideally, I would like code that works with Opera, perhaps by modifying ClipSpy so that it accepts (and displays) a URL dropped on it from Opera.

Thanks,

--Steve
0
sklein
Asked:
sklein
  • 5
  • 4
  • 4
1 Solution
 
bastibartelCommented:
Hi there,

hyperlinks do not work with std. droptargets as files do.
Try this though

You need an object derived from COleDropTarget  as member of your dialog class. This COleDropTarget
will accept hyperlinks as drops, if a couple of member functions are defined.

//###################
// In your Dlg class you add a variable:
CMyOleDropTarget m_DropTarget;

// In OnInitDialog of your Dlg class you add
m_DropTarget.Register( this );


//##############################
//## Class Definition of my CMyOleDropTarget
//##############################
#include <afxole.h> // if I remember correctly

class CMyOleDropTarget : public COleDropTarget
{
public:
      CMyOleDropTarget() {;}

      BOOL            OnDrop(CWnd* pWnd, COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point );
      DROPEFFECT      OnDragEnter(CWnd* pWnd, COleDataObject* pDataObject, DWORD dwKeyState, CPoint point );
      DROPEFFECT      OnDragOver(CWnd* pWnd, COleDataObject* pDataObject, DWORD dwKeyState, CPoint point );
};

//##############################
//## Implementation of my CMyOleDropTarget
//##############################

BOOL CMyOleDropTarget::OnDrop(CWnd* pWnd, COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point )
{
      STGMEDIUM r;
      BOOL fRet= pDataObject->GetData(CF_TEXT, &r );
      HGLOBAL hGlob= pDataObject->GetGlobalData( CF_TEXT );
      LPCSTR lpsz= (LPCSTR)GlobalLock( hGlob );
      GlobalUnlock( hGlob );
      
      AfxMessageBox( lpsz ); // debugging
      return( TRUE );
}

DROPEFFECT CMyOleDropTarget::OnDragEnter(CWnd* pWnd, COleDataObject* pDataObject, DWORD dwKeyState, CPoint point )
{
      STGMEDIUM r;
      BOOL fRet= pDataObject->IsDataAvailable(CF_TEXT );
      return( DROPEFFECT_COPY);
}

DROPEFFECT CMyOleDropTarget::OnDragOver(CWnd* pWnd, COleDataObject* pDataObject, DWORD dwKeyState, CPoint point )
{
      return( DROPEFFECT_COPY);
}


Cheers
Sebastian
0
 
bastibartelCommented:
Hi  sklein,

Have you found my code to be useful to you or do you have additional questions ?

Cheers,
Sebastian
0
 
bastibartelCommented:
Hi sklein,
 :-(
0
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

 
skleinAuthor Commented:
Sebastian--

Your example code appears to be equivalent to the implementation in ClipSpy. Here are the relevant bits extracted from LeftView.cpp:

class CLeftView : public CListView
{
...
// Implementation
...
protected:
    COleDropTarget m_drop;              // makes the list a drop target
...
}

void CLeftView::OnInitialUpdate()
{
    ...
    // Register the list control as a drop target.
    m_drop.Register ( this );
    ...
}

DROPEFFECT CLeftView::OnDragEnter(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
{
    ...
    return DROPEFFECT_COPY;
}

The ClipSpy project works great for dragging and dropping URLs from IE and Firefox, but not for Opera.

I put a breakpoint in CLeftView::OnDragEnter(). I get the break when dragging from Explorer, IE, or Firefox, but not for Opera. I can drag from the Opera address bar to the desktop. Thoughts?

--Steve
0
 
bastibartelCommented:
Hi sklein,

This was a solution from a previous EE question.
I don't have Opera myself and never tested it - sry, I couldn't help you.

Cheers,
Sebastian
0
 
DanRollinsCommented:
You will need to know exactly what format is being used by Opera.  I don't have that browser, so I can't test it, but it should be easy for you to do.  In your OnDragEnter handler, make a call to EnumClipboardFormats to learn exactly what Operas has put in there.

    EnumClipboardFormats Function
    http://msdn.microsoft.com/library/en-us/winui/winui/windowsuserinterface/dataexchange/clipboard/clipboardreference/clipboardfunctions/enumclipboardformats.asp

You should find one of these:
   Clipboard Formats
   http://msdn.microsoft.com/library/en-us/winui/winui/windowsuserinterface/dataexchange/clipboard/clipboardformats.asp

It could be a CF_HDROP or something else (maybe a "rivate" format -- who knows with non-microsoft software? :-)  But once you know what it uses, change the code above in the places where it looks for CF_TEXT to look for that format.
0
 
skleinAuthor Commented:
Sebastian--

Thanks for giving it a go.

--Steve
0
 
skleinAuthor Commented:
Dan--

An interesting suggestion,except that the OnDragEnter event handler is not being called at all if the drag source is Opera (but it is for IE, Firefox, Explorer). Yet clearly Opera is initiating a drag, since the cursor changes and I can drop from Opera to the desktop. When I try to drag over my app (or ClipSpy) I get the barred circle. So somehow the target is rejecting the dragover. Is there somewhere other than OnDragEnter or OnDragOver that can reject the drag target "accept"???

--Steve
0
 
bastibartelCommented:
Hi sklein,

BTW, the code you have quoted is not at all the same as the one I posted.

In your example you are using CView::OnDragEnter
My code uses COleDropTarget::OnDragEnter.

Have you tried the COleDropTarget subclassing appraoch ?

Cheers,
Sebastian
0
 
DanRollinsCommented:
Are you 100% certain that OnDragEnter is not being called (or are you relying on the cursor appearance?)  Place a breakpoint or a MessageBox there to be certain.

I've been searching the Web and it does appear that Opera's handling of Drag and Drop is rather unusual -- the fact the ClipSpy does not handle it is an important clue in that regard.  I'll keep looking to see if I can find anything more specific.  It may be a security issue... there are several known exploits related to dragging and perhaps the authors of Opera have avoided those by some unusual methods.
0
 
DanRollinsCommented:
This discussion indicates the unusual handling:  You can drag to the desktop only (or within Opera) but Operat itself is rejecting drops on anything else.

    http://my.opera.com/community/forums/topic.dml?id=138677

These guys suggest dropping it on the dektop then dragging it again to the desired target.  I doubt if they'd even consider that if there were a more natural way.

Improvement in Operar Drag-and=drop are high on the "wish list" and the current limits are discussed here:
     http://my.opera.com/community/forums/topic.dml?id=135056

So.. the answer is:  "It can't be done by Opera."  

There is some chance that it is possible to an Opera Plugin to help make it happen, but that is outside of the realm of this question.
0
 
skleinAuthor Commented:
Sorry for the delay. I'm 100% positive that OnDragEnter is not being called.

The really interesting thing is that if Opera is using DoDragDrop(), the IDropSource interface doesn't appear to allow you to "decline" a drop target. Perhaps the answer is that they don't use DoDragDrop() and "rolled their own".
0
 
DanRollinsCommented:
That appears to the the valid assessment.  The Opera forums were filled with chatter about how the code needed to remain platform-neutral.  Presumably the Windows mechanism of querying each potential drop target is not standard on other platforms, or if it is, then it is done in a substantially different way and the programmers did not want bifurcate the codebase so they used a simpler "mouse-capture-until-over-a-recognized-target" technique.

Thanks for the points and the grade :-)

-- Dan
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: Certified Penetration Testing

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

  • 5
  • 4
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now