如何使用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资源管理器中拖动文件效果很好,因此文件正确。
答案 0 :(得分:2)
目前,SWT的传输类型均不能用于放置在任务栏上。问题在于FileTransfer使用CF_HDROP作为传输数据类型,而任务栏期望使用CFSTR_SHELLIDLIST。
另请参阅类似的chromium bug report和此SWT bug report。
为了表明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
实现新的Transfer,它以IDA中ITEMLISTS的形式提供数据。
小更新:
我在Windows 7上对此进行了测试,但是无论出于何种原因,传输类型ID在Windows 10上都是另一个。因此,在上面的示例中,您需要将Windows 7的ID 49287
替换为Windows 10的49336
。您可以使用SWT Snippet 83轻松检查这些ID。
如here所述,获取类型ID的正确方法是使用RegisterClipboardFormat函数。