将 .lnk 文件拖到 Windows 10 任务栏
Drag a .lnk file to the Windows 10 taskbar
如何使用 Java 和 SWT 将 .lnk
文件成功拖到 Windows 10 任务栏 ("Pin to Taskbar")?我尝试了以下代码(拖动标签的内容),但无论我使用什么操作常量,它都会在 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 资源管理器中拖动文件可以正常工作,因此文件是正确的。
2019 年 7 月 11 日更新:当前的夜间构建和下一版本的 SWT 改进了 FileTransfer 以将文件拖放到 Windows 任务栏上。因此,对于 SWT 4.13+ Thomas 的示例代码无需进一步更改即可运行。
SWT 4.12 及更早版本的解决方法:
目前 none 的 SWT 传输类型可用于放置在任务栏上。问题是 FileTransfer 使用 CF_HDROP as transfer data type while the taskbar expects a CFSTR_SHELLIDLIST.
另请参阅此类似内容 chromium bug report and this 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 或其他类型)拖放到此示例上,然后将其拖到任务栏,固定应该会起作用。
所以最后 "only" 你需要做的事情是用 CFSTR_SHELLIDLIST
实现一个新的传输,它将数据提供为 IDA of ITEMLISTS.
小更新:
我在 Windows 7 上对此进行了测试,但出于某种原因,传输类型 ID 在 Windows 10 上是另一个。因此,在我上面的示例中,您需要将 ID 49287
替换为 Windows 7 with 49336
for Windows 10。顺便说一句,你可以用 SWT Snippet 83.
轻松检查这些 ID
如所述here获取类型 ID 的正确方法是使用 RegisterClipboardFormat 函数。
如何使用 Java 和 SWT 将 .lnk
文件成功拖到 Windows 10 任务栏 ("Pin to Taskbar")?我尝试了以下代码(拖动标签的内容),但无论我使用什么操作常量,它都会在 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 资源管理器中拖动文件可以正常工作,因此文件是正确的。
2019 年 7 月 11 日更新:当前的夜间构建和下一版本的 SWT 改进了 FileTransfer 以将文件拖放到 Windows 任务栏上。因此,对于 SWT 4.13+ Thomas 的示例代码无需进一步更改即可运行。
SWT 4.12 及更早版本的解决方法:
目前 none 的 SWT 传输类型可用于放置在任务栏上。问题是 FileTransfer 使用 CF_HDROP as transfer data type while the taskbar expects a CFSTR_SHELLIDLIST.
另请参阅此类似内容 chromium bug report and this 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 或其他类型)拖放到此示例上,然后将其拖到任务栏,固定应该会起作用。
所以最后 "only" 你需要做的事情是用 CFSTR_SHELLIDLIST
实现一个新的传输,它将数据提供为 IDA of ITEMLISTS.
小更新:
我在 Windows 7 上对此进行了测试,但出于某种原因,传输类型 ID 在 Windows 10 上是另一个。因此,在我上面的示例中,您需要将 ID 49287
替换为 Windows 7 with 49336
for Windows 10。顺便说一句,你可以用 SWT Snippet 83.
如所述here获取类型 ID 的正确方法是使用 RegisterClipboardFormat 函数。