protected void checkSubclass() { String name = getClass().getName(); String validName = DragSource.class.getName(); if (!validName.equals(name)) { DND.error(SWT.ERROR_INVALID_SUBCLASS); } }
/** * This implementation of <code>javaToNative</code> converts a list of file names represented by a * java <code>String[]</code> to a platform specific representation. Each <code>String</code> in * the array contains the absolute path for a single file or directory. For additional information * see <code>Transfer#javaToNative</code>. * * @param object a java <code>String[]</code> containing the file names to be converted * @param transferData an empty <code>TransferData</code> object; this object will be filled in on * return with the platform specific format of the data */ public void javaToNative(Object object, TransferData transferData) { if (!checkFile(object) || !isSupportedType(transferData)) { DND.error(DND.ERROR_INVALID_DATA); } String[] fileNames = (String[]) object; StringBuffer allFiles = new StringBuffer(); for (int i = 0; i < fileNames.length; i++) { allFiles.append(fileNames[i]); allFiles.append(CF_HDROP_SEPARATOR); // each name is null terminated } TCHAR buffer = new TCHAR( 0, allFiles.toString(), true); // there is an extra null terminator at the very end DROPFILES dropfiles = new DROPFILES(); dropfiles.pFiles = DROPFILES.sizeof; dropfiles.pt_x = dropfiles.pt_y = 0; dropfiles.fNC = 0; dropfiles.fWide = OS.IsUnicode ? 1 : 0; // Allocate the memory because the caller (DropTarget) has not handed it in // The caller of this method must release the data when it is done with it. int byteCount = buffer.length() * TCHAR.sizeof; int /*long*/ newPtr = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, DROPFILES.sizeof + byteCount); OS.MoveMemory(newPtr, dropfiles, DROPFILES.sizeof); OS.MoveMemory(newPtr + DROPFILES.sizeof, buffer, byteCount); transferData.stgmedium = new STGMEDIUM(); transferData.stgmedium.tymed = COM.TYMED_HGLOBAL; transferData.stgmedium.unionField = newPtr; transferData.stgmedium.pUnkForRelease = 0; transferData.result = COM.S_OK; }
/** * Adds the listener to the collection of listeners who will be notified when a drag and drop * operation is in progress, by sending it one of the messages defined in the <code> * DragSourceListener</code> interface. * * <p> * * <ul> * <li><code>dragStart</code> is called when the user has begun the actions required to drag the * widget. This event gives the application the chance to decide if a drag should be * started. * <li><code>dragSetData</code> is called when the data is required from the drag source. * <li><code>dragFinished</code> is called when the drop has successfully completed (mouse up * over a valid target) or has been terminated (such as hitting the ESC key). Perform * cleanup such as removing data from the source side on a successful move operation. * </ul> * * @param listener the listener which should be notified * @exception IllegalArgumentException * <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null * </ul> * * @exception SWTException * <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver * </ul> * * @see DragSourceListener * @see #getDragListeners * @see #removeDragListener * @see DragSourceEvent */ public void addDragListener(DragSourceListener listener) { if (listener == null) DND.error(SWT.ERROR_NULL_ARGUMENT); DNDListener typedListener = new DNDListener(listener); typedListener.dndWidget = this; addListener(DND.DragStart, typedListener); addListener(DND.DragSetData, typedListener); addListener(DND.DragEnd, typedListener); }
/** * Creates a new <code>DragSource</code> to handle dragging from the specified <code>Control * </code>. Creating an instance of a DragSource may cause system resources to be allocated * depending on the platform. It is therefore mandatory that the DragSource instance be disposed * when no longer required. * * @param control the <code>Control</code> that the user clicks on to initiate the drag * @param style the bitwise OR'ing of allowed operations; this may be a combination of any of * DND.DROP_NONE, DND.DROP_COPY, DND.DROP_MOVE, DND.DROP_LINK * @exception SWTException * <ul> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass * </ul> * * @exception SWTError * <ul> * <li>ERROR_CANNOT_INIT_DRAG - unable to initiate drag source; this will occur if more than * one drag source is created for a control or if the operating system will not allow * the creation of the drag source * </ul> * <p>NOTE: ERROR_CANNOT_INIT_DRAG should be an SWTException, since it is a recoverable error, * but can not be changed due to backward compatibility. * @see Widget#dispose * @see DragSource#checkSubclass * @see DND#DROP_NONE * @see DND#DROP_COPY * @see DND#DROP_MOVE * @see DND#DROP_LINK */ public DragSource(Control control, int style) { super(control, checkStyle(style)); this.control = control; if (control.getData(DND.DRAG_SOURCE_KEY) != null) { DND.error(DND.ERROR_CANNOT_INIT_DRAG); } control.setData(DND.DRAG_SOURCE_KEY, this); createCOMInterfaces(); this.AddRef(); controlListener = new Listener() { public void handleEvent(Event event) { if (event.type == SWT.Dispose) { if (!DragSource.this.isDisposed()) { DragSource.this.dispose(); } } if (event.type == SWT.DragDetect) { if (!DragSource.this.isDisposed()) { DragSource.this.drag(event); } } } }; control.addListener(SWT.Dispose, controlListener); control.addListener(SWT.DragDetect, controlListener); this.addListener( SWT.Dispose, new Listener() { public void handleEvent(Event e) { DragSource.this.onDispose(); } }); Object effect = control.getData(DEFAULT_DRAG_SOURCE_EFFECT); if (effect instanceof DragSourceEffect) { dragEffect = (DragSourceEffect) effect; } else if (control instanceof Tree) { dragEffect = new TreeDragSourceEffect((Tree) control); } else if (control instanceof Table) { dragEffect = new TableDragSourceEffect((Table) control); } }
/** * Removes the listener from the collection of listeners who will be notified when a drag and drop * operation is in progress. * * @param listener the listener which should no longer be notified * @exception IllegalArgumentException * <ul> * <li>ERROR_NULL_ARGUMENT - if the listener is null * </ul> * * @exception SWTException * <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver * </ul> * * @see DragSourceListener * @see #addDragListener * @see #getDragListeners */ public void removeDragListener(DragSourceListener listener) { if (listener == null) DND.error(SWT.ERROR_NULL_ARGUMENT); removeListener(DND.DragStart, listener); removeListener(DND.DragSetData, listener); removeListener(DND.DragEnd, listener); }