Java 将.lnk文件拖动到Windows 10任务栏

Java 将.lnk文件拖动到Windows 10任务栏,java,windows,drag-and-drop,swt,Java,Windows,Drag And Drop,Swt,如何使用Java和SWT将.lnk文件成功拖动到Windows 10任务栏(“固定到任务栏”)上?我尝试了以下代码(拖动标签的内容),但无论我使用什么操作常量,它都会在Windows 10任务栏上显示“不允许拖动”光标 import org.eclipse.swt.*; import org.eclipse.swt.dnd.*; import org.eclipse.swt.layout.*; import org.eclipse.swt.widgets.*; public class Dra

如何使用Java和SWT将
.lnk
文件成功拖动到Windows 10任务栏(“固定到任务栏”)上?我尝试了以下代码(拖动标签的内容),但无论我使用什么操作常量,它都会在Windows 10任务栏上显示“不允许拖动”光标

import org.eclipse.swt.*;
import org.eclipse.swt.dnd.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;

public class DragTest {

    public static void main(String[] args) {
        final Display display = new Display();
        final Shell shell = new Shell(display);
        shell.setLayout(new FillLayout());
        final Label label = new Label(shell, SWT.BORDER);
        label.setText("Start drag from here");

        final Transfer[] types = new Transfer[] {FileTransfer.getInstance()};
        final int operations = DND.DROP_LINK; // DND.DROP_COPY or DND.DROP_MOVE

        final DragSource source = new DragSource(label, operations);
        source.setTransfer(types);
        source.addListener(DND.DragSetData, 
                           event -> event.data = new String[] { 
                                "C:\\ThunderbirdPortable\\ThunderbirdPortable - Shortcut.lnk"
                           });

        shell.setSize(200, 200);
        shell.open();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
        display.dispose();
    }
}

请注意,从Windows资源管理器中拖动文件可以正常工作,因此文件是正确的。

更新11.07.19:当前的夜间版本和下一版本的SWT改进了文件传输,可以将文件放到Windows任务栏上。因此,对于SWT4.13+Thomas的示例代码,无需进一步修改即可正常工作

SWT 4.12及更高版本的解决方案:

目前,SWT的任何传输类型都不能用于将其放到任务栏上。问题是FileTransfer使用作为传输数据类型,而任务栏需要一个

另请参见此类似和此

为了显示SWT通常可以放到任务栏上,我修改了您的示例

import org.eclipse.swt.*;
import org.eclipse.swt.dnd.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;

public class DragTransferTest {

    public static void main(String[] args) {
        final Display display = new Display();
        final Shell shell = new Shell(display);
        shell.setLayout(new FillLayout());
        final Label label = new Label(shell, SWT.BORDER);
        label.setText("Drop file here to start");

        final Transfer[] types = new Transfer[] { new ByteArrayTransfer() {

            byte[] lastDrop;

            @Override
            protected Object nativeToJava(TransferData transferData) {
                byte[] data = (byte[]) super.nativeToJava(transferData);
                lastDrop = data;
                return null;
            }

            @Override
            protected void javaToNative(Object object, TransferData transferData) {
                if (lastDrop == null) {
                    DND.error(DND.ERROR_INVALID_DATA);
                }
                super.javaToNative(lastDrop, transferData);
            };

            @Override
            protected String[] getTypeNames() {
                return new String[] { "Shell IDList Array" };
            }

            @Override
            protected int[] getTypeIds() {
                return new int[] { registerType("Shell IDList Array") };
            }
        } };
        final int operations = DND.DROP_LINK | DND.DROP_COPY | DND.DROP_MOVE;

        final DragSource source = new DragSource(label, operations);
        source.setTransfer(types);

        DropTarget target = new DropTarget(label, -1);
        target.setTransfer(types);

        shell.setSize(200, 200);
        shell.open();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
        display.dispose();
    }
}
如果您将一个文件(.lnk或其他类型)放到本例中,然后将其拖动到任务栏上,固定应该可以工作

因此,最后,您需要做的“唯一”事情是使用
CFSTR_SHELLIDLIST
实现一个新的传输,该传输将数据作为一个of

小更新: 我在Windows7上测试了这个,但是由于任何原因,传输类型id在Windows10上是另一个。因此,在我上面的示例中,您需要将Windows 7的ID
49287
替换为Windows 10的
49336
。顺便说一句,你可以很容易地检查这些ID与


如上所述,获取类型ID的正确方法是使用RegisterClipboardFormat函数。

这里有什么问题?你有什么例外吗?没有,我只是得到一个不允许拖动的光标。我需要改变什么才能让它工作?其他任务栏功能在SWT中通过实际调用平台函数实现。例如,任务项的进度动画位于org.eclipse.swt.widgets.TaskItem.setProgress(int)中。也许你可以在那里挖掘,找到一种不用拖放就能实现的方法。完美的答案!