diff --git a/samples/dnd/dnd.cpp b/samples/dnd/dnd.cpp index 1009775055..97d9afb108 100644 --- a/samples/dnd/dnd.cpp +++ b/samples/dnd/dnd.cpp @@ -95,11 +95,15 @@ public: void OnNewFrame(wxCommandEvent& event); void OnHelp (wxCommandEvent& event); void OnLogClear(wxCommandEvent& event); + void OnCopy(wxCommandEvent& event); void OnPaste(wxCommandEvent& event); + void OnCopyBitmap(wxCommandEvent& event); void OnPasteBitmap(wxCommandEvent& event); + void OnCopyFiles(wxCommandEvent& event); + void OnLeftDown(wxMouseEvent& event); void OnRightDown(wxMouseEvent& event); @@ -577,8 +581,7 @@ enum Menu_Paste, Menu_CopyBitmap, Menu_PasteBitmap, - Menu_ToBeGreyed, /* for testing */ - Menu_ToBeDeleted, /* for testing */ + Menu_CopyFiles, Menu_Shape_New = 500, Menu_Shape_Edit, Menu_Shape_Clear, @@ -598,6 +601,7 @@ BEGIN_EVENT_TABLE(DnDFrame, wxFrame) EVT_MENU(Menu_Paste, DnDFrame::OnPaste) EVT_MENU(Menu_CopyBitmap, DnDFrame::OnCopyBitmap) EVT_MENU(Menu_PasteBitmap,DnDFrame::OnPasteBitmap) + EVT_MENU(Menu_CopyFiles, DnDFrame::OnCopyFiles) EVT_UPDATE_UI(Menu_Paste, DnDFrame::OnUpdateUIPasteText) EVT_UPDATE_UI(Menu_PasteBitmap, DnDFrame::OnUpdateUIPasteBitmap) @@ -702,6 +706,8 @@ DnDFrame::DnDFrame(wxFrame *frame, char *title, int x, int y, int w, int h) clip_menu->AppendSeparator(); clip_menu->Append(Menu_CopyBitmap, "&Copy bitmap\tAlt+C"); clip_menu->Append(Menu_PasteBitmap, "&Paste bitmap\tAlt+V"); + clip_menu->AppendSeparator(); + clip_menu->Append(Menu_CopyFiles, "&Copy files\tCtrl+F"); wxMenuBar *menu_bar = new wxMenuBar; menu_bar->Append(file_menu, "&File"); @@ -897,18 +903,13 @@ void DnDFrame::OnLeftDown(wxMouseEvent &WXUNUSED(event) ) void DnDFrame::OnRightDown(wxMouseEvent &event ) { - wxMenu *menu = new wxMenu; + wxMenu menu("Dnd sample menu"); - menu->Append(Menu_Drag, "&Test drag..."); - menu->Append(Menu_About, "&About"); - menu->Append(Menu_Quit, "E&xit"); - menu->Append(Menu_ToBeDeleted, "To be deleted"); - menu->Append(Menu_ToBeGreyed, "To be greyed"); + menu.Append(Menu_Drag, "&Test drag..."); + menu.AppendSeparator(); + menu.Append(Menu_About, "&About"); - menu->Delete( Menu_ToBeDeleted ); - menu->Enable( Menu_ToBeGreyed, FALSE ); - - PopupMenu( menu, event.GetX(), event.GetY() ); + PopupMenu( &menu, event.GetX(), event.GetY() ); } DnDFrame::~DnDFrame() @@ -1024,6 +1025,50 @@ void DnDFrame::OnPasteBitmap(wxCommandEvent& WXUNUSED(event)) wxTheClipboard->Close(); } +// ---------------------------------------------------------------------------- +// file clipboard +// ---------------------------------------------------------------------------- + +void DnDFrame::OnCopyFiles(wxCommandEvent& WXUNUSED(event)) +{ +#ifdef __WXMSW__ + wxFileDataObject *dobj = new wxFileDataObject; + + wxFileDialog dialog(this, "Select a file to copy", "", "", + "All files (*.*)|*.*", 0); + + if ( dialog.ShowModal() == wxID_OK ) + { + wxString filename = dialog.GetPath(); + dobj->AddFile(filename); + + wxClipboardLocker locker; + if ( !locker ) + { + wxLogError("Can't open clipboard"); + } + else + { + if ( !wxTheClipboard->AddData(dobj) ) + { + wxLogError("Can't copy file to the clipboard"); + } + else + { + wxLogStatus(this, "File '%s' copied to the clipboard", + filename.c_str()); + } + } + } + else + { + wxLogStatus(this, "Aborted"); + } +#else // !MSW + wxLogError("Sorry, not implemented"); +#endif // MSW/!MSW +} + // --------------------------------------------------------------------------- // text clipboard // --------------------------------------------------------------------------- diff --git a/src/msw/clipbrd.cpp b/src/msw/clipbrd.cpp index ba954e8263..6b93ebf988 100644 --- a/src/msw/clipbrd.cpp +++ b/src/msw/clipbrd.cpp @@ -483,7 +483,9 @@ bool wxClipboard::IsOpened() const bool wxClipboard::SetData( wxDataObject *data ) { +#if !wxUSE_OLE_CLIPBOARD (void)wxEmptyClipboard(); +#endif // wxUSE_OLE_CLIPBOARD if ( data ) return AddData(data); diff --git a/src/msw/ole/dataobj.cpp b/src/msw/ole/dataobj.cpp index 492023bdd2..21eae48819 100644 --- a/src/msw/ole/dataobj.cpp +++ b/src/msw/ole/dataobj.cpp @@ -433,6 +433,19 @@ STDMETHODIMP wxIDataObject::SetData(FORMATETC *pformatetc, case TYMED_HGLOBAL: { + wxDataFormat format = pformatetc->cfFormat; + + // this is quite weird, but for file drag and drop, explorer + // calls our SetData() with the formats we do *not* support! + // + // as we can't fix this bug in explorer (it's a bug because it + // should only use formats returned by EnumFormatEtc), do the + // check here + if ( !m_pDataObject->IsSupportedFormat(format) ) { + // go away! + return DV_E_FORMATETC; + } + // copy data void *pBuf = GlobalLock(pmedium->hGlobal); if ( pBuf == NULL ) { @@ -447,7 +460,7 @@ STDMETHODIMP wxIDataObject::SetData(FORMATETC *pformatetc, // synthetise it for known formats and we suppose that all data // in custom formats starts with a DWORD containing the size size_t size; - switch ( pformatetc->cfFormat ) + switch ( format ) { case CF_TEXT: case CF_OEMTEXT: @@ -480,7 +493,6 @@ STDMETHODIMP wxIDataObject::SetData(FORMATETC *pformatetc, } } - wxDataFormat format = pformatetc->cfFormat; bool ok = m_pDataObject->SetData(format, size, pBuf); GlobalUnlock(pmedium->hGlobal); @@ -928,6 +940,8 @@ bool wxFileDataObject::SetData(size_t WXUNUSED(size), const void *pData) // get number of files (magic value -1) UINT nFiles = ::DragQueryFile(hdrop, (unsigned)-1, NULL, 0u); + wxCHECK_MSG ( nFiles != (UINT)-1, FALSE, wxT("wrong HDROP handle") ); + // for each file get the length, allocate memory and then get the name wxString str; UINT len, n;