在微软给的例子OClient中,有选中一个OLE对象然后Change Source的功能,但是会报错。分析了一下是这样的:

void CMainView::OnOleChangeSource()

{

    ASSERT(m_pSelection != NULL && m_pSelection->GetType() == OT_LINK);

 

    COleChangeSourceDialog dlg(m_pSelection);

    dlg.DoModal();

}

 

然后找到COleChangeSourceDialog 的定义,在c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\atlmfc\include\afxodlgs.h中。

可以看到里面有个成员m_xLinkInfo.

然后找到COleChangeSourceDialog的实现文件,在C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\atlmfc\src\mfc\oledlgs3.cpp。

先看构造函数:

COleChangeSourceDialog::COleChangeSourceDialog(COleClientItem* pItem,

    CWnd* pParentWnd) : COleDialog(pParentWnd), m_xLinkInfo(NULL)

{

    ASSERT_VALID(pItem);

 

    memset(&m_cs, 0, sizeof(m_cs)); // initialize structure to 0/NULL

 

    // fill in common part

    m_cs.cbStruct = sizeof(m_cs);

    m_cs.dwFlags = 0;

    if (AfxHelpEnabled())

        m_cs.dwFlags |= CSF_SHOWHELP;

    m_cs.lpfnHook = AfxOleHookProc;

    m_nIDHelp = AFX_IDD_CHANGESOURCE;

 

    // specific to this dialog

    m_cs.lpOleUILinkContainer = &m_xLinkInfo;

    COleDocument* pDoc = pItem->GetDocument();

    DWORD dwItem = 0;

    if (pDoc != NULL)

    {

        POSITION posItem = pDoc->GetStartPosition();

        ULONG iItem = 1;

        while ((posItem != NULL) && (dwItem == 0))

        {

            COleClientItem* pSearchItem = pDoc->GetNextClientItem(posItem);

            if (pSearchItem == pItem)

            {

                dwItem = iItem;

            }

            iItem++;

        }

    }

    m_cs.dwLink = dwItem;

}

 

可以看到,这里面把成员m_xLinkInfo设置为NULL.

这里面用到了pItem,就是我们在CMainView::OnOleChangeSource传进来的m_pSelection, pItem->GetDocument()得到的就是我们主程序的CMainDoc指针,构造函数利用这个指针,获得当前文档中被选中的OLE对象的索引,比如第一个就是1.

m_xLinkInfo被赋给了m_cs.lpOleUILinkContainer,m_cs的定义如下:

OLEUICHANGESOURCE m_cs

 

构造函数根据传入的pItem,初始化m_cs成员,以备它的其他函数调用。

现在我们回头看CMainView::OnOleChangeSource事件,这个事件中调用了COleChangeSourceDialog.DoModal函数。下面是这个函数的代码:

INT_PTR COleChangeSourceDialog::DoModal()

{

    ASSERT_VALID(this);

    ASSERT(m_cs.lpfnHook != NULL); // can still be a user hook

 

    m_cs.hWndOwner = PreModal();

    INT_PTR iResult = MapResult(::OleUIChangeSource(&m_cs));

    PostModal();

    return iResult;

}

 

可以看到这里用到了m_cs变量。

然后执行这步的时候报错了,报错点在这个文件的这个函数:

C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\atlmfc\src\mfc\oledlgs1.cpp

COleClientItem* COleUILinkInfo::GetLinkItem( DWORD dwLink )

{

    POSITION posItem = m_pDocument->GetStartPosition();

    COleClientItem* pItem = NULL;

    for (ULONG iLink = 0; iLink < dwLink; ++iLink)

    {

        pItem = m_pDocument->GetNextClientItem(posItem);

    }

 

    return pItem;

}

 

调试了一下发现m_pDocument为NULL(0x00000000)

为什么那?

我们看COleUILinkInfo的构造函数:

 

COleUILinkInfo::COleUILinkInfo(COleDocument* pDocument)

{

    ASSERT(pDocument == NULL ||

        pDocument->IsKindOf(RUNTIME_CLASS(COleDocument)));

    m_pDocument = pDocument;

    m_pSelectedItem = NULL;

    m_pos = NULL;

    m_bUpdateLinks = FALSE;

    m_bUpdateEmbeddings = FALSE;

}

 

现在问题明确了,因为在COleChangeSourceDialog的构造函数中把成员m_xLinkInfo设置为NULL, 所以传给COleUILinkInfo构造函数的参数也是空,所以COleUILinkInfo的m_pDocument成员为空,所以m_pDocument->GetStartPosition()会报错。

【解决方法】

继承COleChangeSourceDialog类自己写一个类来修复这个问题。

#pragma
once

#include
"afxodlgs.h"

 

class MyOleChangeSourceDialog :

    public COleChangeSourceDialog

{

public:

    MyOleChangeSourceDialog(COleClientItem* pItem, CWnd* pParentWnd = NULL);

};

 

#include
"MyOleChangeSourceDialog.h"

 

MyOleChangeSourceDialog::MyOleChangeSourceDialog(COleClientItem* pItem,

                                                 CWnd* pParentWnd) : COleChangeSourceDialog(pItem, pParentWnd)

{

    m_xLinkInfo = COleUILinkInfo(pItem->GetDocument());

}

 

