怎么从剪贴板获取复制的Outlook邮件/附件,保存为文件
如何从剪贴板获取复制的Outlook邮件/附件,保存为文件?
目前我正在设计一个申请系统,需要用户将审批邮件和附件关联到对应申请表单,上传到系统中。
系统是通过FTP上传文件的,使用idFTP控件。目前我只能使用OpenDialog,用户将邮件另存为文件,然后在系统中点击按钮,浏览选中该文件,然后上传。这样就多了一个把邮件另存为文件的动作,用户抵触很大。
我希望做到的是,在Outlook选中邮件或者附件->Ctrl+C复制->在系统中Ctrl+V(或者点按钮),系统自动识别,然后从剪贴板获取文件流,上传到FTP。
现在主要问题卡在文件流的获取上面。
以下测试代码:
当选择邮件或者附件时,运行结果:
49161 DataObject
49453 FileGroupDescriptorW
49452 FileGroupDescriptor
49711 RenPrivateItem
49451 FileContents
49171 Ole Private Data
经查,FileGroupDescriptorW可以表明剪贴板中有此类文件。但是问题来了:
1,这个代码49453居然是会变的,昨天是这个,今天开机测试,又变49464了。对于VB,可以用Clipboard.ContainsData("FileGroupDescriptor")来判断;但是Delphi应该如何用格式名称来获取对应的代码,并判断是否存在?我目前只能通过遍历剪贴板中所有格式的名称是否有"FileGroupDescriptorW"来判断;
2,如果有FileGroupDescriptorW格式,该如何从剪贴板中获取到对应的文件流?该如何从文件流中获取文件名/文件格式信息,以便保存为对应格式文件?
3,如何让窗体本身接受Ctrl+V事件并在事件发生时,进行指定操作?我如下代码不起作用:
请大家多多指教,非常感谢!
参考:VB版:http://social.msdn.microsoft.com/Forums/vstudio/en-US/affcf9cd-704d-4ea2-b80b-4c09062af72d/how-extract-an-outlook-attachment-from-the-clipboard-?forum=wpf
C#版:http://*.com/questions/11041005/getting-multiple-outlook-attachments-from-clipboard
------解决方案--------------------
俺也没做过此类应用,稍微帮你搜了搜,具体得自己查MSDN
http://www.delphigroups.info/2/5d/414002.html
shlobj 单元中的 IDataObject 接口提供了QueryGetData方法,通过QueryGetData可以获取到一个FileGroupDescriptor 文件组描述结构体的指针,由此来判断
3,如何让窗体本身接受Ctrl+V事件并在事件发生时,进行指定操作?
可以对该窗体定义热键ctrl+v,当该热键按下时做处理
MSDN中也提供了一个综合各种剪贴板操作的示例
目前我正在设计一个申请系统,需要用户将审批邮件和附件关联到对应申请表单,上传到系统中。
系统是通过FTP上传文件的,使用idFTP控件。目前我只能使用OpenDialog,用户将邮件另存为文件,然后在系统中点击按钮,浏览选中该文件,然后上传。这样就多了一个把邮件另存为文件的动作,用户抵触很大。
我希望做到的是,在Outlook选中邮件或者附件->Ctrl+C复制->在系统中Ctrl+V(或者点按钮),系统自动识别,然后从剪贴板获取文件流,上传到FTP。
现在主要问题卡在文件流的获取上面。
以下测试代码:
procedure TForm1.btn1Click(Sender: TObject);
var
P:PWideChar;
i:Integer;
begin
txt1.Clear; //txt1是一个mmotext
if Clipboard.FormatCount>0 then
try
Clipboard.Open;
for i := 0 to Clipboard.FormatCount-1 do
begin
GetClipboardFormatName(Clipboard.Formats[i],P,255);
txt1.Lines.Add(IntToStr(Clipboard.Formats[i]) + #9 + P); //剪贴板格式代码+格式注册名称
end;
finally
Clipboard.Close;
end;
end;
当选择邮件或者附件时,运行结果:
49161 DataObject
49453 FileGroupDescriptorW
49452 FileGroupDescriptor
49711 RenPrivateItem
49451 FileContents
49171 Ole Private Data
经查,FileGroupDescriptorW可以表明剪贴板中有此类文件。但是问题来了:
1,这个代码49453居然是会变的,昨天是这个,今天开机测试,又变49464了。对于VB,可以用Clipboard.ContainsData("FileGroupDescriptor")来判断;但是Delphi应该如何用格式名称来获取对应的代码,并判断是否存在?我目前只能通过遍历剪贴板中所有格式的名称是否有"FileGroupDescriptorW"来判断;
2,如果有FileGroupDescriptorW格式,该如何从剪贴板中获取到对应的文件流?该如何从文件流中获取文件名/文件格式信息,以便保存为对应格式文件?
3,如何让窗体本身接受Ctrl+V事件并在事件发生时,进行指定操作?我如下代码不起作用:
private
procedure WMPaste(var Message: TMessage); message WM_PASTE;
procedure TForm1.WMPaste(var Message: TMessage);
var
S:string;
i,NumFiles:Integer;
DataHandle: THandle;
buffer: Array [0..MAX_PATH] of Char;
begin
if IsClipboardFormatAvailable(CF_HDROP) then
begin
Clipboard.Open;
try
DataHandle:=Clipboard.GetAsHandle(CF_HDROP);
If DataHandle<>0 Then
Begin
NumFiles:=DragQueryFile(DataHandle,$FFFFFFFF, nil,0);
for i:= 0 to NumFiles - 1 do
begin
buffer[0] := #0;
DragQueryFile(DataHandle,i,buffer,sizeof(buffer));
ShowMessage(buffer);
end;
end;
finally
Clipboard.close;
end;
end;
end;
请大家多多指教,非常感谢!
参考:VB版:http://social.msdn.microsoft.com/Forums/vstudio/en-US/affcf9cd-704d-4ea2-b80b-4c09062af72d/how-extract-an-outlook-attachment-from-the-clipboard-?forum=wpf
C#版:http://*.com/questions/11041005/getting-multiple-outlook-attachments-from-clipboard
------解决方案--------------------
俺也没做过此类应用,稍微帮你搜了搜,具体得自己查MSDN
http://www.delphigroups.info/2/5d/414002.html
shlobj 单元中的 IDataObject 接口提供了QueryGetData方法,通过QueryGetData可以获取到一个FileGroupDescriptor 文件组描述结构体的指针,由此来判断
3,如何让窗体本身接受Ctrl+V事件并在事件发生时,进行指定操作?
可以对该窗体定义热键ctrl+v,当该热键按下时做处理
MSDN中也提供了一个综合各种剪贴板操作的示例
Example of a Clipboard Viewer
The following example shows a simple clipboard viewer application.
HINSTANCE hinst;
UINT uFormat = (UINT)(-1);
BOOL fAuto = TRUE;
LRESULT APIENTRY MainWndProc(hwnd, uMsg, wParam, lParam)
HWND hwnd;
UINT uMsg;
WPARAM wParam;
LPARAM lParam;
{
static HWND hwndNextViewer;
HDC hdc;
HDC hdcMem;
PAINTSTRUCT ps;
LPPAINTSTRUCT lpps;
RECT rc;
LPRECT lprc;
HGLOBAL hglb;
LPSTR lpstr;
HBITMAP hbm;
HENHMETAFILE hemf;
HWND hwndOwner;
switch (uMsg)
{
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
// Branch depending on the clipboard format.
switch (uFormat)