扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
编者按:上一篇《使用C++和XML建立智能文档(二)》我们给读者介绍了ISmartDocument接口教程、属性包、建立智能文档操作DLL、安装智能文档解决方案 .本篇接下来将做如下讲解: 目录 访问智能文档内容 为了能起到作用,你的智能文档操作DLL一般需要访问(并且可能修改)下层的Office文档。在例子中,它是Excel项目进程表电子表格。为了这个目的,ISmartDocument的几个方法为你下层文档提供了一个IDispatch COM接口指针。在Office上编写COM的人知道,Idispatch提供了进入Office对象模型的通道。在Visual Basic中,使用Idispatch和类型库是相当自动化的,但是在C++中稍微复杂一些。 起先我准备使用#import指令,它允许Visual C++为类型库中的所有接口生成ATL智能指针包装。但是要让它正确的编译需要做大量的工作,它常常提示有东西出错了。果真,我找到了知识库文章“Office Application Remains in Memory After Program Finishes”,它描述了在Office类型库中使用#import指令所遇到的知名的问题以及相应的建议。 最后,我决定建立自己的类CexcelWorkbook来包装需要的Excel方法。这个类继承自ATL模版CcomDispatchDriver,这使它相对容易通过IDispatch调用Excel对象模型上的方法。使用CcomDispatchDriver的方法GetIDOfName,你可以得到一个给定的属性或方法(例如,Excel对象模型中的ActiveSheet的范围)的DISPID。你一旦有了DISPID(为了效率更高,我在类中对它进行了缓冲处理),就可以使用某个其它的CcomDispatch方法(例如GetProperty或InvokeN,此处的N是参数的数量)访问对象模型中的属性和方法。注意Exce Range值是作为VBA属性(而不是方法)暴露的,但是它也需要一个参数(范围地址)。因为CcomDispatchDriver没有提供为GetProperty调用传递的参数的途径,我在自定义类(CExcelWorkbook)中实现了一个新的方法(GetProperty1),它用于处理这种情况。 一切都在预料之中,在我尝试建立智能文档操作DLL的时候也没有出现异常。我试图在Excel中附加一个XML大纲的时候,收到了一个错误信息“XML扩展包逻辑丢失或无效”。为了调试这个错误,我首先使用ListDLLs(http://www.sysinternals.com上的一个方便的工具)确定Excel是否载入了我的库,这样清单才能看起来足够好,它可以让Excel找到该DLL的。我退出Excel,接着修改了项目的Debugging属性(右键点击解决方案并选择“属性”)告诉Visual Studio使用Excel作为该DLL的EXE容器。我浏览Excel.exe并选择它作为Command值。 接着,我按下Ctrl-B打开“New Breakpoints”对话框,在Function字段中输入DllMain,当出现“disambiguate symbol”窗口(显然有两个重载的DllMain函数)的时候选择了它们两个,通过这些操作在DllMain中设置了一个断点。我的目的是当Excel第一次调用该DLL的时候得到控制权。接着我按下F5,Excel启动了。Visual Studio警告没有Excel符号,但是我早就知道了。我打开智能文档,使用Data | XML | XML Expansion Packs试图再次附加XML大纲。Visual Studio同ATL生成的DllMain中的断点一起出现了。 这个时候我的目标是确定DLL中是否有方法、哪些方法被调用了。我在自己的IsmartDocument接口实现中的所有方法上设置了断点,以确定它们其中的哪些被调用了。实际上,有几个方法被调用了,并且通过逐步运行我找到了一个普通的索引问题,传递到get_SmartDocXmlTypeName的控件索引是从1开始的,但是C++代码把它处理为从0开始的,因此对最后一个元素的调用返回了E_INVALIDARG。后来我给所有的接口方法的入口点添加了ATLTRACE2宏,使自己更容易知道正在调用什么、什么时候调用。 对于示例解决方案,我需要知道用户什么时候选择了电子表格的数据项区域中的某行,这意味着他希望编辑该事务的相关信息。接着我从当前行中抓取信息并填充事务面板,允许他输入本周的工作和下一周的计划工作的相关信息。当他改变了事务面板中的某些东西的时候,我将使用Excel对象模型把新的信息复制回原工作表行。但是我如何知道什么时候选择了新的行?有一种比较复杂的解决方案,即使用Excel事件(在Visual Basic中容易,但是在C++中不是太容易),但是我发现这是没有必要的。在Excel中无论选择什么时候发生了改变,都会调用IsmartDocument接口方法,因此无论什么事情,你仅仅需要改变通知。通过更新每次改变后的进度表事务内部视图,我能够忽略行选择的变化。 因为宏病毒和其它的脚本技术的恶意使用变得很普遍,Office在两个途径做了修改:通过提高默认的安全性设置,防止运行大多数没有签名的、潜在的恶意代码;通过增加安全性设置的数量,为即使没有数字签名的解决方案的运行提供了更多的管理权限。这考虑了现实情况:很多Office解决方案(嵌入Word或Excel文档中的宏)都已经广泛的布署在大型组织中,要让它们完全安全将花费一定时间。如果新版本Office突然要求所有的解决方案必须有数组签名(理想的解决方案),这将给很多组织带来布署方面的障碍。但是,Office安全性设置的增加也使安全性更加复杂,在本文中我没有谈到这个主题。 应用于宏和插件程序的相同的Office安全性设置也可应用于智能文档。这些设置包括: ·用户宏的安全性设置(高、中或低,在Tools | Macro | Security中设置;默认的是高)。 ·智能文档是否从可信(trusted)位置载入:可信的文件系统目录(例如每个用户的或工作组模版目录)、公司局域网上的Web服务器或可信的Internet站点。 ·智能文档组件是否是数字签名的,如果是,发行人是否在Tools | Macro | Security | Trusted Publishers设置为可信发行人。 ·是否在Tools | Macro | Security | Trusted Publishers中选择了“相信所有安装了的插件程序和模版”。 默认情况下,Tools | Macro | Security中的安全性层次被设置高,Office阻止任何没有数字签名的插件程序DLL(包含智能文档操作DLL)的载入。上面列举的安全性设置的其它组合可以允许智能文档被载入(可能给用户显示一个安全性提示),但是保证组织中的安全性的最好途径仍然是使用从VeriSign或GTE CyberTrust得到的数字证书对所有的已布署的解决方案(包括智能文档组件)进行数字签名。微软2003 智能文档SDK中的XMLSign.exe工具可以用于对XML智能文档清单文件进行数字签名。 此外,如果某个Office智能文档解决方案是从Web服务器上运行的,微软Internet Explorer和Office安全性设置都会影响解决方案是否能运行。如果服务器上的XML扩展包清单文件既不在Internet Explorer可信站点中,也不在局域网区域,就不会试图检索它,也不会给用户提示把该站点添加到Internet Explorer可信列表站点列表中。如果XML扩展包清单文件位于可信的服务器或局域网上,清单是否被载入依赖于它是否签名了。如果它是签名了的,并允许运行,它仍然受到用户Office安全性设置的约束。 在智能文档解决方案开发过程中,你可以通过编辑注册表的下述键下面的REG_DWORD值“DisableManifestSecurityCheck”激活或禁止XML扩展包清单文件安全性检查:
如果它的值为1将禁止XML扩展包清单文件安全性检查,如果值为0就激活了它。当你试图引用某个XML扩展包清单文件的时候,如果这个注册表设置是1(禁止安全性检查),将出现一个对话框警告用户禁止安全性是危险的。它同时提供一个“确定”按钮,这个按钮允许你立即重新激活XML扩展包安全性检查。你应该仅仅在开发解决方案的时候把开发计算机的注册表的这个值设置为1(这个时候每次编译每个组件后进行数字签名可能不方便),但是要确保在签名后的组件的最后测试中激活它。在用户计算机上禁止XML扩展包清单文件安全性检查是非常不可取的。 尽管本文讨论了在C++中智能文档操作DLL的建立,但是用Visual Basic .NET或C#建立受控操作DLL也是可行的。在那种情况下,将应用.NET框架组件安全性模型,但是这超出了本文讨论的范围。 我的示例依据Excel对象模型使用Idispatch访问来自进度表智能文档工作表的信息以生成状态报告。我也可以选择开发一些C++代码来驱动Word对象模型建立状态文档,但是我选择了另一种途径,它也利用了Word 2003中的新XML特性的优点。我把状态报告生成为XML文件,并使用XSLT在Word中打开它以提供良好的格式化。这种方法利用了使用XSLT很容易把几个XML文件(可能是整个小组的状态报告)合并成一个大的报告的优点,如果它们作为Word文档保存就很难合并了。 在花费一段时间研究如何实现XML保存后,我决定定义一个类来管理将显示在状态报告上的数据项列表。当开发者更新进度表中的信息的时候,智能文档操作DLL中的代码就会建立并更新这个事务列表,这与文档操作工作面板中放置的控件对应。最后,开发者点击工作面板中的控件生成XML状态报告。每个类负责使用MSXML DOM正确地保持存储在XML中的信息。处理这种情行的处理方法是CScheduleTaskList和CScheduleTask。我用于格式化它的Word XSL样式表是ScheduleReport.xsl,它在示例代码中提供了。当你安装智能文档解决方案的时候,这个XLST文件就会被安装好,并让Word知道它,这样当你在Word中打开XML状态报告的时候,它将自动应用这个样式表。你也可以使用Word中的XML数据视图事务面板来选择这个样式表。 在我生成的XML中有一个指令值得提起:
这条指令告诉Windows资源管理器这个XML文件的默认的应用程序是Word。你也可能注意到结果是这个文件的图标改变了。 让这个Word样式表精确地显示状态报告需要花一段时间,因此此处我没有提供详细信息。但是,我要警告你,如果你查看我提供的样式表,你会对显示的这个Word XML大纲的复杂程度感到惊奇。其中的很多是样板代码,很多都是在Word中建立示例状态文档(我希望通过这种方式设置样式和字体)并把该文档保存为XML格式的时候获得的。我把生成的XML中的大部分复制到自己的XSLT样式表中。但是,我不能确定这种办法生成的XML是在Word中生成良好格式化的状态报告所需要的最小的XML. 我可以根据自己的经验为开发XSLT提供一些建议。要记住XML是一种非常精确的、大小写敏感的语言。在这方面它与C++没有不同,但是如果出错了,你接收到的诊断信息可能是某种类型的“不能应用样式表”信息,而不是编译器提供的详细描述。如果你对某些已经在运行的东西做大范围的修改,应该逐步增加并做好版本控制,这样才能回滚到以前的修改去。我遇到了一个问题,即样式表引用了ScheduleSmartDocument名字空间,但是由于操作DLL中出了错误,在生成的XML状态报告中该名字空间的名称变成了ScheduleSmartDoc。结果当我在XML状态报告上应用该XSLT的时候,Word简单地显示了一个空文档,因为样式表中使用的XPATH与XML中的不匹配。 让Word自动地应用正确的样式表需要花点力气。最后,我让安装智能文档操作DLL的清单也安装该样式表。为了让Word知道这个样式表,清单中的解决方案条目必须含有context属性,它引用该Word XML名字空间(http://schemas.microsoft.com/office/word/2003/wordml)。 最后一步是把智能文档URI(示例中的是ScheduleSmartDocument)作为清单、样式表和生成的XML状态报告文档的XML名字空间。在例子中,我把ScheduleSmartDocument作为名字空间的名称。你应该根据组织中的唯一的URI来使用名字空间。 反向操作,从Word文档生成XML看起来是个好的办法。但是,幅面和切割结果的Word输出的时候要非常小心。例如,我试图减小列表部分的复杂性(它描述了文档中使用的格式列表),因为我的状态报告只需要一个简单的、一层的符号列表。在一个小时以后,我放弃了,留下大量的未改动的部分,虽然我确信其中的很多是我不需要的。 如果你在Visual Studio中打开一个生成好的Word XML文件,你会发现它对于Visual Studio .NET大纲查看器来说太复杂了。因此,我建议当XML打开的时候,首先点击“数据视图”,强制Visual Studio分解该XML,接着返回“XML视图”查看良好格式化的版本(它在Notepad中打开的时候,实际上是不可阅读的)。 我的最后一条建议是在调整样式表的时候可以使用一个非常强大的工具。MSXSL.EXE命令行工具允许你给XML文件应用样式表并查看生成的XML输出。你可以从链接http://msdn.microsoft.com/library/en-us/dnxml/html/msxsl.asp处下载它。 我首先是在C++中开始开发操作DLL的,这是因为目前Office编码的太多示例都是用Visual Basic编写的。但是,使用C++执行一些甚至于很简单的事务(例如引用Excel中的一个单元值)也比使用Visual Basic明显复杂多了。图11显示了与Visual Basic中ActiveSheet.Range("A1").Value语句等同的C++代码(注意这个方法的示例代码有不同的版本,因为我用设置值方法把它重新编写为共享代码)。我提供了智能文档处理程序希望对Excel对象模型执行的少量操作的C++代码,但是我编写的示例根本没有因为使用C++而受益。我鼓励读者认真的考虑使用C++与Visual Basic之间的代价。
Office 2003中的另一个选择是C#,它是有吸引力的,但是请你确保自己清楚了解非受控代码(Office)调用受控代码(用C#或Visual Basic .NET编写的操作处理程序部件)的性能问题。有可能使用Visual Basic是最好的办法。 智能文档为开发者提供了非常强大的用户界面范例。你可以在利用微软Office应用程序的所有功能的时候,同时提供无缝地集成到Office事务面板用户界面中的自定义UI和行为。我认为智能文档将很快在大型组织中广泛使用,以简化业务过程,如同目前使用的带有宏的电子表格一样。【完】 原文标题:《Create Word and Excel Smart Documents with C++ and XML》 原文作者:Mike Kelly 原文链接:http://msdn.microsoft.com/msdnmag/issues/03/12/SmartDocuments/default.aspx 代码下载: |
濠电姷鏁告慨鐑藉极閸涘﹥鍙忛柣鎴濐潟閳ь剙鍊圭粋鎺斺偓锝庝簽閸旓箑顪冮妶鍡楀潑闁稿鎹囬弻娑㈡偄闁垮浠撮梺绯曟杹閸嬫挸顪冮妶鍡楀潑闁稿鎸剧槐鎾愁吋閸滃啳鍚Δ鐘靛仜閸燁偉鐏掗柣鐘叉穿鐏忔瑧绮i悙鐑樷拺鐟滅増甯掓禍浼存煕閹惧娲撮柟顔藉劤鐓ゆい蹇撴噳閹锋椽姊婚崒姘卞闁告娲熷畷濂稿Ψ閵壯勭叄婵犵數濮撮敃銈団偓姘煎弮瀹曪綀绠涢弮鍌滅槇婵犵數濮撮崐缁樻櫠濞戙垺鐓曢悗锝冨妼婵′粙鏌曢崶褍顏€殿喕绮欐俊姝岊槹闁逞屽墯鐢繝寮婚悢鍏煎癄濠㈣泛锕ュ▓濠氭⒑閸濆嫮鐏遍柛鐘崇墵楠炲啫饪伴崼婵堝幐闂佺ǹ鏈粙鎾广亹鐎n喗鐓熼幖娣€ゅḿ鎰箾閸欏顏堟偩濠靛牏鐭欓悹鎭掑妽濞堥箖姊洪崜鎻掍簼婵炲弶鐗犻幃鈥斥槈閵忥紕鍘遍柣蹇曞仜婢т粙鎯岀€n偆绠鹃柛顐ゅ枑閸婃劖鎱ㄦ繝鍕笡闁瑰嘲鎳愮划鐢碘偓锝庝簼閻d即姊绘担瑙勫仩闁告柨顑夊畷锟犲礃閼碱剚娈鹃梺闈涚箞閸婃洟宕橀埀顒€顪冮妶鍡楀闁稿骸宕惃顒勬⒒閸屾瑧鍔嶉悗绗涘懐鐭欓柟瀵稿Л閸嬫挸顫濋悡搴$睄閻庤娲戦崡鍐茬暦閸楃倣鐔兼⒐閹邦喚娉块梻鍌欑窔濞佳囨偋閸℃稑绠犻幖娣灪閸欏繑銇勯幒鍡椾壕闂佸疇顫夐崹鍧楀春閵夆晛骞㈡俊鐐插⒔閸戣绻濋悽闈浶為柛銊︽そ閺佸鏌ч懡銈呬沪濞e洤锕俊鍫曞川椤斿吋顏¢梻浣呵归鍛村磹閸︻厽宕叉繛鎴欏灩楠炪垺淇婇婵愬殭缁炬澘绉归弻锝嗘償閵忥絽顥濆銈忓閺佽顕g拠宸悑闁割偒鍋呴鍥⒒娴e憡鍟為柟鎼佺畺瀹曠増鎯旈…鎴炴櫔闂佹寧绻傞ˇ浠嬪极閸℃ぜ鈧帒顫濋濠傚闂佹椿鍘介〃鍡欐崲濞戙垹绠婚柡澶嬪灩閸斾即姊虹粙娆惧剱闁圭懓娲濠氭晲閸涱亝顫嶅┑鐐叉閸旀洜澹曢幎鑺モ拺闁告繂瀚﹢鎵磼鐎n偄鐏撮柛鈺冨仱楠炲鏁冮埀顒€顔忓┑鍥ヤ簻闁哄洨鍋為崳娲煃鐠囪鍔熺紒杈ㄦ崌瀹曟帒鈻庨幋婵嗩瀴婵$偑鍊戦崝宀勫箠濮椻偓楠炲棗鐣濋崟顐わ紲闂佺粯鍔欏ḿ褏绮婇敃鍌涚厵闁稿繗鍋愰弳姗€鏌涢弬璺ㄧ劯闁诡喚鍋ゅ畷褰掝敃閻樿京鐩庨梻浣告贡閸庛倝宕归悽鍓叉晜闁冲搫鎳忛崐鍨叏濮楀棗澧绘俊鎻掔秺閺屾洟宕惰椤忣厾鈧鍠曠划娆愪繆濮濆矈妲奸梺闈╃祷閸庡磭妲愰幘瀛樺缂佹稑顑呭▓顓炩攽閳藉棗浜濈紒璇茬墕椤曪絾绻濆顓炰簻缂佺偓濯芥ご鎼佸疾閿濆鍋℃繝濠傚暟鏁堥梺璇″枟閿曘垽骞婇悩娲绘晢闁稿本绮g槐鏌ユ⒑閸濆嫷妲搁柣妤€瀚板畷婵囨償閿濆洣绗夐梺缁樺姉閸庛倝鎮″☉銏″€堕柣鎰硾琚氶梺鍝ュУ閿曘垽寮婚埄鍐╁闁荤喐婢橀~鎺楁倵鐟欏嫭绀堥柛鐘崇墵閵嗕礁顫滈埀顒勫箖閳哄懏鎯炴い鎰╁€濋幏濠氭⒒閸屾艾鈧嘲霉閸パ呮殾闁割煈鍋呴崣蹇涙煙閹澘袚闁抽攱姊婚埀顒€绠嶉崕閬嵥囬鐐插瀭闁稿瞼鍋為悡銏′繆椤栨粌鐨戠紒杈ㄥ哺閺屻劌鈹戦崱鈺傂︾紓浣插亾閻庯綆鍋佹禍婊堟煛瀹ュ啫濡块柍钘夘槹缁绘盯宕奸悢铏圭厜濠殿喖锕ㄥ▍锝呪槈閻㈢ǹ宸濇い鏂惧嫎閳ь剚鍔曢—鍐Χ鎼粹€茬凹濠电偠灏欓崰鏍х暦濞差亜鐒垫い鎺嶉檷娴滄粓鏌熼崫鍕棞濞存粓绠栧娲箰鎼淬垻鈹涙繝纰樷偓铏悙閸楅亶鏌熼悧鍫熺凡缂侇偄绉归弻娑㈩敃閿濆洨鐣煎銈嗘尰濡炶棄顫忛搹鍦<婵☆垰鎼~宀勬倵濞堝灝娅橀柛鎾寸懆閻忓啴姊洪崨濠佺繁闁哥姵宀稿畷銏ゅ箹娴e厜鎷洪梺鍛婃尰瑜板啯绂嶆禒瀣厱閻庯綆浜滈顓㈡煙椤旀枻鑰块柡浣稿暣瀹曟帒鈽夊顒€绠為梻浣筋嚙閸戠晫绱為崱娑樼;闁糕剝蓱濞呯姵銇勯幒鎴濃偓鑽ゅ婵傚憡鐓曢悘鐐插⒔閳藉绱掑锕€娲﹂悡娆撴煟閻斿憡绶叉い蹇e弮閺岀喖鎮℃惔銏g闂佺懓寮堕幐鍐茬暦閻斿吋顥堟繛鎴炵懄閻濓繝姊婚崒姘偓鎼佸磹妞嬪海鐭嗗〒姘e亾妤犵偞鐗犻、鏇㈠Χ閸屾矮澹曞┑顔矫畷顒勫储鐎电硶鍋撶憴鍕缂傚秴锕濠氬幢濡ゅ﹤鎮戦梺鍛婁緱閸ㄧ晫妲愰柆宥嗙厽閹艰揪绱曢悾顓㈡煕鎼淬劋鎲鹃挊婵喢归崗鍏肩稇缁炬崘娉曢埀顒€绠嶉崕閬嵥囨导瀛樺亗闁哄洢鍨洪悡娑㈡煕閵夛絽鍔氬┑锛勫帶椤儻顧侀柛銊ゅ嵆濠€渚€姊虹紒妯撳湱绮旈鈧、鏃堝醇閻旇櫣鏆㈤梻鍌氬€烽悞锔锯偓绗涘懏宕查柛灞绢嚤濞戞鏃堝川椤撶姴骞掗梻浣告惈濞层垽宕瑰ú顏呭亗闁告劦浜濋崰鎰節婵犲倻澧曠紒鈧崼鐔稿弿婵☆垱瀵х涵楣冩煢閸愵亜鏋涢柡灞炬礃缁绘稖顦查悗姘卞厴瀹曟垿濡搁埡鍌楁嫼缂傚倷鐒﹂敋濠殿喖娲﹂妵鍕即閵娿儱绫嶉梺绯曟杺閸ㄨ棄顕i幘顔碱潊闁炽儲鏋奸崑鎾绘偨閸涘﹦鍙嗗┑鐘绘涧濡鍩€椤掑倹鍤€闁宠绉瑰畷鍫曞Ω閿濆嫮鐩庨梻濠庡亜濞诧妇绮欓幇鏉跨疅濡わ絽鍟悡娑㈡倶閻愰潧浜剧紒鈧€n兘鍋撶憴鍕濞存粌鐖奸妴浣割潨閳ь剟骞冮姀锛勯檮濠㈣泛顦辨径锟�
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者