起步软件技术论坛-X3

 找回密码
 立即注册
搜索
查看: 265|回复: 4

关于OLE容器的SaveAsDocument的问题[请求]

[复制链接]
发表于 2007-4-23 14:58:51 | 显示全部楼层 |阅读模式
使用 二进制流\表现OLE\非结构化 的方式上传附件,此时库中保存的文件应该是 源文件+OLE信息,此时用OLE方式浏览、修改文档都没有问题(包括word、xls、bmp、jpg等等)。
可是有时候用户也需要把此文档下载到本地使用,我用了论坛中提到的SaveAsDocument来实现,结果只有Word文档下载正常,xls文件只有在DoVerb时,保存出来才正常,其它的一律不正常,就是说SaveAsDocument并没有把原来的文件从OLE流中分离出来。

1、请问是不是我对SaveAsDocument的理解有问题?
2、麻烦给出以上问题的解决方法,谢谢!(注:为了表现上的需要,必须使用OLE表现)
回复

使用道具 举报

发表于 2007-4-23 15:28:48 | 显示全部楼层
procedure TOleContainer.SaveAsDocument(const FileName: string);
var
  TempStorage: IStorage;
  PersistStorage: IPersistStorage;
begin
  CheckObject;
  if FModSinceSave then SaveObject;
  FOleObject.QueryInterface(IPersistStorage, PersistStorage);
  if PersistStorage <> nil then
  begin
    OleCheck(StgCreateDocFile(PWideChar(WideString(Filename)), STGM_READWRITE
      or STGM_SHARE_EXCLUSIVE or STGM_CREATE, 0, TempStorage));
    OleCheck(OleSave(PersistStorage, TempStorage, False));
    PersistStorage.SaveCompleted(nil);
  end;
end;

StgCreateDocfile
Creates a new storage object using the OLE-provided compound file implementation for the IStorage interface.

HRESULT StgCreateDocfile(

    const WCHAR * pwcsName,         //Points to pathname of compound file to create
    DWORD grfMode,         //Specifies the access mode for opening the storage object
    DWORD reserved,         //Reserved; must be zero
    IStorage ** ppstgOpen        //Points to location for returning the new storage object
   );       
Parameters

pwcsName

Points to the pathname of the compound file to create. Passed uninterpreted to the file system. This can be a relative name or NULL. If NULL, a temporary compound file is allocated with a unique name.

grfMode

Specifies the access mode to use when opening the new storage object. For more information, see the STGM enumeration.

reserved

Reserved for future use; must be zero.

ppstgOpen

Points to the location where the new storage object is placed.

Return Values

S_OK

Indicates the compound file was successfully created.

STG_E_ACCESSDENIED

Indicates the calling process does not have sufficient access. Attempt to open file with conflicting permissions to a simultaneous open.

STG_E_FILEALREADYEXISTS

Indicates the compound file already exists and grfMode is set to STGM_FAILIFTHERE.

STG_S_CONVERTED

Indicates the specified file was successfully converted to Storage format.

STG_E_INSUFFICIENTMEMORY

Indicates the compound file was not created due to a lack of memory.

STG_E_INVALIDNAME

Indicates bad name in the pwcsName parameter.

STG_E_INVALIDPOINTER

Indicates bad pointer in the pwcsName parameter or the ppStgOpen parameter.

STG_E_INVALIDFLAG

Indicates bad flag combination in the grfMode pointer.

STG_E_TOOMANYOPENFILES

Indicates the compound file was not created due to a lack of file handles.

See also any file system errors for other error return values.

Comments

This function creates a new storage object using the OLE-provided, compound-file implementation for the IStorage interface. The name of the open compound file can be retrieved by calling the IStorage::Stat method.
The StgCreateDocfile function creates the file if it does not exist. If it does exist, the use of the STGM_CREATE, STGM_CONVERT, and STGM_FAILIFTHERE flags in the grfMode parameter indicate how to proceed. See the STGM enumeration for more information on these values.

If the compound file is opened in transacted mode (the grfMode parameter specifies STGM_TRANSACTED) and a file with this name already exists, the existing file is not altered until all outstanding changes are committed. If the calling process lacks write access to the existing file (because of access control in the file system), the grfMode parameter can only specify STGM_READ and not STGM_WRITE or STGM_READWRITE. The resulting new open compound file can still be written to, but a commit operation will fail (in transacted mode, write permissions are enforced at commit time).

