michael@0: // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: michael@0: #ifndef BASE_BASE_DROP_TARGET_H_ michael@0: #define BASE_BASE_DROP_TARGET_H_ michael@0: michael@0: #include michael@0: michael@0: #include "base/ref_counted.h" michael@0: michael@0: struct IDropTargetHelper; michael@0: michael@0: // A DropTarget implementation that takes care of the nitty gritty michael@0: // of dnd. While this class is concrete, subclasses will most likely michael@0: // want to override various OnXXX methods. michael@0: // michael@0: // Because BaseDropTarget is ref counted you shouldn't delete it directly, michael@0: // rather wrap it in a scoped_refptr. Be sure and invoke RevokeDragDrop(m_hWnd) michael@0: // before the HWND is deleted too. michael@0: // michael@0: // This class is meant to be used in a STA and is not multithread-safe. michael@0: class BaseDropTarget : public IDropTarget { michael@0: public: michael@0: // Create a new BaseDropTarget associating it with the given HWND. michael@0: explicit BaseDropTarget(HWND hwnd); michael@0: virtual ~BaseDropTarget(); michael@0: michael@0: // When suspend is set to |true|, the drop target does not receive drops from michael@0: // drags initiated within the owning HWND. michael@0: // TODO(beng): (http://b/1085385) figure out how we will handle legitimate michael@0: // drag-drop operations within the same HWND, such as dragging michael@0: // selected text to an edit field. michael@0: void set_suspend(bool suspend) { suspend_ = suspend; } michael@0: michael@0: // IDropTarget implementation: michael@0: HRESULT __stdcall DragEnter(IDataObject* data_object, michael@0: DWORD key_state, michael@0: POINTL cursor_position, michael@0: DWORD* effect); michael@0: HRESULT __stdcall DragOver(DWORD key_state, michael@0: POINTL cursor_position, michael@0: DWORD* effect); michael@0: HRESULT __stdcall DragLeave(); michael@0: HRESULT __stdcall Drop(IDataObject* data_object, michael@0: DWORD key_state, michael@0: POINTL cursor_position, michael@0: DWORD* effect); michael@0: michael@0: // IUnknown implementation: michael@0: HRESULT __stdcall QueryInterface(const IID& iid, void** object); michael@0: ULONG __stdcall AddRef(); michael@0: ULONG __stdcall Release(); michael@0: michael@0: protected: michael@0: // Returns the hosting HWND. michael@0: HWND GetHWND() { return hwnd_; } michael@0: michael@0: // Invoked when the cursor first moves over the hwnd during a dnd session. michael@0: // This should return a bitmask of the supported drop operations: michael@0: // DROPEFFECT_NONE, DROPEFFECT_COPY, DROPEFFECT_LINK and/or michael@0: // DROPEFFECT_MOVE. michael@0: virtual DWORD OnDragEnter(IDataObject* data_object, michael@0: DWORD key_state, michael@0: POINT cursor_position, michael@0: DWORD effect); michael@0: michael@0: // Invoked when the cursor moves over the window during a dnd session. michael@0: // This should return a bitmask of the supported drop operations: michael@0: // DROPEFFECT_NONE, DROPEFFECT_COPY, DROPEFFECT_LINK and/or michael@0: // DROPEFFECT_MOVE. michael@0: virtual DWORD OnDragOver(IDataObject* data_object, michael@0: DWORD key_state, michael@0: POINT cursor_position, michael@0: DWORD effect); michael@0: michael@0: // Invoked when the cursor moves outside the bounds of the hwnd during a michael@0: // dnd session. michael@0: virtual void OnDragLeave(IDataObject* data_object); michael@0: michael@0: // Invoked when the drop ends on the window. This should return the operation michael@0: // that was taken. michael@0: virtual DWORD OnDrop(IDataObject* data_object, michael@0: DWORD key_state, michael@0: POINT cursor_position, michael@0: DWORD effect); michael@0: michael@0: // Return the drag identity. michael@0: static int32_t GetDragIdentity() { return drag_identity_; } michael@0: michael@0: private: michael@0: // Returns the cached drop helper, creating one if necessary. The returned michael@0: // object is not addrefed. May return NULL if the object couldn't be created. michael@0: static IDropTargetHelper* DropHelper(); michael@0: michael@0: // The data object currently being dragged over this drop target. michael@0: scoped_refptr current_data_object_; michael@0: michael@0: // A helper object that is used to provide drag image support while the mouse michael@0: // is dragging over the content area. michael@0: // michael@0: // DO NOT ACCESS DIRECTLY! Use DropHelper() instead, which will lazily create michael@0: // this if it doesn't exist yet. This object can take tens of milliseconds to michael@0: // create, and we don't want to block any window opening for this, especially michael@0: // since often, DnD will never be used. Instead, we force this penalty to the michael@0: // first time it is actually used. michael@0: static IDropTargetHelper* cached_drop_target_helper_; michael@0: michael@0: // The drag identity (id). An up-counter that increases when the cursor first michael@0: // moves over the HWND in a DnD session (OnDragEnter). 0 is reserved to mean michael@0: // the "no/unknown" identity, and is used for initialization. The identity is michael@0: // sent to the renderer in drag enter notifications. Note: the identity value michael@0: // is passed over the renderer NPAPI interface to gears, so use int32_t instead michael@0: // of int here. michael@0: static int32_t drag_identity_; michael@0: michael@0: // The HWND of the source. This HWND is used to determine coordinates for michael@0: // mouse events that are sent to the renderer notifying various drag states. michael@0: HWND hwnd_; michael@0: michael@0: // Whether or not we are currently processing drag notifications for drags michael@0: // initiated in this window. michael@0: bool suspend_; michael@0: michael@0: LONG ref_count_; michael@0: michael@0: DISALLOW_EVIL_CONSTRUCTORS(BaseDropTarget); michael@0: }; michael@0: michael@0: #endif // BASE_BASE_DROP_TARGET_H_