COleChangeSourceDialog不能Change Source的解决方法
在微软给的例子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 #include
class MyOleChangeSourceDialog : public COleChangeSourceDialog { public: MyOleChangeSourceDialog(COleClientItem* pItem, CWnd* pParentWnd = NULL); }; |
|
#include
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的解决方法的更多相关文章
- 【linux】——FTP出现500 OOPS: cannot change directory的解决方法
cannot change directory:/home/*** ftp服务器连接失败,错误提示: 500 OOPS: cannot change directory:/home/******* 5 ...
- 3、eclipse 查看原始类出现The jar file rt.jar has no source attachment解决方法
因为rt的source在jdk目录的src.zip文件里,将文件设置为jdk下的src.zip就行了.具体如下 Window>Preferences>Java>Installed J ...
- 解决方法:配置群集时# 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 安 ...
- MyElipes遇到 source not found解决方案(查看.class文件源码一劳永逸的解决方法)
在用Myeclipse 或者是eclipse进行开发时候经常遇到这个问题. File class editor source not found 问题.原因很简单,就是因为这是一个源码包,相应的没有编 ...
- 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 ...
- Android Configuration change引发的问题及解决方法(转)
之前在学习Fragment和总结Android异步操作的时候会在很多blog中看到对Configuration Change的讨论,以前做的项目都是固定竖屏的,所以对横竖屏切换以及横竖屏切换对程序有什 ...
- Android Configuration change引发的问题及解决方法
之前在学习Fragment和总结Android异步操作的时候会在很多blog中看到对Configuration Change的讨论,以前做的项目都是固定竖屏的,所以对横竖屏切换以及横竖屏切换对程序有什 ...
- MySQL mysqldump与source导入慢的解决方法
Jquery中文网 > 数据库 > mysql > 正文 MySQL mysqldump与source导入慢的解决方法 MySQL mysqldump与source导入慢的 ...
- Source Insight中文注释乱码、字体大小、等宽解决方法
中文注释乱码解决方法: 用记事本打开源文件,然后,选择文件->另存为,编码选为”ANSI“ 字体的调整: Source Insight 菜单栏选择Options->Document O ...
随机推荐
- Java数据结构和算法之哈希表
五.哈希表 一般的线性表.树中,记录在结构中的相对位置是随机的即和记录的关键字之间不存在确定的关系,在结构中查找记录时需进行一系列和关键字的比较.这一类查找方法建立在“比较”的基础上,查找的效率与比较 ...
- Map/Reduce 工作机制分析 --- 数据的流向分析
前言 在MapReduce程序中,待处理的数据最开始是放在HDFS上的,这点无异议. 接下来,数据被会被送往一个个Map节点中去,这也无异议. 下面问题来了:数据在被Map节点处理完后,再何去何从呢? ...
- (实用篇)jQuery+PHP+MySQL实现二级联动下拉菜单
二级联动下拉菜单选择应用在在很多地方,比如说省市下拉联动,商品大小类下拉选择联动.本文将通过实例讲解使用jQuery+PHP+MySQL来实现大小分类二级下拉联动效果. 先看下效果 大类: 前端技术 ...
- Learning to write a compiler
http://stackoverflow.com/questions/1669/learning-to-write-a-compiler?rq=1 Big List of Resources: A N ...
- python集成开发工具
1. IDLE http://python.org/idle/ (在 Python 发行版中自带) 2 BlackAdder 3 PythonWorks 4 Wing IDE http://wingw ...
- 【freemaker】之自定义指令<#macro>
测试代码 @Test public void test07(){ try { root.put("name", "张三"); freemakerUtil.fpr ...
- !!!!!122. Best Time to Buy and Sell Stock II
Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...
- Hololens开发笔记之Gesture手势识别(单击,双击)
本文使用手势识别实现识别单击及双击手势的功能,当单击Cube时改变颜色为蓝色,当双击Cube时改变颜色为绿色. 手势识别是HoloLens交互的重要输入方法之一.HoloLens提供了底层API和高层 ...
- gerrit 解决中文乱码相关配置(转载)
From:http://www.cnblogs.com/Jerryshome/archive/2012/04/19/2457170.html 计划在团队中采用code review,因为一直是用git ...
- CRM 日期类型的一些处理JS
//当前日期 var now = new Date(); //换算为毫秒数 var now_ms = Date.UTC( now.getFullYear(), now.getMonth(),now.g ...