gpt4 book ai didi

excel - `DoVerb(ovInplaceActivate)` 从 TOleContainer 提取文档数据时崩溃并显示各种错误消息

转载 作者:行者123 更新时间:2023-12-03 15:13:31 37 4
gpt4 key购买 nike

一位客户在通过 OLE 处理 Office 文档时遇到了我们软件的一些奇怪行为。当某些派生 TOleContainer 类的实例尝试通过 DoVerb(ovInPlaceActivate) 调用激活 OLE 对象时,代码崩溃。

有各种错误消息,包括:

  • (0x80030002) 找不到%1。
  • (0x80030005) 访问被拒绝。
  • (0x800706BE) 远程过程调用失败。

查看我的代码:

function TfrmOleOffice.SaveToStream: TStream;
var
LOleContainerState: TObjectState;
LModified: Boolean;
begin
Result := TMemoryStream.Create;
if IsEmpty and OleOfficeAvailable then exit;

if OleOfficeAvailable then
begin
LOleContainerStateBefore := FOleContainer.State;

LModified := FOleContainer.Modified; // 'FOleContainer.Modified' could be changed by 'FOleContainer.Close'
FOleContainer.Close;
FValue.Position := 0;
if LModified then // otherwise, take stored 'FValue' (see below)
FOleContainer.SaveToStream(FValue);
if LOleContainerStateBefore in [osUIActive] then
ActivateContainer; // reactivate the container
end;
Result.CopyFrom(FValue, 0);
end;


//---------------------------------------------------


procedure THKSOleContainer.SaveToStream(Stream: TStream);
var
TempLockBytes: ILockBytes;
TempStorage: IStorage;
DataHandle: HGlobal;
Buffer: Pointer;
Header: TStreamHeader;
R: TRect;
LFileName: String;
LFileStream: TFileStream;
begin
CheckObject;
if FModSinceSave then SaveObject;

// the following block might be obsolete
if FCopyOnSave then
begin
OleCheck(CreateILockBytesOnHGlobal(0, True, TempLockBytes));
OleCheck(StgCreateDocfileOnILockBytes(TempLockBytes, STGM_READWRITE
or STGM_SHARE_EXCLUSIVE or STGM_CREATE, 0, TempStorage));
OleCheck(FStorage.CopyTo(0, nil, nil, TempStorage));
OleCheck(TempStorage.Commit(STGC_DEFAULT));
OleCheck(GetHGlobalFromILockBytes(TempLockBytes, DataHandle));
end else
OleCheck(GetHGlobalFromILockBytes(FLockBytes, DataHandle));

// save the document as a temporary file and read it into a TFileStream
LFileName := IncludeTrailingPathDelimiter(GetMainTempFolder) + TPath.GetGUIDFileName + ExtractFileExt(FOriginalFileName); // get a unique temporary filename
SaveOleObject(LFileName);
try
LFileStream := TFileStream.Create(LFileName, fmOpenRead or fmShareDenyNone);
try
Stream.CopyFrom(LFileStream, 0);
finally
FreeAndNil(LFileStream);
end;
finally
SysUtils.DeleteFile(LFileName);
end;

FModified := False;
end;

procedure THKSOleContainer.SaveOleObject(AFileName: String = '');
var
LActivatedBefore: Boolean;
begin
LActivatedBefore := GetIsActivated;
DoVerb(ovInPlaceActivate, False); // <-- this call crashes with various error messages on several systems of a client
ForceDirectories(ExtractFilePath(AFileName));

OleObject.SaveAs(AFileName);

if not LActivatedBefore then
Close(OLECLOSE_NOSAVE, False);
end;

代码应该做什么?THKSOleContainer重新实现了SaveToStream,但不是保存一些只有OLE容器才能保存的内部OLE流正确打开后,它会将容器的内容保存到某个临时文件中,并将其读回到 TFileStream 中。结果应该是流形式的 native 文档。TfrmOleOffice 是显示 THKSOleContainer 实例的表单。

哪些情况可以正常运行,哪些情况不能? 首先,在我的计算机上,一切运行正常。我不知道还有其他客户遇到过这个问题。但在该客户的计算机上,当编辑文档并在表单确认时调用 SaveToStream 时,它会崩溃。如果文档已加载但未激活,它不会崩溃。实际上,SaveToStream 也被调用了,但它成功了。

我使用Microsoft Excel 2010 - 家庭和企业,而客户安装了Microsoft Excel 2010 - Professional Plus。我的系统和他的系统都是Windows 7 x64

对可能出现的问题有什么想法吗?

<小时/>

“常见问题解答”

GSerg: They have an antivirus and you don't?

  • 我们通过暂时停用防病毒软件进行了检查,但没有效果。我们甚至重新启动了计算机(并确保防病毒软件仍然处于停用状态)。

最佳答案

似乎是在函数 TfrmOleOffice.SaveToStream 中调用 FOleContainer.Close 导致了保存问题。在我提供此调用已被注释掉的版本后,客户在保存时不再出现错误。

我们还检测到另一个麻烦制造者:Microsoft Dynamics NAV 的 Excel COM 插件。停用后,加载时也不再出现错误。有时,Excel 在调用 OleCreateFromFile 时会卡住。我们现在将尝试更改其加载行为,以便仅在需要时才加载它。这可能也导致了一些保存问题。

关于excel - `DoVerb(ovInplaceActivate)` 从 TOleContainer 提取文档数据时崩溃并显示各种错误消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32121144/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com