Перетащите файл .lnk на панель задач Windows 10 - PullRequest
2 голосов
/ 18 мая 2019

Как можно успешно перетащить файл .lnk на панель задач Windows 10 («Закрепить на панели задач»), используя Java и SWT?Я попробовал следующий код (перетаскивая содержимое метки), но независимо от того, какую константу операции я использую, он показывает курсор, не позволяющий перетаскивать курсор над панелью задач 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 Explorer работает нормально, поэтому файл правильный.

1 Ответ

2 голосов
/ 24 мая 2019

Обновление 11.07.19: текущие ночные сборки и следующий выпуск SWT улучшают FileTransfer для удаления файлов на панели задач Windows. Так что для SWT 4.13+ пример кода Томаса просто работает без дальнейших изменений.

Обходной путь для SWT 4.12 и старше:

В настоящее время ни один из типов передачи SWT не может быть использован для сброса на панели задач. Проблема в том, что FileTransfer использует CF_HDROP в качестве типа передаваемых данных, в то время как панель задач ожидает CFSTR_SHELLIDLIST .

См. Также этот отчет об ошибке хрома и отчет об ошибке SWT .

Чтобы показать, что 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 или другой тип) на этот пример, а затем перетащите его на панель задач, закрепление должно работать.

Таким образом, в конце концов, «единственное», что вам нужно сделать, это реализовать новый Transfer с CFSTR_SHELLIDLIST, который предоставляет данные в виде IDA из ITEMLISTS .

Небольшое обновление: Я протестировал это в Windows 7, но по любой причине идентификатор типа передачи является другим в Windows 10. Поэтому в моем примере выше вам нужно заменить идентификатор 49287 для Windows 7 на 49336 для Windows 10. Кстати, вы можете легко проверить эти идентификаторы с SWT Snippet 83 .

Как описано здесь правильный способ получения идентификатора типа - использование функции RegisterClipboardFormat.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...