然后调用新类。

void CMainView::OnOleChangeSource()

{

    ASSERT(m_pSelection != NULL && m_pSelection->GetType() == OT_LINK);

 

    MyOleChangeSourceDialog dlg(m_pSelection);

    

    dlg.DoModal();

}

 

运行起来后,成功!选择Change Source的时候不再报错了。

COleChangeSourceDialog不能Change Source的解决方法的更多相关文章

  1. 【linux】——FTP出现500 OOPS: cannot change directory的解决方法

    cannot change directory:/home/*** ftp服务器连接失败,错误提示: 500 OOPS: cannot change directory:/home/******* 5 ...

  2. 3、eclipse 查看原始类出现The jar file rt.jar has no source attachment解决方法

    因为rt的source在jdk目录的src.zip文件里,将文件设置为jdk下的src.zip就行了.具体如下 Window>Preferences>Java>Installed J ...

  3. 解决方法:配置群集时# gem install redis 报错:Unable to require openssl, install OpenSSL and rebuild ruby

    问题:前面已经在/usr/local/src安装了ruby-2.3.0.tar.gz.rubygems-2.4.2.tar.gz.在配置 redis-3.1.1 群集中,使用gem install 安 ...

  4. MyElipes遇到 source not found解决方案(查看.class文件源码一劳永逸的解决方法)

    在用Myeclipse 或者是eclipse进行开发时候经常遇到这个问题. File class editor source not found 问题.原因很简单,就是因为这是一个源码包,相应的没有编 ...

  5. Source insight 3572版本安装及An invalid source insight serial number was detected解决方法

    Source insight有最新版3572.3.50.0076 下载连接:http://www.sourceinsight.com/down35.html,   http://www.sourcei ...

  6. Android Configuration change引发的问题及解决方法(转)

    之前在学习Fragment和总结Android异步操作的时候会在很多blog中看到对Configuration Change的讨论,以前做的项目都是固定竖屏的,所以对横竖屏切换以及横竖屏切换对程序有什 ...

  7. Android Configuration change引发的问题及解决方法

    之前在学习Fragment和总结Android异步操作的时候会在很多blog中看到对Configuration Change的讨论,以前做的项目都是固定竖屏的,所以对横竖屏切换以及横竖屏切换对程序有什 ...

  8. MySQL mysqldump与source导入慢的解决方法

    Jquery中文网 >  数据库  >  mysql  >  正文 MySQL mysqldump与source导入慢的解决方法 MySQL mysqldump与source导入慢的 ...

  9. Source Insight中文注释乱码、字体大小、等宽解决方法

    中文注释乱码解决方法: 用记事本打开源文件,然后,选择文件->另存为,编码选为”ANSI“   字体的调整: Source Insight 菜单栏选择Options->Document O ...

随机推荐

  1. JS运动基础(二) 摩擦运动、缓冲运动

    摩擦运动: 逐渐变慢,最后停止 缓冲运动: 与摩擦力的区别:可以精确的停到指定目标点距离越远速度越大速度由距离决定速度=(目标值-当前值)/缩放系数Bug:速度取整值取整: iSpeed = iSpe ...

  2. ASP.Net Session, Cookie, Cache的区别

    Session—管理用户会话状态 什么是状态管理? 指对同一页或不同页的多个请求维护状态和页信息的过程 为什么要进行状态管理? Web页是无状态的,不保存任何用户请求信息,而且到服务器的每一往返过程都 ...

  3. 标准库中的-stack

    #include <sequence_concepts.h> __STL_BEGIN_NAMESPACE // Forward declarations of operators == a ...

  4. oracle之sqlplus讲解

    这里要解释的sqlplus有2方面内容:sqlplus登陆命令和sql*plus工具命令. [sqlplus登陆命令] 常用的登陆命令有: sqlplus /nolog 登陆到sqlplus,还未登录 ...

  5. ubuntu 上安装mysql

    打开"终端窗口",输入"sudo apt-get install mysql-server mysql-client"-->回车-->输入" ...

  6. 黑马程序员——JAVA基础之标准输入输出流

    ------- android培训.java培训.期待与您交流! ---------- 标准输入输出流: System中的基本字段,in,out 它们各代表了系统标准的输入和输出设备. 默认输入设备是 ...

  7. 使用 .bash_profile与.bashrc修改字符集

    发现终端设置为UTF8显示以后 svn打印终端就一直乱码, 是用户字符集的原因 有人建议 修改.bashrc 有人建议修改~/.bash_profile 搜索了下区别 /etc/profile:此文件 ...

  8. spring技术核心概念纪要

    一.背景 springframework 从最初的2.5版本发展至今,期间已经发生了非常多的修正及优化.许多新特性及模块的出现,使得整个框架体系显得越趋庞大,同时也带来了学习及理解上的困难. 本文阐述 ...

  9. MySQL下载及安装

    MySQL官网  http://dev.mysql.com/downloads/ Download --> Community --> MySQL Community Server 选择操 ...

  10. 【转】maven核心,pom.xml详解

    感谢如下博主: http://www.cnblogs.com/qq78292959/p/3711501.html maven核心,pom.xml详解 什么是pom?    pom作为项目对象模型.通过 ...