CLSID clsid;
CLSIDFromProgID(L"Word.Application", &clsid);  
CComPtr<IUnknown>  spUnk = NULL;
CComPtr<IDispatch> spDisp = NULL;
HRESULT hr = GetActiveObject(clsid, NULL, (IUnknown**)&spUnk);
if(SUCCEEDED(hr)) 
{
hr = spUnk->QueryInterface(IID_IDispatch, (void **)&spDisp);
if(SUCCEEDED(hr))
{
m_app.AttachDispatch(spDisp);
m_sel.AttachDispatch(m_app.GetSelection());
}
}像上面的代码获取word窗口是选中的文本.因为在程序里还要进行其它处理.
当在程序运行的过程中关闭word窗口后就会报错:对象已被删除.
怎么判断word文档是否已关闭?

解决方案 »

  1.   

    使用连接点,连接word退出消息。
      

  2.   

    能不说具体点,最好给点代码.
    因为我对Word自动化不是很熟。谢谢。
      

  3.   

    C++的没写过,C#写过。有个ApplicationEvents2_Event_DocumentBeforeClose事件。
    你可以用vc自带的oleview工具查看word.application的idl定义,获得所有接口方法的说明。
    可连接的事件都是在 dispinterface 里。
      

  4.   

    有没办法通过m_app或m_sel来判断word文档是否已关闭呢?
      

  5.   

    我其实不想捕获word关闭消息,
    只是在应用程序中使用m_app和m_sel时想知道它们是否还有效。
      

  6.   

    你手动调用QueryInterface获取的接口指针,都要调用一下AddRef(),这样Word程序即使在外面关掉,也不会导致你的程序出错了。
      

  7.   

    加了AddRef也不行呀。在关闭word后,如果我再使用m_app的话:
    m_app.GetSelection(..);弹出:RPC服务器不可用
    我不一定要在word关闭后还能继续使用m_app,
    我只想知道在我调用m_app.GetSelection的时候会不会出错,有没办法判断m_app是否还可以使用?
      

  8.   

    据我的经验是只能通过响应word关闭事件来处理。AddRef()没用的。上次回复的不准确,word关闭事件是 ApplicationEvents2_Event_Quit,在.net里是叫这个,不知道idl里具体啥名,我没查。使用连接点的过程大致如下:
    1、获得word.application的IDispatch指针后,QueryInterface获得IConnectionPointContainer接口指针;
    2、从IConnectionPointContainer接口中获得IConnectionPoint指针;
    3、用MFC的Wizard创建一个新MFC类,继承CCmdTarget,选择支持连接点;
    4、Wizard会在你的类里生成一个嵌套类,此类实现了IDispatch接口,并在你的类里声明此嵌套类的实例成员;
    5、用此实例成员的指针作为参数,调用IConnectionPoint接口的Advise()方法;
    6、到此为止,已经将你的类连接到了word的事件上。继续往下。
    7、Wizard会生成一个OnEvent方法,需要你手工实现,实现方法如下;
    8、通过idl定义,获得名称为ApplicationEvents2_Event_Quit的dispid;
    9、判断如果OnEvent参数里的dispid不是此事件的dispid,则忽略,否则继续;
    10、到此,说明收到了word退出的消息,你该怎么清理你的指针,是你的事了。以上是个大概过程说明。在MFC里写这个是好久以前的事了,呵呵,所以可能有的记忆不是很准确,你可以按此步骤试试,另外你自己查查文档。有问题再说。