如何连接到非预览的第二个Word OLE实例(多进程共享)
问题背景与需求
我们有一个模块用Word预览旧格式(.DOC)文档,另有其他模块通过OLE打开Word实例处理文档。当前需求是仅创建一个具备完整功能的Word实例(非预览/嵌入式实例,这类实例没有功能区、菜单等),且支持多个进程连接该实例。
已知GetActiveObject可以获取Word实例,但它只返回第一个实例,如果该实例是预览/嵌入式的,就需要忽略它并创建新实例。现在要实现找到并连接第二个正常Word实例的功能,相关代码及修改尝试如下:
原代码片段
hr := GetActiveObject(ClassID, nil, unknown); if Succeeded(hr) then begin // Instance is running - get the IDispatch interface isRunning := true; OleCheck(unknown.QueryInterface(IDispatch, dispatch)); Result := dispatch; // Is the instance visible? If not, then we need to launch a new instance. Denotes a preview instance. isVisible := Result.Visible; end; // Only launch a new instance of Word if requested or isVisible is False. if ((not isRunning) or (not isVisible)) or createInstance then begin // Trying to find the right instance of Word. Experimental... isAssigned := False; if GetRunningObjectTable(0, ROT) = S_OK then begin if ROT.EnumRunning(enumMon) = S_OK then begin CreateBindCtx(0, Bind); while enumMon.Next(1, Moniker, Count) = S_OK do begin Moniker.GetDisplayName(Bind, Nil, DN); // This is the instance we want, and we get it... if pos('normal.dotm', Lowercase(DN)) > 0 then begin // What should be here to return the OLE Object? if Moniker.BindToObject(Bind, nil, IDispatch, Result) = S_OK then begin isAssigned := True; Break; end; end; end; end; end; // Create a new instance if (not isAssigned) or createInstance then begin OleCheck(CoCreateInstance(ClassID, nil, CLSCTX_INPROC_SERVER or CLSCTX_LOCAL_SERVER, IDispatch, dispatch)); Result := dispatch; end; end;
修改尝试片段
// What should be here to return the Object? if Moniker.BindToObject(Bind, nil, IDispatch, Unknown) = S_OK then begin OleCheck(unknown.QueryInterface(IDispatch, dispatch)); Result := dispatch; isAssigned := True; Break; end; if Moniker.BindToObject(Bind, nil, IDispatch, Unknown) = S_OK then begin OleCheck(unknown.QueryInterface(IDispatch, dispatch)); WordObj := dispatch; Result := WordObj.Application; isAssigned := True; Break; end;
内容的提问来源于stack exchange,提问作者David OBrien
相关产品推荐
相关产品推荐