If the grfMode parameter specifies STGM_TRANSACTED and no file yet exists with the name specified by the pwcsName parameter, the file is created immediately. In an access-controlled file system, the caller must have write permissions in the file system directory in which the compound file is created.
The absence of STGM_TRANSACTED in the grfMode parameter indicates the file is to be created and opened in direct access mode. Any existing file with the same name is destroyed before creating the new file.

The StgCreateDocfile function can be used to create a temporary compound file by passing a NULL value for the pwcsName parameter. However, these files are temporary only in the sense that they have a system-provided unique name
- likely one that is meaningless to the user. The caller is responsible for deleting the temporary file when finished with it, unless STGM_DELETEONRELEASE was specified for the grfMode parameter.

Note  By default, a Windows application can have 20 file handles open at one time. Each storage object opened in transacted mode uses three file handles. To increase the number of file handles the application has available, applications often call the Windows SetHandleCount function. However, the SetHandleCount function affects C run-time libraries (those statically linked to the application) that are hard-coded to expect only 20 file handles. There is no check on overflow, so if the application already has a few compound files open and it then uses a C run-time library (for example, fopen or sopen), the application corrupts memory past the end of the file-handle array (low in its data segment) if the library gets a file handle above 20.

To solve this problem, applications should reserve some number of file handles on start up, making them available to the components that might be based on C run-time libraries. If your application does not use any dynamic link libraries that use the C run-time libraries, there is no need for any special file-handle reservation code.

See Also

StgCreateDocFileOnILockBytes
回复 支持 反对

使用道具 举报

发表于 2007-4-23 15:29:58 | 显示全部楼层
OleSave
Saves an object opened in transacted mode into the specified storage object.

HRESULT OleSave(

    IPersistStorage * pPS,         //Points to the object to be saved
    IStorage * pStg,        //Points to the destination storage to which pPS is saved
    BOOL fSameAsLoad        //Indicates whether the object was loaded from pstg or not
   );       
Parameters

pPS

Points to the object to be saved.

pStg

Points to the destination storage object to which pPS is to be saved.

fSameAsLoad

TRUE indicates that pStg is the same storage object from which the object was loaded or created; FALSE indicates that pstg was loaded or created from a different storage object.

Return Values

S_OK

Indicates the object was successfully saved.

STG_E_MEDIUMFULL

Indicates the object could not be saved due to lack of disk space.

See also the IPersistStorage::Save method for other error return values.

Comments

The OleSave helper function handles the common scenario in which an object is open in transacted mode and is to be saved into the specified storage object which uses the OLE-provided compound file implementation. Other scenarios can be handled with the IPersistStorage and IStorage interfaces directly.
The OleSave function does the following:

1.        Calls the IPersistStorage::GetClassID method to get the CLSID.
        2.        Writes the CLSID to the storage object using the WriteClassStg function.
        3.        Calls the IPersistStorage::Save method to save the object.
        4.        If there were no errors on the save; calls the IPersistStorage::Commit method to commit the changes.

Note  Static objects are saved into a stream called CONTENTS. Static metafile objects get saved in "placeable metafile format" and static DIB data gets saved in "DIB file format." These formats are defined to be the OLE standards for metafile and DIB. All data transferred using an IStream interface or a file (that is; via IDataObject::GetDataHere) must be in these formats. Also; all objects whose default file format is a metafile or DIB must write their data into a CONTENTS stream using these standard formats.

See Also

IStorage, IPersistStorage
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-4-23 16:29:09 | 显示全部楼层
2、3楼给出的代码是OLE中保存文件的标准代码吧,对比其它语言的该部分代码,实现方式是一样的,理解上好象并没有错。那为什么我在SaveAsDocument时,会得到不正确的结果呢?
回复 支持 反对

使用道具 举报

发表于 2007-4-24 08:43:44 | 显示全部楼层
建议楼主在其他语言用Ole的SaveAsDocument看看,应该是一样的
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Justep Inc.

GMT+8, 2025-6-19 18:33 , Processed in 0.037515 second(s), 16 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表