Woo*_*III 5 outlook swt drag-and-drop
背景
我们的基于Eclipse RCP 3.6的应用程序允许人们拖动文件进行存储/处理.从文件系统拖动文件时,这种方法很有效,但是当人们直接从Outlook拖动项目(邮件或附件)时则不行.
这似乎是因为Outlook希望通过养活我们的应用程序的文件FileGroupDescriptorW和FileContents,但只SWT包括FileTransfer类型.(在FileTransfer,只有文件路径通过,并假设接收器可以找到并阅读.在FileGroupDescriptorW/ FileContents方法,而无需编写临时文件到磁盘可以提供文件直接应用到应用程序.)
我们试图生成一个ByteArrayTransfer可以接受FileGroupDescriptorW和的子类FileContents.基于Web上的一些示例,我们能够接收和解析FileGroupDescriptorW,(顾名思义)描述了可用于传输的文件.(见下面的代码草图.)但我们一直无法接受FileContents.
这似乎是因为Outlook FileContents仅将数据提供为TYMED_ISTREAM或TYMED_ISTORAGE,但SWT仅了解如何交换数据TYMED_HGLOBAL.其中,似乎TYMED_ISTORAGE更可取,因为不清楚如何TYMED_ISTREAM提供对多个文件内容的访问.
(我们也有一些担心SWT希望选择和转换只有一种TransferData类型,考虑到我们需要处理两种类型,但我们认为我们可能会以某种方式破解Java:似乎所有TransferDatas都可以在其他点上获得这个过程.)
问题
我们在这里走在正确的轨道上吗?有没有人设法接受FileContentsSWT呢?我们是否有可能在TYMED_ISTORAGE不离开Java的情况下处理数据(即使是通过创建基于片段的补丁或SWT的派生版本),还是我们还需要构建一些新的本机支持代码?
相关代码片段
提取文件名的草图代码:
// 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;
}
}
};
Run Code Online (Sandbox Code Playgroud)
在调试中,我们看到ByteArrayTransfer的isSupportedType()最终返回false了FileContents,因为下面的测试不通过(因为它的tymedIS 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;
Run Code Online (Sandbox Code Playgroud)
这段摘录org.eclipse.swt.internal.ole.win32.COM让我们对一个简单的解决方案感到不那么希望:
public static final int TYMED_HGLOBAL = 1;
//public static final int TYMED_ISTORAGE = 8;
//public static final int TYMED_ISTREAM = 4;
Run Code Online (Sandbox Code Playgroud)
谢谢.
小智 2
您看过https://bugs.eclipse.org/bugs/show_bug.cgi?id=132514吗?
此 bugzilla 条目附带了一个可能令人感兴趣的补丁(针对相当旧的 SWT 版本)。
| 归档时间: |
|
| 查看次数: |
1301 次 |
| 最近记录: |