本文介绍了我可以将项目从Outlook拖到我的SWT应用程序中吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景

我们基于Eclipse RCP 3.6的应用程序使人们可以拖入文件进行存储/处理.当从文件系统中拖动文件时,这种方法可以很好地工作,但当人们直接从Outlook中拖动项目(消息或附件)时,效果不佳.

Our Eclipse RCP 3.6-based application lets people drag files in for storage/processing. This works fine when the files are dragged from a filesystem, but not when people drag items (messages or attachments) directly from Outlook.

这似乎是因为Outlook希望通过FileGroupDescriptorWFileContents为我们的应用程序提供文件,但是SWT仅包含FileTransfer类型. (在FileTransfer中,仅传递文件路径,并假设接收方可以找到并读取它们.FileGroupDescriptorW/FileContents方法可以直接在应用程序之间提供文件,而无需将临时文件写出到文件中.磁盘.)

This appears to be because Outlook wants to feed our application the files via a FileGroupDescriptorW and FileContents, but SWT only includes a FileTransfer type. (In a FileTransfer, only the file paths are passed, with the assumption that the receiver can locate and read them. The FileGroupDescriptorW/FileContents approach can supply files directly application-to-application without writing temporary files out to disk.)

我们试图产生一个可以接受FileGroupDescriptorWFileContentsByteArrayTransfer子类.根据Web上的一些示例,我们能够接收和解析FileGroupDescriptorW,该文件(顾名思义)描述了可用于传输的文件. (请参见下面的代码草图.)但是我们无法接受FileContents.

We have tried to produce a ByteArrayTransfer subclass that could accept FileGroupDescriptorW and FileContents. Based on some examples on the Web, we were able to receive and parse the FileGroupDescriptorW, which (as the name implies) describes the files available for transfer. (See code sketch below.) But we have been unable to accept the FileContents.

这似乎是因为Outlook仅以TYMED_ISTREAMTYMED_ISTORAGE的形式提供FileContents数据,但是SWT仅理解如何以TYMED_HGLOBAL的形式交换数据.其中,TYMED_ISTORAGE似乎更可取,因为尚不清楚TYMED_ISTREAM如何提供对多个文件内容的访问.

This seems to be because Outlook offers the FileContents data only as TYMED_ISTREAM or TYMED_ISTORAGE, but SWT only understands how to exchange data as TYMED_HGLOBAL. Of those, it appears that TYMED_ISTORAGE would be preferable, since it's not clear how TYMED_ISTREAM could provide access to multiple files' contents.

(鉴于我们需要处理两种类型,我们还担心SWT只选择和转换一种TransferData类型的愿望,但我们认为我们可能会以某种方式在Java中解决: TransferData在该过程的其他位置可用.)

(We also have some concerns about SWT's desire to pick and convert only a single TransferData type, given that we need to process two, but we think we could probably hack around that in Java somehow: it seems that all the TransferDatas are available at other points of the process.)

问题

我们在这里正确吗?有没有人设法在SWT中接受FileContents?是否有可能在不离开Java的情况下处理TYMED_ISTORAGE数据(即使通过为SWT创建基于片段的补丁程序或SWT的派生版本)还是还是必须构建一些新的本机支持代码?

Are we on the right track here? Has anyone managed to accept FileContents in SWT yet? Is there any chance that we could process the TYMED_ISTORAGE data without leaving Java (even if by creating a fragment-based patch to, or a derived version of, SWT), or would we have to build some new native support code too?

相关代码段

提取文件名的素描代码:

Sketch code that extracts file names:

    // THIS IS NOT PRODUCTION-QUALITY CODE - FOR ILLUSTRATION ONLY
    final Transfer transfer = new ByteArrayTransfer() {
        private final String[] typeNames = new String[] { "FileGroupDescriptorW", "FileContents" };
        private final int[] typeIds = new int[] { registerType(typeNames[0]), registerType(typeNames[1]) };

        @Override
        protected String[] getTypeNames() {
            return typeNames;
        }

        @Override
        protected int[] getTypeIds() {
            return typeIds;
        }

        @Override
        protected Object nativeToJava(TransferData transferData) {
            if (!isSupportedType(transferData))
                return null;

            final byte[] buffer = (byte[]) super.nativeToJava(transferData);
            if (buffer == null)
                return null;

            try {
                final DataInputStream in = new DataInputStream(new ByteArrayInputStream(buffer));

                long count = 0;
                for (int i = 0; i < 4; i++) {
                    count += in.readUnsignedByte() << i;
                }

                for (int i = 0; i < count; i++) {
                    final byte[] filenameBytes = new byte[260 * 2];
                    in.skipBytes(72); // probable architecture assumption(s) - may be wrong outside standard 32-bit Win XP
                    in.read(filenameBytes);
                    final String fileNameIncludingTrailingNulls = new String(filenameBytes, "UTF-16LE");
                    int stringLength = fileNameIncludingTrailingNulls.indexOf('\0');
                    if (stringLength == -1)
                        stringLength = 260;
                    final String fileName = fileNameIncludingTrailingNulls.substring(0, stringLength);
                    System.out.println("File " + i + ": " + fileName);
                }

                in.close();

                return buffer;
            }
            catch (final Exception e) {
                return null;
            }
        }
    };

在调试器中,我们看到ByteArrayTransferisSupportedType()最终为FileContents返回false,因为未通过以下测试(因为其tymedTYMED_ISTREAM | TYMED_ISTORAGE):

In the debugger, we see that ByteArrayTransfer's isSupportedType() ultimately returns false for the FileContents because the following test is not passed (since its tymed is TYMED_ISTREAM | TYMED_ISTORAGE):

    if (format.cfFormat == types[i] &&
        (format.dwAspect & COM.DVASPECT_CONTENT) == COM.DVASPECT_CONTENT && 
        (format.tymed & COM.TYMED_HGLOBAL) == COM.TYMED_HGLOBAL  )
        return true;

摘录自org.eclipse.swt.internal.ole.win32.COM的内容使我们对寻求简单解决方案的希望减少了:

This excerpt from org.eclipse.swt.internal.ole.win32.COM leaves us feeling less hope for an easy solution:

public static final int TYMED_HGLOBAL = 1;
//public static final int TYMED_ISTORAGE = 8;
//public static final int TYMED_ISTREAM = 4;

谢谢.

推荐答案

您是否看过 https://bugs.eclipse.org/bugs/show_bug.cgi?id=132514 吗?

此bugzilla条目所附的是一个补丁(相对于SWT的较旧版本),可能是您感兴趣的补丁.

Attached to this bugzilla entry is an patch (against an rather old version of SWT) that might be of interest.

这篇关于我可以将项目从Outlook拖到我的SWT应用程序中吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-23 07:33