﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-swo2006-文章分类-com</title><link>http://www.cppblog.com/swo2006/category/3200.html</link><description /><language>zh-cn</language><lastBuildDate>Sat, 24 May 2008 18:33:33 GMT</lastBuildDate><pubDate>Sat, 24 May 2008 18:33:33 GMT</pubDate><ttl>60</ttl><item><title> VC中的“__declspec”能作什么（2）－为类增加属性</title><link>http://www.cppblog.com/swo2006/articles/16298.html</link><dc:creator>swo</dc:creator><author>swo</author><pubDate>Mon, 11 Dec 2006 15:40:00 GMT</pubDate><guid>http://www.cppblog.com/swo2006/articles/16298.html</guid><wfw:comment>http://www.cppblog.com/swo2006/comments/16298.html</wfw:comment><comments>http://www.cppblog.com/swo2006/articles/16298.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/swo2006/comments/commentRss/16298.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/swo2006/services/trackbacks/16298.html</trackback:ping><description><![CDATA[
		<pre>属性，是面向对象程序设计中不可缺少的元素，广义的属性是用来描述一个对象所处于的状态。<br />而我们这篇文章所说的属性是狭义的，指能用“=”操作符对类的一个数据进行get或set操作，而且能控制get和set的权限。<br />        先看一下代码：<br /><span class="pre"><font color="#000099">#include &lt;IOSTREAM&gt;<br />#include &lt;map&gt;<br />#include &lt;string&gt;<br />#include &lt;CONIO.H&gt;</font></span><span class="keyword"><font color="#990000"><br />using namespace</font></span> std<span class="operator"><strong><font color="#663300">;</font></strong></span><span class="keyword"><font color="#990000"><br />class</font></span> propertytest<span class="operator"><strong><font color="#663300">{</font></strong></span><span class="type"><font color="#ff6633"><br />int</font></span> m_xvalue<span class="operator"><strong><font color="#663300">;</font></strong></span><span class="type"><font color="#ff6633"><br />int</font></span> m_yvalues<span class="operator"><strong><font color="#663300">[</font></strong></span><span class="int"><font color="#999900">100</font></span><span class="operator"><strong><font color="#663300">];</font></strong></span><br />map<span class="operator"><strong><font color="#663300">&lt;</font></strong></span>string<span class="operator"><strong><font color="#663300">,</font></strong></span>string<span class="operator"><strong><font color="#663300">&gt;</font></strong></span> m_zvalues<span class="operator"><strong><font color="#663300">;</font></strong></span><span class="keyword"><font color="#990000"><br />public</font></span><span class="operator"><strong><font color="#663300">:</font></strong></span><br />__declspec<span class="operator"><strong><font color="#663300">(</font></strong></span>property<span class="operator"><strong><font color="#663300">(</font></strong></span>get<span class="operator"><strong><font color="#663300">=</font></strong></span>GetX<span class="operator"><strong><font color="#663300">,</font></strong></span> put<span class="operator"><strong><font color="#663300">=</font></strong></span>PutX<span class="operator"><strong><font color="#663300">))</font></strong></span><span class="type"><font color="#ff6633"><br />int</font></span> x<span class="operator"><strong><font color="#663300">;</font></strong></span><br />__declspec<span class="operator"><strong><font color="#663300">(</font></strong></span>property<span class="operator"><strong><font color="#663300">(</font></strong></span>get<span class="operator"><strong><font color="#663300">=</font></strong></span>GetY<span class="operator"><strong><font color="#663300">,</font></strong></span> put<span class="operator"><strong><font color="#663300">=</font></strong></span>PutY<span class="operator"><strong><font color="#663300">))</font></strong></span><span class="type"><font color="#ff6633"><br />int</font></span> y<span class="operator"><strong><font color="#663300">[];</font></strong></span><br />__declspec<span class="operator"><strong><font color="#663300">(</font></strong></span>property<span class="operator"><strong><font color="#663300">(</font></strong></span>get<span class="operator"><strong><font color="#663300">=</font></strong></span>GetZ<span class="operator"><strong><font color="#663300">,</font></strong></span> put<span class="operator"><strong><font color="#663300">=</font></strong></span>PutZ<span class="operator"><strong><font color="#663300">))</font></strong></span><span class="type"><font color="#ff6633"><br />int</font></span> z<span class="operator"><strong><font color="#663300">[];</font></strong></span><span class="type"><font color="#ff6633"><br />int</font></span> GetX<span class="operator"><strong><font color="#663300">()	<br />{</font></strong></span><span class="flow"><font color="#ff0000"><br />return</font></span> m_xvalue<span class="operator"><strong><font color="#663300">;<br /> };</font></strong></span><span class="type"><font color="#ff6633"><br />void</font></span> PutX<span class="operator"><strong><font color="#663300">(</font></strong></span><span class="type"><font color="#ff6633">int</font></span> x<span class="operator"><strong><font color="#663300">)<br /> {</font></strong></span><br />m_xvalue<span class="operator"><strong><font color="#663300"> =</font></strong></span> x<span class="operator"><strong><font color="#663300">;	<br />};</font></strong></span><span class="type"><font color="#ff6633"><br />int</font></span> GetY<span class="operator"><strong><font color="#663300">(</font></strong></span><span class="type"><font color="#ff6633">int</font></span> n<span class="operator"><strong><font color="#663300">)	<br />{</font></strong></span><span class="flow"><font color="#ff0000"><br />	return</font></span> m_yvalues<span class="operator"><strong><font color="#663300">[</font></strong></span>n<span class="operator"><strong><font color="#663300">];	<br />};</font></strong></span><span class="type"><font color="#ff6633"><br />void</font></span> PutY<span class="operator"><strong><font color="#663300">(</font></strong></span><span class="type"><font color="#ff6633">int</font></span> n<span class="operator"><strong><font color="#663300">,</font></strong></span><span class="type"><font color="#ff6633">int</font></span> y<span class="operator"><strong><font color="#663300">)	<br />{</font></strong></span><br />m_yvalues<span class="operator"><strong><font color="#663300">[</font></strong></span>n<span class="operator"><strong><font color="#663300">] =</font></strong></span> y<span class="operator"><strong><font color="#663300">;	<br />};</font></strong></span><br />string GetZ<span class="operator"><strong><font color="#663300">(</font></strong></span>string key<span class="operator"><strong><font color="#663300">)	<br />{</font></strong></span><span class="flow"><font color="#ff0000"><br />return</font></span> m_zvalues<span class="operator"><strong><font color="#663300">[</font></strong></span>key<span class="operator"><strong><font color="#663300">];	<br />};</font></strong></span><span class="type"><font color="#ff6633"><br />void</font></span> PutZ<span class="operator"><strong><font color="#663300">(</font></strong></span>string key<span class="operator"><strong><font color="#663300">,</font></strong></span>string z<span class="operator"><strong><font color="#663300">)	<br />{</font></strong></span><br />	m_zvalues<span class="operator"><strong><font color="#663300">[</font></strong></span>key<span class="operator"><strong><font color="#663300">] =</font></strong></span> z<span class="operator"><strong><font color="#663300">;	<br />};<br />};</font></strong></span><span class="type"><font color="#ff6633"><br />int</font></span><span class="keyword"><font color="#990000"> main</font></span><span class="operator"><strong><font color="#663300">(</font></strong></span><span class="type"><font color="#ff6633">int</font></span> argc<span class="operator"><strong><font color="#663300">,</font></strong></span><span class="type"><font color="#ff6633"> char</font></span><span class="operator"><strong><font color="#663300">*</font></strong></span> argv<span class="operator"><strong><font color="#663300">[]){</font></strong></span><br />propertytest test<span class="operator"><strong><font color="#663300">;</font></strong></span><br />test<span class="operator"><strong><font color="#663300">.</font></strong></span>x<span class="operator"><strong><font color="#663300"> =</font></strong></span><span class="int"><font color="#999900"> 3</font></span><span class="operator"><strong><font color="#663300">;</font></strong></span><br />test<span class="operator"><strong><font color="#663300">.</font></strong></span>y<span class="operator"><strong><font color="#663300">[</font></strong></span><span class="int"><font color="#999900">3</font></span><span class="operator"><strong><font color="#663300">] =</font></strong></span><span class="int"><font color="#999900"> 4</font></span><span class="operator"><strong><font color="#663300">;</font></strong></span><br />test<span class="operator"><strong><font color="#663300">.</font></strong></span>z<span class="operator"><strong><font color="#663300">[</font></strong></span><span class="string"><font color="#009900">"aaa"</font></span><span class="operator"><strong><font color="#663300">] =</font></strong></span><span class="string"><font color="#009900"> "aaa"</font></span><span class="operator"><strong><font color="#663300">;</font></strong></span><br />std<span class="operator"><strong><font color="#663300">::</font></strong></span>cout<span class="operator"><strong><font color="#663300"> &lt;&lt;</font></strong></span> test<span class="operator"><strong><font color="#663300">.</font></strong></span>x<span class="operator"><strong><font color="#663300"> &lt;&lt;</font></strong></span>std<span class="operator"><strong><font color="#663300">::</font></strong></span>endl<span class="operator"><strong><font color="#663300">;</font></strong></span><br />std<span class="operator"><strong><font color="#663300">::</font></strong></span>cout<span class="operator"><strong><font color="#663300"> &lt;&lt;</font></strong></span> test<span class="operator"><strong><font color="#663300">.</font></strong></span>y<span class="operator"><strong><font color="#663300">[</font></strong></span><span class="int"><font color="#999900">3</font></span><span class="operator"><strong><font color="#663300">] &lt;&lt;</font></strong></span>std<span class="operator"><strong><font color="#663300">::</font></strong></span>endl<span class="operator"><strong><font color="#663300">;</font></strong></span><br />std<span class="operator"><strong><font color="#663300">::</font></strong></span>cout<span class="operator"><strong><font color="#663300"> &lt;&lt;</font></strong></span> test<span class="operator"><strong><font color="#663300">.</font></strong></span>z<span class="operator"><strong><font color="#663300">[</font></strong></span><span class="string"><font color="#009900">"aaa"</font></span><span class="operator"><strong><font color="#663300">] &lt;&lt;</font></strong></span>std<span class="operator"><strong><font color="#663300">::</font></strong></span>endl<span class="operator"><strong><font color="#663300">;</font></strong></span>	getch<span class="operator"><strong><font color="#663300">();</font></strong></span><span class="flow"><font color="#ff0000"><br />return</font></span><span class="int"><font color="#999900"> 0</font></span><span class="operator"><strong><font color="#663300">;<br />}<br /><br /></font></strong></span>__declspec(property(get=[get方法名], put=[put方法名])) [类型] [属性名];<br />        __declspec(property)实际上就是做了一个映射，把你的方法映射成属性，以供访问。<br />get和put就是属性访问的权限，一个是读的权限，一个是写的权限。你可以根据需要来决定get和put两种权限的取舍。<br /></pre>
<img src ="http://www.cppblog.com/swo2006/aggbug/16298.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/swo2006/" target="_blank">swo</a> 2006-12-11 23:40 <a href="http://www.cppblog.com/swo2006/articles/16298.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>outlook</title><link>http://www.cppblog.com/swo2006/articles/16297.html</link><dc:creator>swo</dc:creator><author>swo</author><pubDate>Mon, 11 Dec 2006 15:28:00 GMT</pubDate><guid>http://www.cppblog.com/swo2006/articles/16297.html</guid><wfw:comment>http://www.cppblog.com/swo2006/comments/16297.html</wfw:comment><comments>http://www.cppblog.com/swo2006/articles/16297.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/swo2006/comments/commentRss/16297.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/swo2006/services/trackbacks/16297.html</trackback:ping><description><![CDATA[http://www.codeproject.com/com/outlookcontacts.asp<br /><br /><br /><pre><span class="pre"><font color="#000099">#include &lt;IOSTREAM&gt;</font></span><span class="keyword"><font color="#990000">using namespace</font></span> std<span class="operator"><strong><font color="#663300">;<br /></font></strong></span><span class="pre"><font color="#000099">#define interface class __declspec(novtable)</font></span>interface ICodec<span class="operator"><strong><font color="#663300"><br />{<br /></font></strong></span><span class="keyword"><font color="#990000">	public</font></span><span class="operator"><strong><font color="#663300">:</font></strong></span><span class="keyword"><font color="#990000">	virtual</font></span><span class="type"><font color="#ff6633"> bool</font></span> Decode<span class="operator"><strong><font color="#663300">(</font></strong></span><span class="type"><font color="#ff6633">char</font></span><span class="operator"><strong><font color="#663300"> *</font></strong></span> lpDataSrc<span class="operator"><strong><font color="#663300">,</font></strong></span><span class="type"><font color="#ff6633">unsigned int</font></span> nSrcLen<span class="operator"><strong><font color="#663300">,</font></strong></span><span class="type"><font color="#ff6633">char</font></span><span class="operator"><strong><font color="#663300"> *</font></strong></span> lpDataDst<span class="operator"><strong><font color="#663300">,</font></strong></span><span class="type"><font color="#ff6633">unsigned int</font></span><span class="operator"><strong><font color="#663300"> *</font></strong></span>pnDstLen<span class="operator"><strong><font color="#663300">);</font></strong></span><span class="keyword"><font color="#990000"><br />	virtual</font></span><span class="type"><font color="#ff6633"> bool</font></span> Encode<span class="operator"><strong><font color="#663300">(</font></strong></span><span class="type"><font color="#ff6633">char</font></span><span class="operator"><strong><font color="#663300"> *</font></strong></span> lpDataSrc<span class="operator"><strong><font color="#663300">,</font></strong></span><span class="type"><font color="#ff6633">unsigned int</font></span> nSrcLen<span class="operator"><strong><font color="#663300">,</font></strong></span><span class="type"><font color="#ff6633">char</font></span><span class="operator"><strong><font color="#663300"> *</font></strong></span> lpDataDst<span class="operator"><strong><font color="#663300">,</font></strong></span><span class="type"><font color="#ff6633">unsigned int</font></span><span class="operator"><strong><font color="#663300"> *</font></strong></span>pnDstLen<span class="operator"><strong><font color="#663300">);<br />};<br /></font></strong></span><span class="keyword"><font color="#990000">class</font></span> CCodec<span class="operator"><strong><font color="#663300"> :</font></strong></span><span class="keyword"><font color="#990000"> public</font></span> ICodec<span class="operator"><strong><font color="#663300"><br />{<br /></font></strong></span><span class="keyword"><font color="#990000">	public</font></span><span class="operator"><strong><font color="#663300">:</font></strong></span><span class="keyword"><font color="#990000">	virtual</font></span><span class="type"><font color="#ff6633"> bool</font></span> Decode<span class="operator"><strong><font color="#663300">(</font></strong></span><span class="type"><font color="#ff6633">char</font></span><span class="operator"><strong><font color="#663300"> *</font></strong></span> lpDataSrc<span class="operator"><strong><font color="#663300">,</font></strong></span><span class="type"><font color="#ff6633">unsigned int</font></span> nSrcLen<span class="operator"><strong><font color="#663300">,</font></strong></span><span class="type"><font color="#ff6633">char</font></span><span class="operator"><strong><font color="#663300"> *</font></strong></span> lpDataDst<span class="operator"><strong><font color="#663300">,</font></strong></span><span class="type"><font color="#ff6633">unsigned int</font></span><span class="operator"><strong><font color="#663300"> *</font></strong></span>pnDstLen<span class="operator"><strong><font color="#663300">)<br /> 	{</font></strong></span><br />		cout<span class="operator"><strong><font color="#663300"> &lt;&lt;</font></strong></span><span class="string"><font color="#009900"> "解码..."</font></span><span class="operator"><strong><font color="#663300"> &lt;&lt;</font></strong></span> endl<span class="operator"><strong><font color="#663300">;</font></strong></span><span class="flow"><font color="#ff0000"><br />		return</font></span><span class="bool"><strong> true</strong></span><span class="operator"><strong><font color="#663300">;	<br />	}</font></strong></span><span class="keyword"><font color="#990000"><br />	virtual</font></span><span class="type"><font color="#ff6633"> bool</font></span> Encode<span class="operator"><strong><font color="#663300">(</font></strong></span><span class="type"><font color="#ff6633">char</font></span><span class="operator"><strong><font color="#663300"> *</font></strong></span> lpDataSrc<span class="operator"><strong><font color="#663300">,</font></strong></span><span class="type"><font color="#ff6633">unsigned int</font></span> nSrcLen<span class="operator"><strong><font color="#663300">,</font></strong></span><span class="type"><font color="#ff6633">char</font></span><span class="operator"><strong><font color="#663300"> *</font></strong></span> lpDataDst<span class="operator"><strong><font color="#663300">,</font></strong></span><span class="type"><font color="#ff6633">unsigned int</font></span><span class="operator"><strong><font color="#663300"> *</font></strong></span>pnDstLen<span class="operator"><strong><font color="#663300">)	<br />	{	</font></strong></span><br />		cout<span class="operator"><strong><font color="#663300"> &lt;&lt;</font></strong></span><span class="string"><font color="#009900"> "编码..."</font></span><span class="operator"><strong><font color="#663300"> &lt;&lt;</font></strong></span> endl<span class="operator"><strong><font color="#663300">;</font></strong></span><span class="flow"><font color="#ff0000"><br />		return</font></span><span class="bool"><strong> true</strong></span><span class="operator"><strong><font color="#663300">;	<br />	}<br />};</font></strong></span><span class="type"><font color="#ff6633"><br />int</font></span><span class="keyword"><font color="#990000"> main</font></span><span class="operator"><strong><font color="#663300">(</font></strong></span><span class="type"><font color="#ff6633">int</font></span> argc<span class="operator"><strong><font color="#663300">,</font></strong></span><span class="type"><font color="#ff6633"> char</font></span><span class="operator"><strong><font color="#663300">*</font></strong></span> argv<span class="operator"><strong><font color="#663300">[]){<br /></font></strong></span> 	ICodec<span class="operator"><strong><font color="#663300"> *</font></strong></span> pCodec<span class="operator"><strong><font color="#663300"> =</font></strong></span><span class="keyword"><font color="#990000"> new</font></span> CCodec<span class="operator"><strong><font color="#663300">();</font></strong></span><br />	pCodec<span class="operator"><strong><font color="#663300">-&gt;</font></strong></span>Decode<span class="operator"><strong><font color="#663300">(</font></strong></span>NULL<span class="operator"><strong><font color="#663300">,</font></strong></span><span class="int"><font color="#999900">0</font></span><span class="operator"><strong><font color="#663300">,</font></strong></span>NULL<span class="operator"><strong><font color="#663300">,</font></strong></span>NULL<span class="operator"><strong><font color="#663300">);</font></strong></span><br />	pCodec<span class="operator"><strong><font color="#663300">-&gt;</font></strong></span>Encode<span class="operator"><strong><font color="#663300">(</font></strong></span>NULL<span class="operator"><strong><font color="#663300">,</font></strong></span><span class="int"><font color="#999900">0</font></span><span class="operator"><strong><font color="#663300">,</font></strong></span>NULL<span class="operator"><strong><font color="#663300">,</font></strong></span>NULL<span class="operator"><strong><font color="#663300">);</font></strong></span><span class="keyword"><font color="#990000"><br />	delete</font></span><span class="operator"><strong><font color="#663300"> (</font></strong></span>CCodec<span class="operator"><strong><font color="#663300">*)</font></strong></span>pCodec<span class="operator"><strong><font color="#663300">;</font></strong></span><span class="flow"><font color="#ff0000"><br />	return</font></span><span class="int"><font color="#999900"> 0</font></span><span class="operator"><strong><font color="#663300">;<br />}</font></strong></span><br />上面的ICodec接口等价于下面的定义：<br /><span class="keyword"><font color="#990000">class</font></span> ICodec<span class="operator"><strong><font color="#663300">{</font></strong></span><span class="keyword"><font color="#990000"><br />public</font></span><span class="operator"><strong><font color="#663300">:</font></strong></span><span class="keyword"><font color="#990000">	virtual</font></span><span class="type"><font color="#ff6633"> bool</font></span> Decode<span class="operator"><strong><font color="#663300">(</font></strong></span><span class="type"><font color="#ff6633">char</font></span><span class="operator"><strong><font color="#663300"> *</font></strong></span> lpDataSrc<span class="operator"><strong><font color="#663300">,</font></strong></span><span class="type"><font color="#ff6633">unsigned int</font></span> nSrcLen<span class="operator"><strong><font color="#663300">,</font></strong></span><span class="type"><font color="#ff6633">char</font></span><span class="operator"><strong><font color="#663300"> *</font></strong></span> lpDataDst<span class="operator"><strong><font color="#663300">,</font></strong></span><span class="type"><font color="#ff6633">unsigned int</font></span><span class="operator"><strong><font color="#663300"> *</font></strong></span>pnDstLen<span class="operator"><strong><font color="#663300">)=</font></strong></span><span class="int"><font color="#999900">0</font></span><span class="operator"><strong><font color="#663300">;</font></strong></span><span class="keyword"><font color="#990000"><br />virtual</font></span><span class="type"><font color="#ff6633"> bool</font></span> Encode<span class="operator"><strong><font color="#663300">(</font></strong></span><span class="type"><font color="#ff6633">char</font></span><span class="operator"><strong><font color="#663300"> *</font></strong></span> lpDataSrc<span class="operator"><strong><font color="#663300">,</font></strong></span><span class="type"><font color="#ff6633">unsigned int</font></span> nSrcLen<span class="operator"><strong><font color="#663300">,</font></strong></span><span class="type"><font color="#ff6633">char</font></span><span class="operator"><strong><font color="#663300"> *</font></strong></span> lpDataDst<span class="operator"><strong><font color="#663300">,</font></strong></span><span class="type"><font color="#ff6633">unsigned int</font></span><span class="operator"><strong><font color="#663300"> *</font></strong></span>pnDstLen<span class="operator"><strong><font color="#663300">)=</font></strong></span><span class="int"><font color="#999900">0</font></span><span class="operator"><strong><font color="#663300">;<br />};</font></strong></span></pre><br /><img src ="http://www.cppblog.com/swo2006/aggbug/16297.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/swo2006/" target="_blank">swo</a> 2006-12-11 23:28 <a href="http://www.cppblog.com/swo2006/articles/16297.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>How To Automate Outlook Using Visual C++/MFC</title><link>http://www.cppblog.com/swo2006/articles/16289.html</link><dc:creator>swo</dc:creator><author>swo</author><pubDate>Mon, 11 Dec 2006 13:57:00 GMT</pubDate><guid>http://www.cppblog.com/swo2006/articles/16289.html</guid><wfw:comment>http://www.cppblog.com/swo2006/comments/16289.html</wfw:comment><comments>http://www.cppblog.com/swo2006/articles/16289.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/swo2006/comments/commentRss/16289.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/swo2006/services/trackbacks/16289.html</trackback:ping><description><![CDATA[
		<h2 class="subTitle" id="tocHeadRef">MORE INFORMATION</h2>
		<script type="text/javascript"><![CDATA[oadTOCNode(1, 'moreinformation');]]&gt;</script> Follow the steps below to build and run the example: 
        <table class="list ol"><tbody><tr><td class="number">1.</td><td class="text">Start Visual C++ and create a new MFC EXE dialog-based
            application.</td></tr><tr><td class="number">2.</td><td class="text">Add a button to your dialog.</td></tr><tr><td class="number">3.</td><td class="text">Double-click the button to add a handler for it, and add
            the following code:<br /><code></code><pre class="code">   // Start Outlook.<br />   // If it is already running, you'll use the same instance...<br />   _Application olApp;<br />   COleException e;<br />   if(!olApp.CreateDispatch("Outlook.Application", &amp;e)) {<br />      CString str;<br />      str.Format("CreateDispatch() failed w/error 0x%08lx", e.m_sc);<br />      AfxMessageBox(str, MB_SETFOREGROUND);<br />      return;<br />   }<br /><br />   // Logon. Doesn't hurt if you are already running and logged on...<br />   NameSpace olNs(olApp.GetNamespace("MAPI"));<br />   COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);<br />   olNs.Logon(covOptional, covOptional, covOptional, covOptional);<br /><br />   // Create and open a new contact<br />   _ContactItem olItem(olApp.CreateItem(2));<br /><br />   // Setup Contact information...<br />   olItem.SetFullName("James Smith");<br />   COleDateTime bdDate;<br />   bdDate.SetDate(1975, 9, 15);<br />   olItem.SetBirthday(bdDate);<br />   olItem.SetCompanyName("Microsoft");<br />   olItem.SetHomeTelephoneNumber("704-555-8888");<br />   olItem.SetEmail1Address("someone@microsoft.com");<br />   olItem.SetJobTitle("Developer");<br />   olItem.SetHomeAddress("111 Main St.\nCharlotte, NC 28226");<br /><br />   // Save Contact<br />   olItem.Save();<br /><br />   // Create a new appointment<br />   _AppointmentItem olAppt(olApp.CreateItem(1));<br /><br />   // Schedule it for two minutes from now...<br />   COleDateTime apptDate = COleDateTime::GetCurrentTime();   <br />   olAppt.SetStart((DATE)apptDate + DATE(2.0/(24.0*60.0)));<br /><br />   // Set other appointment info...<br />   olAppt.SetDuration(60);<br />   olAppt.SetSubject("Meeting to discuss plans...");<br /><br />   olAppt.SetBody("Meeting with James to discuss plans.");<br />   olAppt.SetLocation("Home Office");<br />   olAppt.SetReminderMinutesBeforeStart(1);<br />   olAppt.SetReminderSet(TRUE);<br /><br />   // Save Appointment<br />   olAppt.Save();<br /><br />   // Prepare a new mail message<br />   _MailItem olMail(olApp.CreateItem(0));<br />   olMail.SetTo("someone@microsoft.com");<br />   olMail.SetSubject("About our meeting...");<br />   olMail.SetBody(<br />      "Hi James,\n\n"<br />      "\tI'll see you in two minutes for our meeting!\n\n"<br />      "Btw: I've added you to my contact list!");<br /><br />   // Send the message!<br />   olMail.Send();<br /><br />   AfxMessageBox("All done.", MB_SETFOREGROUND);<br />   olNs.Logoff();<br /></pre></td></tr><tr><td class="number">4.</td><td class="text">Bring up the ClassWizard (Control-W) click the Automation
            Tab, and choose "From a type library" under the Add Class menu.</td></tr><tr><td class="number">5.</td><td class="text">In the dialog box that comes up, navigate to the directory
            where Outlook is installed, and choose the Outlook type library (see table
            below). Select all the items it finds, and click OK to have ClassWizard
            generate MFC wrapper classes for all of them:
            <table class="table" cellspacing="1"><tbody><tr><th>Outlook Version</th><th>Type Library</th></tr><tr><td>97</td><td>msoutl8.olb</td></tr><tr><td>98</td><td>msoutl85.olb</td></tr><tr><td>2000</td><td>msoutl9.olb</td></tr><tr><td>2002</td><td>msoutl.olb</td></tr><tr><td>2003</td><td>msoutl.olb</td></tr></tbody></table><br /></td></tr><tr><td class="number">6.</td><td class="text">Add the following just before the implementation of your
            button handler:<br /><code></code><pre class="code">   #include "msoutl85.h" // for Outlook 2000 use msoutl9.h<br />                         // for Outlook 2002 &amp; Outlook 2003 use msoutl.h<br /><br />   // Ole-initialization class.<br />   class OleInitClass {<br />   public:<br />      OleInitClass() {<br />         OleInitialize(NULL);<br />      }<br />      ~OleInitClass() {<br />         OleUninitialize();<br />      }<br />   };<br />   // This global class calls OleInitialize() at<br />   // application startup, and calls OleUninitialize()<br />   // at application exit...<br />   OleInitClass g_OleInitClass;<br /></pre></td></tr><tr><td class="number">7.</td><td class="text">Compile and run the project. Once it has run, you should
            have a new contact named James Smith, an appointment scheduled in two minutes
            with a reminder to appear in one minute, and have sent a message to
            someone@microsoft.com. Also, because you added a birthday for your contact
            (9/15), a recurring event was added for your Outlook Calendar to remind you on
            that day.</td></tr></tbody></table><div class="topOfPage"><table><tbody><tr><td class="image"><a href="http://support.microsoft.com/default.aspx?scid=kb;en-us;220600#top"><img src="http://support.microsoft.com/library/images/support/kbgraphics/public/en-us/uparrow.gif" alt="Back to the top" title="Back to the top" /></a></td><td class="text"><a href="http://support.microsoft.com/default.aspx?scid=kb;en-us;220600#top">Back to the top</a></td></tr></tbody></table></div><h3 id="tocHeadRef">Automating Microsoft Outlook 2000, 2002, and 2003</h3><script type="text/javascript"><![CDATA[oadTOCNode(2, 'moreinformation');]]&gt;</script> You can use the sample code previously described to automate
        Outlook 2000, 2002, and 2003 with one small change. The Outlook 97 Namespace
        class member has changed to _Namespace in Outlook 2000, 2002, and 2003. To use
        the code above for automating Outlook 2000, 2002, and 2003 change this line: <code></code><pre class="code">Namespace olNS(olApp.GetNames("MAPI"));<br /></pre> to: <code></code><pre class="code">_Namespace olNS(olApp.GetNames("MAPI"));<br /></pre><img src ="http://www.cppblog.com/swo2006/aggbug/16289.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/swo2006/" target="_blank">swo</a> 2006-12-11 21:57 <a href="http://www.cppblog.com/swo2006/articles/16289.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>读取Outlook收件箱中信的类型(HTML/RTF/WORD/TEXT)</title><link>http://www.cppblog.com/swo2006/articles/16286.html</link><dc:creator>swo</dc:creator><author>swo</author><pubDate>Mon, 11 Dec 2006 13:01:00 GMT</pubDate><guid>http://www.cppblog.com/swo2006/articles/16286.html</guid><wfw:comment>http://www.cppblog.com/swo2006/comments/16286.html</wfw:comment><comments>http://www.cppblog.com/swo2006/articles/16286.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/swo2006/comments/commentRss/16286.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/swo2006/services/trackbacks/16286.html</trackback:ping><description><![CDATA[
		<p>Dim OL As New Outlook.Application<br />Dim OLNameSP As Outlook.NameSpace<br />Dim OLMFolder As Outlook.MAPIFolder<br />Dim OLMItem As Outlook.MailItem<br />Dim i As Integer</p>
		<p>Set OLNameSP = OL.GetNamespace("MAPI")<br />Set OLMFolder = OLNameSP.GetDefaultFolder(olFolderInbox)<br />For i = 1 To OLMFolder.Items.Count<br />    Set OLMItem = OLMFolder.Items.Item(i)<br />    Select Case OLMItem.GetInspector.EditorType<br />        Case olEditorText<br />            Debug.Print i &amp; "   " &amp; "olEditorText"<br />'            Debug.Print OLMItem.Body<br />        Case olEditorHTML<br />            Debug.Print i &amp; "   " &amp; "olEditorHTML"<br />'            Debug.Print OLMItem.HTMLBody<br />        Case olEditorRTF<br />            Debug.Print i &amp; "   " &amp; "olEditorRTF"<br />            <br />        Case olEditorWord<br />            Debug.Print i &amp; "   " &amp; "olEditorWord"<br />'            Debug.Print OLMItem.GetInspector.EditorType<br />        Case Else<br />            Debug.Print i &amp; "   " &amp; "Unknow"<br />    End Select<br />Next</p>
<img src ="http://www.cppblog.com/swo2006/aggbug/16286.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/swo2006/" target="_blank">swo</a> 2006-12-11 21:01 <a href="http://www.cppblog.com/swo2006/articles/16286.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>读取Outlook收件箱中信的类型</title><link>http://www.cppblog.com/swo2006/articles/16285.html</link><dc:creator>swo</dc:creator><author>swo</author><pubDate>Mon, 11 Dec 2006 13:00:00 GMT</pubDate><guid>http://www.cppblog.com/swo2006/articles/16285.html</guid><wfw:comment>http://www.cppblog.com/swo2006/comments/16285.html</wfw:comment><comments>http://www.cppblog.com/swo2006/articles/16285.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/swo2006/comments/commentRss/16285.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/swo2006/services/trackbacks/16285.html</trackback:ping><description><![CDATA[try{<br />                FormList-&gt;ListView1-&gt;Clear();<br />                _ApplicationPtr pApp;<br />                _NameSpace* pNS;<br />                AddressLists* pAddr;<br />                AddressEntries * pAddrEntries;<br />                AddressEntry* pEntry;<br />                AddressList* pList;<br />                int count,count1;<br />                pApp = this-&gt;OutlookApplication1-&gt;get_Application();<br />                pNS = pApp-&gt;GetNamespace(WideString("MAPI"));<br />                pAddr = pNS-&gt;AddressLists;<br />                count = pAddr-&gt;Count;
<p>                WideString email;</p><p>                email.SetLength(128);<br />                //emailname.SetLength(128);</p><p>                for(int i = 1;i &lt;= count;i++)<br />                {<br />                        pList = pAddr-&gt;Item(TVariant(i));<br />                        pAddrEntries = pList-&gt;get_AddressEntries();<br />                        count1 = pAddrEntries-&gt;Count;<br />                        for(int j = 1;j &lt;= count1;j++)<br />                        {<br />                                pEntry = pAddrEntries-&gt;Item(TVariant(j));<br />                                //pEntry-&gt;get_Name(&amp;emailname);<br />                                pEntry-&gt;get_Address(&amp;email);<br />                               
//this-&gt;Memo1-&gt;Lines-&gt;Add(AnsiString(emailname.c_bstr()) +
"\t"+AnsiString(email.c_bstr()));<br />                                TListItem * ListItem;<br />                                ListItem = FormList-&gt;ListView1-&gt;Items-&gt;Add();<br />                                ListItem-&gt;Caption = "";<br />                                ListItem-&gt;SubItems-&gt;Add(AnsiString(email.c_bstr()));</p><p>                                ListItem-&gt;Checked = true;<br />                        }</p><p>                }<br />                ListView1-&gt;SetFocus();<br />                ListView1-&gt;Update();<br />        }<br />        catch(...)<br />        {<br />                try{<br />                        HRESULT hRes;<br />                        //LPADRBOOK lpAdrBook;<br />                        DelphiInterface&lt;IAddrBook&gt;  lpAdrBook;<br />                //LPWABOBJECT lpWABObject;<br />                        DelphiInterface&lt;IWABObject&gt;  lpWABObject;<br />                //LPWAB_PARAM lpWABParam = NULL;<br />                DWORD Reserved2 = NULL;</p><p>                        char szPath[MAX_PATH];<br />                        SHGetFolderPathX(szPath);<br />                        char * s = "\\System\\wab32.dll";<br />                        strcat(szPath, s);</p><p>                HINSTANCE hinstLib;<br />                hinstLib = LoadLibrary(szPath);</p><p>               // hinstLib = LoadLibrary(s.c_str()+"\\System\\wab32.dll");<br />                fWABOpen procWABOpen;</p><p>                if (hinstLib != NULL)<br />                {<br />                // 获取"Wab32.dll"内部涵数WABOpen的进程地址<br />                procWABOpen = (fWABOpen) GetProcAddress(hinstLib, "WABOpen");</p><p>                if (procWABOpen != NULL)<br />                {<br />                hRes = (procWABOpen)(&amp;lpAdrBook,&amp;lpWABObject,NULL,Reserved2);<br />                //_ASSERTE(hRes == S_OK);<br />                if (hRes != S_OK)<br />                                                exit(1);</p><p>                ULONG lpcbEntryID;<br />                ENTRYID *lpEntryID;<br />                hRes = lpAdrBook-&gt;GetPAB(<br />                &amp;lpcbEntryID,<br />                &amp;lpEntryID<br />                        );<br />                //_ASSERTE(hRes == S_OK);<br />                if (hRes != S_OK)<br />                                                exit(2);</p><p>                ULONG ulFlags = MAPI_BEST_ACCESS;<br />                ULONG ulObjType = NULL;<br />                //LPUNKNOWN lpUnk = NULL;<br />                                        DelphiInterface&lt;IABContainer&gt;  lpContainer;<br />                hRes = lpAdrBook-&gt;OpenEntry(<br />                                                lpcbEntryID,<br />                lpEntryID,<br />                NULL,<br />                ulFlags,<br />                &amp;ulObjType,<br />                (LPUNKNOWN FAR *)&amp;lpContainer<br />                        );</p><p>                ulFlags = NULL;</p><p>                if (ulObjType == MAPI_ABCONT)<br />                {</p><p>                //IABContainer *lpContainer = static_cast &lt;IABContainer *&gt;(lpUnk);</p><p>                LPMAPITABLE lpTable = NULL;<br />                hRes = lpContainer-&gt;GetContentsTable(<br />                ulFlags,<br />                &amp;lpTable<br />                        );<br />                //_ASSERT(lpTable);<br />                ULONG ulRows;<br />                hRes = lpTable-&gt;GetRowCount(0,&amp;ulRows);<br />                //_ASSERTE(hRes == S_OK);<br />                SRowSet *lpRows;</p><p>                hRes = lpTable-&gt;QueryRows(<br />                ulRows,// 获取所有行<br />                0,<br />                &amp;lpRows<br />                );<br />                ListView1-&gt;Clear();<br />                for(ULONG i=0;i&lt;lpRows-&gt;cRows;i++)<br />                {<br />                SRow *lpRow = &amp;lpRows-&gt;aRow[i];<br />                AnsiString strTemp;</p><p>                for(ULONG j=0;j&lt;lpRow-&gt;cValues;j++)<br />                {<br />                SPropValue *lpProp = &amp;lpRow-&gt;lpProps[j];</p><p>                if (lpProp-&gt;ulPropTag == PR_EMAIL_ADDRESS_A)<br />                 {<br />                    TListItem * ListItem;<br />                    ListItem = FormList-&gt;ListView1-&gt;Items-&gt;Add();<br />                    ListItem-&gt;Caption = "";<br />                    ListItem-&gt;SubItems-&gt;Add((char *)lpProp-&gt;Value.lpszA);<br />                //strTemp =(char *)lpProp-&gt;Value.lpszA;</p><p>                 ListItem-&gt;Checked = true;<br />                                                                }<br />                }<br />                //ListEmail-&gt;Lines-&gt;Add(strTemp);</p><p>                lpWABObject-&gt;FreeBuffer(lpRow);<br />                }<br />                lpWABObject-&gt;FreeBuffer(lpRows);<br />                }<br />                }<br />                //FreeLibrary(hinstLib);（装载和释放 dll 文件的地方改成在主程序执行之前装载，结束的时候释放）<br />                }</p><br />                }<br />                catch(...)<br />                {<br />                        MessageBox(Handle,"没有找到地址薄!","提示信息",MB_OK);<br />                }<br />        }<img src ="http://www.cppblog.com/swo2006/aggbug/16285.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/swo2006/" target="_blank">swo</a> 2006-12-11 21:00 <a href="http://www.cppblog.com/swo2006/articles/16285.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用Delphi开发Office Word插件</title><link>http://www.cppblog.com/swo2006/articles/16109.html</link><dc:creator>swo</dc:creator><author>swo</author><pubDate>Thu, 07 Dec 2006 15:58:00 GMT</pubDate><guid>http://www.cppblog.com/swo2006/articles/16109.html</guid><wfw:comment>http://www.cppblog.com/swo2006/comments/16109.html</wfw:comment><comments>http://www.cppblog.com/swo2006/articles/16109.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/swo2006/comments/commentRss/16109.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/swo2006/services/trackbacks/16109.html</trackback:ping><description><![CDATA[
		<div class="Section1" style="">
				<h3 style="text-align: center;" align="center">
						<b>使用</b>
						<b>Delphi</b>
						<b>开发Office</b>
						<b> Word插件</b>
				</h3>
				<p class="MsoNormal">    在Office 2000中提供了基于COM的插件开发框架，这使得我们可以利用Delphi来扩展Office的功能。</p>
				<p class="MsoNormal">   
在Delphi
3,4中编写基于COM的插件，我们需要自己创建COM接口的封装类，更糟糕的是要想支持事件的话还需要使用连接点（connection
points）对象来实现事件回调，这是非常麻烦的。但在Delphi 5中这一切就变得非常轻松了，Delphi
5的类型库引入工具提供了/L+的开关，可以自动为我们生成封装好的OLE Server。这下子再也没有什么好抱怨的了。</p>
				<p class="40">Office 2000 插件框架</p>
				<p class="MsoNormal">    在Microsoft'的网站上，知识库文章（Knowledge Base article Q230689）中有一篇：Office 2000 COM Add-In Written in Visual C++ 。文章中提供了一个例子(<a href="http://support.microsoft.com/download/support/mslfiles/COMADDIN.EXE">http://support.microsoft.com/download/support/mslfiles/ COMADDIN.EXE</a>)。这篇文章详细地描述了插件框架中的COM接口。仔细研究一下C++代码就可以了解如何编写Office 2000插件。</p>
				<p class="MsoNormal">    Office 2000插件其实就是一个实现了IDTExtensibility2接口的自动化对象。IDTExtensibility2 接口相当简单，插件需要实现接口定义的全部５个函数：</p>
				<p class="MsoNormal">    OnConnection：当应用程序连接到插件时会调用这个函数。插件在函数中接收下列初始化信息——应用程序对象模型进入点的指针，连接模式(是手工加入还是通过命令行载入), 应用程序的对象模型指针和用户自定义的信息。</p>
				<p class="MsoNormal">    OnDisconnection：当应用程序断开插件时被调用，插件应该在这里清除先前分配的资源，删除它添加到应用程序的界面元素。</p>
				<p class="MsoNormal">    OnStartupComplete：这个函数是当应用程序自动启动插件时被调用的。调用时，其他的插件都已经被加载到了内存，这时可以同其他插件进行通信。这个函数还适合添加用户界面元素。</p>
				<p class="MsoNormal">    OnBeginShutdown：当应用程序准备关闭并将要断开插件时会被调用，这时插件应该停止接收用户输入。</p>
				<p class="MsoNormal">    OnAddInsUpdate：当注册的插件列表被改变后会被调用。如果我们的插件不依赖于其他插件，这个函数可以为空。</p>
				<p class="40">接口、类型库和常数</p>
				<p class="MsoNormal">   
创建插件前，我们需要引入COM对象的接口类型库。这里使用Delphi 5带的TlibImp.exe
(Delphi5\Bin目录下)来引入类型库。新版的TlibImp.exe支持新的/L+开关，可以自动创建一个OLE
Server的Delphi封装。IDTExtensibility2接口是在MSADDNDR.DLL文件中声明的，位于\Program
Files\Common Files\Designer\ 目录下。调用TLIBIMP\L+\Program Files\Common
Files\ Designer\MSADDNDR.DLL会生成AddInDesignerObjects_TLB.pas 和
AddInDesignerObjects_TLB.dcr两个文件。在项目的uses部分加上对上面文件的引用以便使用接口。clause of
our project to gain access to the
interface.使用时注意：TLIBIMP重命名接口为_IDTExtensibility2。</p>
				<p class="MsoNormal">   
本文中将使用Word
2000作为例子，如果想编写Outlook、Excel或其他Office程序的插件需要引入相应特定的类型库。比如Word的类型库是定义在\
Program Files\Microsoft
Office\Office\MSWORD9.OLB文件中。类似的，Excel、Access和OutLook类型库分别定义在EXCEL9.OLB、
MSACC9.OLB和MSOUTL9.OLB文件中。引入的接口生成在Office_TLB.pas和Word_TLB.pas单元中。</p>
				<p class="MsoNormal">    注意：Office 2000的插件无法工作在Office 97的应用程序中。</p>
				<p class="40">最简单的插件</p>
				<p class="MsoNormal">    现在让我们来实现一个最简单的插件，它只实现了IDTExtensibility2接口而没有实现任何比较有意义的功能，但对于演示如何实现插件是一个很好的开始。</p>
				<p class="MsoNormal">   
插件可以以进程内或进程外COM服务器的形式实现，在本文中，我们创建的是进程内COM服务器。在Delphi中，选择菜单File |
New命令，然后创建一个ActiveX Library，保存生成的文件，再创建一个自动化对象（Automation
Object），类名定义为AddIn，把实现单元保存为AddInMain.pas。在AddInMain.pas单元的uses部分添加对
AddinDesignerObjects_TLB，Word_TLB和Office_TLB单元的引用。最后添加
IDTExtensibility2 接口到类定义部分定义类要实现的接口。类定义如下： </p>
				<p class="C">    type</p>
				<p class="C">      TAddIn = class(TAutoObject, IAddIn, IDTExtensibility2) </p>
				<p class="C">    ...</p>
				<p class="MsoNormal">    在类声明的protected部分，添加IDTExtensibility2 接口声明的方法定义，代码示意如下：</p>
				<p class="C">    // IDTExtensibility2 methods</p>
				<p class="C">    procedure OnConnection(const Application: IDispatch; </p>
				<p class="C">      ConnectMode: ext_ConnectMode; const AddInInst: IDispatch; </p>
				<p class="C">    var custom: PSafeArray); safecall;</p>
				<p class="C">    procedure OnDisconnection(RemoveMode: ext_DisconnectMode; </p>
				<p class="C">    var custom: PSafeArray); safecall;</p>
				<p class="C">    procedure OnAddInsUpdate(var custom: PSafeArray); safecall;</p>
				<p class="C">    procedure OnStartupComplete(var custom: PSafeArray);  safecall;</p>
				<p class="C">    procedure OnBeginShutdown(var custom: PSafeArray); safecall;</p>
				<p class="MsoNormal">    使用快捷键[Ctrl][Shift][C]来完成类定义，并添加方法的实现部分的框架到单元中。为了测试插件，可添加下面代码到OnConnection方法中： </p>
				<p class="MsoNormal">    ShowMessage('连接到' + WordApp.Name); </p>
				<p class="MsoNormal">    添加下面代码到OnDisconnection方法的实现部分： </p>
				<p class="MsoNormal">    ShowMessage('断开插件'); </p>
				<p class="MsoNormal">    这样就完成了一个最简单的插件了，接下来就是编译并注册插件到Word中去。</p>
				<p class="40">注册Office插件</p>
				<p class="MsoNormal">   
同其他COM对象一样，一个Office插件必须在系统中注册后才能使用。在Delphi中选择Run | Register ActiveX
Server菜单命令，就可以注册我们刚才创建的插件。除了标准的COM注册，还需要进行Office 相关的注册，这需要在注册表中创建一个新的键值：</p>
				<p class="MsoNormal">    HKEY_CURRENT_USER\Software\Microsoft\Office\</p>
				<p class="MsoNormal">      &lt;AppName&gt;\Addins\&lt;AddInProgID&gt; </p>
				<p class="MsoNormal">    &lt;AppName&gt;就是插件宿主应用程序的名字（这里是Word），&lt;AddInProgID&gt;是自动化对象的名字（这里是DIWordAddIn.AddIn，ActiveX library和类名的组合）。</p>
				<p class="MsoNormal">    HKEY_CURRENT_USER \ Software \ Microsoft \ Office \ Word \ Addins\DIWord AddIn.AddIn</p>
				<p class="MsoNormal">   
我们还需要在这个键值下创建几个值：一个DWORD类型的名为LoadBehavior的值决定插件是如何加载及被应用程序调用的。在本文中我们设定它为
3–相当于１和２的结合就是应用程序连接插件并在启动时自动加载。值的意义列在表1.2中，各种值可以相互组合。</p>
				<p class="1">表1.2</p>
				<div align="center">
						<table border="1" cellpadding="0" cellspacing="0">
								<tbody>
										<tr>
												<td valign="top" width="74">
														<p class="C" style="text-align: center; line-height: 14pt;" align="center">值</p>
												</td>
												<td valign="top" width="194">
														<p class="C" style="text-align: center; line-height: 14pt;" align="center">意    义</p>
												</td>
										</tr>
										<tr>
												<td valign="top" width="74">
														<p class="C" style="text-align: center; line-height: 14pt;" align="center">$0</p>
												</td>
												<td valign="top" width="194">
														<p class="C" style="line-height: 14pt;">  断开，不加载 </p>
												</td>
										</tr>
										<tr>
												<td valign="top" width="74">
														<p class="C" style="text-align: center; line-height: 14pt;" align="center">$1</p>
												</td>
												<td valign="top" width="194">
														<p class="C" style="line-height: 14pt;">  连接，加载 </p>
												</td>
										</tr>
										<tr>
												<td valign="top" width="74">
														<p class="C" style="text-align: center; line-height: 14pt;" align="center">$2</p>
												</td>
												<td valign="top" width="194">
														<p class="C" style="line-height: 14pt;">  自动启动加载</p>
												</td>
										</tr>
										<tr>
												<td valign="top" width="74">
														<p class="C" style="text-align: center; line-height: 14pt;" align="center">$8</p>
												</td>
												<td valign="top" width="194">
														<p class="C" style="line-height: 14pt;">  只有当用户请求时才加载</p>
												</td>
										</tr>
										<tr>
												<td valign="top" width="74">
														<p class="C" style="text-align: center; line-height: 14pt;" align="center">$16</p>
												</td>
												<td valign="top" width="194">
														<p class="C" style="line-height: 14pt;">  只在下次程序启动时加载一次</p>
												</td>
										</tr>
								</tbody>
						</table>
				</div>
				<p class="MsoNormal">    还有一些其他的值可以出现在注册表键值下，比如定义出现在应用程序COM管理器对话框中的名字，以及设定是否可以从命令行激活插件。</p>
				<p class="40">Office 2000用户界面</p>
				<p class="MsoNormal">    Ｏffice应用程序共享一组通用的用户界面元素对象、菜单条、工具条通用控件（比如工具条按钮和组合编辑框）以及Office小助手。</p>
				<p class="MsoNormal">   
此前引入的Word类型库就包括了这些通用对象的类型库，但是Delphi引入时并没有像通常那样建立一个封装好的OLE
Server，我们不得不手工创建一个Office公开的CommandBarButton对象的Delphi封装。这个对象对应于Office应用程序
的一个简单的菜单项或工具条按钮。</p>
				<p class="MsoNormal">   
对大多数的Microsoft的应用程序来说，Application对象代表对象模型的切入点。Office
Application类提供了对CommandBars属性的引用。CommandBar对象包括工具条、浮动工具条和菜单。Office对象模型允许
我们创建或更新已有的CommandBars对象。Office_TLB.pas单元包含了ICommandBar接口，它可以被用来修改
CommandBar对象。</p>
				<p class="MsoNormal">   
CommandBar有一个Controls集合属性，对应于一组CommandBarControl控件。CommandBarControl控件对应
于放置在工具条上的控件，比如一个CommandBarButton对应一个简单的工具条按钮（或菜单项），CommandBarCombo控件对应组合
编辑框，CommandBarPopup对应于下拉菜单和CommandBarActiveX对应于ActiveX控制。</p>
				<p class="MsoNormal">   
在Office_TLB.pas单元中，除了ICommandBarButton接口，还有一个ICommandBarButtonEvents接口用来
提供对工具条上控件的事件支持。事件的支持通常是通过连接点、事件接收连接到可连接对象来实现。但这比较麻烦，我们还可以通过更简单的办法来实现事件支
持。检查一下Delphi在word_tlb.pas单元创建的TWordApplication的实现代码可以发现Delphi封装了每一个可连接对
象，自动实现了事件接收机制。这个单元可以作为一个范本用来创建自定义的对接口对象的封装。</p>
				<p class="MsoNormal">   
BtnSvr.pas单元包含了一个手工创建的Delphi封装。除了按标准的Delphi属性方式实现了CommandBarButton对象的属性
外，还实现了InitServerData、InvokeEvent、Connect、ConnectTo和Disconnect方法。可以注意到这部分
完全是模仿TWordApplication实现部分编写的CommandBarButton事件实现。主要就是在InitServerData方法中定
义服务器数据。根据Office_TLB.pas中不同的接口GUID，定义一个CommandBarButton接口的内部的接口Fintf，设定
InvokeEvent方法来激活基于定义在事件接口部分的DispID的Delphi事件支持。最后，Connect、ConnectTo和
Disconnect方法设定Fintf给需要的接口并接收相应的事件。</p>
				<p class="MsoNormal">    定义在BtnSvr.pas单元中的Delphi封装类命名为TButtonServer。它需要从TOleServer对象继承以便支持事件处理。</p>
				<p class="40">同应用程序连接</p>
				<p class="MsoNormal">   
有了工具条按钮封装类后，接下来要声明一个TWordApplication域来保存对Word
Application对象的引用。此外还需要为新的工具条定义一个接口指针以及两个域使用新的TButtonServer类来保存我们要创建的新的工具
条按钮和菜单项。</p>
				<p class="MsoNormal">    在插件类的private部分添加：</p>
				<p class="C">    FWordApp : TWordApplication; </p>
				<p class="C">    DICommandBar : CommandBar; </p>
				<p class="C">    DIBtn : TButtonServer; </p>
				<p class="C">    DIMenu : TButtonServer; </p>
				<p class="MsoNormal">    在OnConnection方法中，保存应用程序指针：</p>
				<p class="C">    var</p>
				<p class="C">      WA : Word_TLB._Application; </p>
				<p class="C">    begin</p>
				<p class="C">      FWordApp := TWordApplication.Create(nil);</p>
				<p class="C">      WA := Application as Word_TLB._Application; </p>
				<p class="C">      WordApp.ConnectTo(WA); </p>
				<p class="C">      …………………………..</p>
				<p class="MsoNormal">   
TWordApplication是Delphi 5中带的Server组件，ConnectTo
方法是用来连接插件和Word提供的接口。因为TWordApplication
把接口事件映射成了Delphi事件，我们可以直接使用标准的Delphi语法来设定事件处理过程。示意如下：</p>
				<p class="MsoNormal">    WordApp.OnEventX := EventXHandler;</p>
				<p class="MsoNormal">    比如我们如果想在Word的选区发生改变时实现某项功能，就可以设定OnWindowSelectionChange 事件。</p>
				<p class="40">插件如何创建新的工具条、按钮和菜单</p>
				<p class="MsoNormal">    在创建新的工具条和按钮前，需要为按钮的OnClick过程先创建事件处理函数，下面就是简单的处理函数例子：</p>
				<p class="C">    procedure TAddIn.TestClick(const Ctrl: OleVariant; </p>
				<p class="C">      var CancelDefault: OleVariant); </p>
				<p class="C">    begin</p>
				<p class="C">      ShowMessage('有人点我了!'); </p>
				<p class="C">      CancelDefault := True; </p>
				<p class="C">    end;</p>
				<p class="MsoNormal">   
CancelDefault参数用来设定是否替代缺省的菜单或工具条按钮的处理过程。这里不需要设定这个参数，因为我们将在插件中创建一个新的按钮。插件
注册为在程序启动时被加载，所以OnStartupComplete方法一定会被调用，用这个方法创建用户界面元素是比较合适的。这里定义BtnIntf
为CommandBarControl接口类型(要创建的CommandBarButton的父类接口)。接下来的任务是确定自定义的工具条是否已经被创
建了</p>
				<p class="C">    DICommandBar := nil;</p>
				<p class="C">    for i := 1 to WordApp.CommandBars.Count do</p>
				<p class="C">      if (WordApp.CommandBars.Item[i].Name ='Delphi') then</p>
				<p class="C">        DICommandBar := WordApp.CommandBars.Item[i]; </p>
				<p class="C">        // 确定是否已经注册了命令条</p>
				<p class="C">      if (not Assigned(DICommandBar)) then begin</p>
				<p class="C">        DICommandBar:=</p>
				<p class="C">WordApp.CommandBars.Add('Delphi',EmptyParam,EmptyParam,EmptyParam); </p>
				<p class="C">        DICommandBar.Set_Protection(msoBarNoCustomize) </p>
				<p class="C">    end;</p>
				<p class="MsoNormal">   
先给工具条起一个唯一的名字“Delphi”，然后在启动时检查工具条是否已经被创建了。如果是的话就把它赋值给DICommandBar，否则调用
Word的CommandBars属性的Add方法创建一个新的工具条。接着给工具条添加msoBarNoCustomize的保护，这可以防止用户添加
或删除工具条上的按钮。这时DICommandBar指向一个有效的工具条，我们可以从接口的Controls集合中获得工具条按钮接口指针。如果工具条
上没有控件，就创建一个新的按钮。</p>
				<p class="C">    if (DICommandBar.Controls.Count &gt; 0) then</p>
				<p class="C">      BtnIntf := DICommandBar.Controls.Item[1] </p>
				<p class="C">     else</p>
				<p class="C">      BtnIntf := DICommandBar.Controls.Add(msoControlButton, </p>
				<p class="C">      EmptyParam, EmptyParam, EmptyParam, EmptyParam); </p>
				<p class="MsoNormal">    注意：集合中第一项是以1为底的，而不像Delphi中那样通常以0为底。现在我们获得了需要的工具条按钮接口，然后要创建一个基于按钮接口的TButtonServer 类封装。</p>
				<p class="C">     DIBtn := TButtonServer.Create(nil);</p>
				<p class="C">     DIBtn.ConnectTo(BtnIntf as _CommandBarButton); </p>
				<p class="C">     DIBtn.Caption := 'Delphi Test'; </p>
				<p class="C">     DIBtn.Style := msoButtonCaption; </p>
				<p class="C">     DIBtn.Visible := True; </p>
				<p class="C">     DIBtn.OnClick := TestClick; </p>
				<p class="MsoNormal">    这里使用ConnectTo 方法连接按钮的事件并设定先前创建的OnClick事件处理过程。最后，要确认使工具条可见。</p>
				<p class="MsoNormal">    DICommandBar.Set_Visible(True); </p>
				<p class="MsoNormal">   
TLIBIMP程序创建了一个只读的而非可读写的工具条Visible 属性，但可以使用Set_Visible
方法来设定显示属性（不能生成可读写的属性可能是TLIBIMP的bug）。添加新的菜单项类似于前面，首先创建菜单的OnClick事件处理函数，下面
这个过程遍历被选文本的第一段，并设定其边框样式：</p>
				<p class="C">    procedure TAddIn.MenuClick(const Ctrl: OleVariant; </p>
				<p class="C">      var CancelDefault: OleVariant); </p>
				<p class="C">    var</p>
				<p class="C">      Sel : Word_TLB.Selection; </p>
				<p class="C">      Par : Word_TLB.Paragraph; </p>
				<p class="C">    begin</p>
				<p class="C">      Sel := WordApp.ActiveWindow.Selection; </p>
				<p class="C">      if (Sel.Type_ in [wdSelectionNormal, </p>
				<p class="C">        wdSelectionIP]) then begin</p>
				<p class="C">        Par := Sel.Paragraphs.Item(1); </p>
				<p class="C">      if (Par.Borders.OutsideLineStyle &lt; wdLineStyleInset) then</p>
				<p class="C">        Par.Borders.OutsideLineStyle := 1 + Par.Borders.OutsideLineStyle</p>
				<p class="C">      else</p>
				<p class="C">        Par.Borders.OutsideLineStyle := wdLineStyleNone; </p>
				<p class="C">      end;</p>
				<p class="C">    end;</p>
				<p class="MsoNormal">    在OnStartupComplete方法中，添加下面的代码来获得工具菜单的接口指针，查找自定义的的菜单项，如果没有就创建新的，然后设定它的OnClick事件：</p>
				<p class="C">    ToolsBar := WordApp.CommandBars['Tools']; </p>
				<p class="C">    MenuIntf := ToolsBar.FindControl(EmptyParam, EmptyParam, </p>
				<p class="C">      'DIMenu', EmptyParam, EmptyParam); </p>
				<p class="C">    if (not Assigned(MenuIntf)) then</p>
				<p class="C">      MenuIntf := ToolsBar.Controls.Add(msoControlButton, </p>
				<p class="C">      EmptyParam, EmptyParam, EmptyParam, EmptyParam); </p>
				<p class="C">      DIMenu := TButtonServer.Create(nil);</p>
				<p class="C">      DIMenu.ConnectTo(MenuIntf as _CommandBarButton); </p>
				<p class="C">      DIMenu.Caption := 'Delp&amp;hi Menu'; </p>
				<p class="C">      DIMenu.ShortcutText := ''; </p>
				<table align="left" cellpadding="0" cellspacing="0" hspace="0" vspace="0" width="296">
						<tbody>
								<tr>
										<td align="left" valign="top">
												<p class="MsoNormal" style="text-align: center;" align="center">
														<img src="http://hubdog.csdn.net/Hubdog/word.files/image002.gif" v:shapes="_x0000_i1025" border="0" height="204" width="258" />
												</p>
												<p class="1">图1.34</p>
										</td>
								</tr>
						</tbody>
				</table>
				<p class="C">      DIMenu.Tag := 'DIMenu'; </p>
				<p class="C">      DIMenu.Visible := True; </p>
				<p class="C">      DIMenu.OnClick := MenuClick; </p>
				<p class="MsoNormal">    CommandBar接口的FindControl方法使用唯一的标识来查找菜单项，如果找到了控件就赋值给 MenuIntf，如果没有找到就创建一个新的菜单项。图1.34显示了自定义的工具条。</p>
				<p class="40">清理资源</p>
				<p class="MsoNormal">    注意应该在OnBeginShutdown 方法中清理用户界面元素：</p>
				<p class="C">      if (Assigned(DIBtn)) then</p>
				<p class="C">      begin</p>
				<p class="C">        DIBtn.Free; </p>
				<p class="C">        DIBtn := nil;</p>
				<p class="C">      end;</p>
				<p class="C">      if (Assigned(DIMenu)) then </p>
				<p class="C">      begin</p>
				<p class="C">        DIMenu.Free; </p>
				<p class="C">        DIMenu := nil;</p>
				<p class="C">      end;</p>
				<p class="C">      if (Assigned(DICommandBar)) then begin</p>
				<p class="C">        DICommandBar.Delete; </p>
				<p class="C">        DICommandBar := nil;</p>
				<p class="C">      end;</p>
				<p class="MsoNormal">   
因为插件的框架是通用的，我们可以将同样的OLE Server
DLL用于多个应用程序，方法就是确定将激活插件的应用程序，并使用合适的对象模型。最简单的判断方法是在OnConnection中把应用程序的
IDispatch的接口指针赋值给一个OleVariant变量，然后使用相应的Name 属性来确定相应的程序：</p>
				<p class="C">    var</p>
				<p class="C">      AppVar : OleVariant; </p>
				<p class="C">    begin</p>
				<p class="C">      AppVar := Application; </p>
				<p class="C">      if (AppVar.Name = 'Outlook') then</p>
				<p class="C">      begin</p>
				<p class="C">        ... </p>
				<p class="C">      end</p>
				<p class="C">      else if (AppVar.Name = 'Microsoft Word') then</p>
				<p class="C">      begin</p>
				<p class="C">        ... </p>
				<p class="C">      end else ... </p>
				<p class="MsoNormal">    最后，要想获得关于Office开发和Office 2000插件创建更详细的资料，可以查阅microsoft.public.officedev新闻组上的信息。 </p>
		</div>
<img src ="http://www.cppblog.com/swo2006/aggbug/16109.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/swo2006/" target="_blank">swo</a> 2006-12-07 23:58 <a href="http://www.cppblog.com/swo2006/articles/16109.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>com</title><link>http://www.cppblog.com/swo2006/articles/16072.html</link><dc:creator>swo</dc:creator><author>swo</author><pubDate>Wed, 06 Dec 2006 15:29:00 GMT</pubDate><guid>http://www.cppblog.com/swo2006/articles/16072.html</guid><wfw:comment>http://www.cppblog.com/swo2006/comments/16072.html</wfw:comment><comments>http://www.cppblog.com/swo2006/articles/16072.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/swo2006/comments/commentRss/16072.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/swo2006/services/trackbacks/16072.html</trackback:ping><description><![CDATA[http://www.codeproject.com/com/AddinProjectFramework.asp<br /><br /><br /><div style="font-weight: bold; font-size: 16pt;">An ATL Component in C++ that fires COM events</div>http://www.codeproject.com/com/nbd_ipc.asp<br /><br /><br />http://www.codeproject.com/com/AddinProjectFramework.asp<br /><br /><br /><br />http://www.codeproject.com/com/LocalCOMServerClient.asp<br /><img src ="http://www.cppblog.com/swo2006/aggbug/16072.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/swo2006/" target="_blank">swo</a> 2006-12-06 23:29 <a href="http://www.cppblog.com/swo2006/articles/16072.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>cdo</title><link>http://www.cppblog.com/swo2006/articles/15801.html</link><dc:creator>swo</dc:creator><author>swo</author><pubDate>Wed, 29 Nov 2006 15:44:00 GMT</pubDate><guid>http://www.cppblog.com/swo2006/articles/15801.html</guid><wfw:comment>http://www.cppblog.com/swo2006/comments/15801.html</wfw:comment><comments>http://www.cppblog.com/swo2006/articles/15801.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/swo2006/comments/commentRss/15801.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/swo2006/services/trackbacks/15801.html</trackback:ping><description><![CDATA[http://www.codeproject.com/com/OutlookForms.asp<br /><br />http://www.cdolive.com/cdo.htm<br /><br />http://www.codeproject.com/useritems/OutlookAdd-in.asp<br /><br />http://www.codeproject.com/com/OutlookForms.asp<br /><img src ="http://www.cppblog.com/swo2006/aggbug/15801.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/swo2006/" target="_blank">swo</a> 2006-11-29 23:44 <a href="http://www.cppblog.com/swo2006/articles/15801.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用 SMTP 发送电子邮件（转自微软）</title><link>http://www.cppblog.com/swo2006/articles/15797.html</link><dc:creator>swo</dc:creator><author>swo</author><pubDate>Wed, 29 Nov 2006 15:26:00 GMT</pubDate><guid>http://www.cppblog.com/swo2006/articles/15797.html</guid><wfw:comment>http://www.cppblog.com/swo2006/comments/15797.html</wfw:comment><comments>http://www.cppblog.com/swo2006/articles/15797.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/swo2006/comments/commentRss/15797.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/swo2006/services/trackbacks/15797.html</trackback:ping><description><![CDATA[http://blog.csdn.net/tgh1981/archive/2004/11/18/185859.aspx<img src ="http://www.cppblog.com/swo2006/aggbug/15797.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/swo2006/" target="_blank">swo</a> 2006-11-29 23:26 <a href="http://www.cppblog.com/swo2006/articles/15797.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Using Native COM Support in Microsoft Visual C++</title><link>http://www.cppblog.com/swo2006/articles/15795.html</link><dc:creator>swo</dc:creator><author>swo</author><pubDate>Wed, 29 Nov 2006 15:24:00 GMT</pubDate><guid>http://www.cppblog.com/swo2006/articles/15795.html</guid><wfw:comment>http://www.cppblog.com/swo2006/comments/15795.html</wfw:comment><comments>http://www.cppblog.com/swo2006/articles/15795.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/swo2006/comments/commentRss/15795.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/swo2006/services/trackbacks/15795.html</trackback:ping><description><![CDATA[
		<div class="postTitle"> </div>
		<a name="_cdosys_using_native_com_support_in_microsoft_visual_c_">
		</a>Using Native COM Support in Microsoft Visual C++<p>Microsoft Visual C++ version 5.0 or later has native COM support through the <code>#import</code>
statement. Using this statement allows you to automatically add type
information contained in a type library into your project. The
generated files normally have the same name as the component DLL with
the extensions .tlh and .tli. </p><p>When using the #import statement,
make sure to import the ActiveX Data Objects type information before
the Microsoft CDO for Windows 2000 type information. The following
examples demonstrate using the <code>#import</code> statement:</p><pre>#import "c:\program files\common files\system\ado\msado15.dll" no_namespace raw_interfaces_only　rename("EOF", "EndOfFile")#import &lt;cdosys.dll&gt; no_namespace raw_interfaces_only#include "cdosysstr.h"#include "cdosyserr.h"void main() {  CoInitialize(NULL);  IMessage* pMsg = NULL;  HRESULT hr =     CoCreateInstance( __uuidof(Message),                      NULL,                      CLSCTX_INPROC_SERVER,                      __uuidof(IMessage),                     (void**) &amp;pMsg                     );  ...  CoUninitialize();}</pre><p><b>Note</b></p><p class="indent">You
must have the ADO 2.5 type information in the same namespace as CDO
type information. CDO interfaces make use of ADO types in arguments.
These types are not qualified using namespaces in the CDO interface
definitions. If these types are not in the same namespace, errors will
occur. You can do one of the following to solve this problem: </p><ul><li>Rename the default <b>ADODB </b>ADO namespace to <b>CDO.</b></li><li>Import type information into the global namespace, if feasible. </li><li>Rename both <b>CDO</b> and <b>ADODB</b> to another namespace, such as <b>CDOSYS</b>. </li></ul><p>The GUID definitions for ADO and CDO types can be retrieved using the <code>__uuidof</code> operator supported by Visual C++. You can use <code>#import</code> flags to specify the CLSID_XXX and IID_XXX definitions if this format is desired.</p><p>Consider the following issues when using the #import statement: </p><ol><li>The
header file generated by the #import directive does not contain the
module constant definitions contained within the type library. However,
the Platform SDK provides two separate headers that can be included
within your project so that these constants are available. These files
are <code>cdosysstr.h</code> and <code>cdosyserr.h</code>. The first
contains the field name constants, and the second includes the CDO
custom HRESULT error codes. If you do not include these, you will have
to manually insert these values. For example, the field
"urn:schemas:httpmail:to" has an associated constant called <b>cdoTo</b> in the string constant header file <code>cdosysstr.h</code>. </li><li>The <code>#import</code>
statement strips the default values for arguments when generating the
header files. If you use #import, you will need to explicitly specify
the defaults. For example: <pre>hr = pBp-&gt;AddBodyPart(-1); // the -1 is the default value in cdosys.h</pre></li></ol><p><b>Using Interface Pointer Wrapper Classes with Import</b></p><p>The <code>raw_interfaces_only</code> flag to <code>#import</code>
directive suppresses the creation of "smart pointer" C++ wrapper
classes. However, in many cases these wrappers simplify working with
CDO in C++. The following example demonstrates using the wrapper
classes produced by the <code>#import</code> statement:</p><pre>#import "c:\program files\common files\system\ado\msado15.dll" no_namespace　rename("EOF", "EndOfFile")#import &lt;cdosys.dll&gt; no_namespace#include "cdosysstr.h"#include "cdosyserr.h"void main() {  CoInitialize(NULL);  {  try {   IMessagePtr iMsg(__uuidof(Message));   FieldsPtr Flds;   Flds = iMsg-&gt;Fields;   Flds-&gt;Item[cdoTo]-&gt;Value      = _variant_t("example@example.com");   Flds-&gt;Item[cdoFrom]-&gt;Value    = _variant_t("example@example.com");   Flds-&gt;Item[cdoSubject]-&gt;Value = _variant_t("a test");   Flds-&gt;Item[cdoTextDescription]-&gt;Value = _variant_t("this is a test");   Flds-&gt;Update();   iMsg-&gt;Send();  }  catch( _com_error err) {   //  ... }  }  CoUninitialize();  return 1;}</pre><p><b>Using the CDO Namespace</b></p><p>You
can use namespaces with the #import statement. However, when you import
the ADO type information, you must make sure to add it to the <b>CDO</b>
namespace, or suppress the namespace by adding it to the global
namespace. If you do not do this, all ADO type information will reside
in the ADODB namespace by default, and CDO arguments that are ADO types
will not resolve at compile time. The following example demonstrates
this:</p><pre>#import "c:\program files\common files\system\ado\msado15.dll" rename("ADODB","CDO")　rename("EOF", "EndOfFile")#import &lt;cdosys.dll&gt;#include "cdosysstr.h"#include "cdosyserr.h"void main() {  CoInitialize(NULL);  {  try {   CDO::IMessagePtr iMsg(__uuidof(CDO::Message));   CDO::FieldsPtr Flds;   Flds = iMsg-&gt;Fields;   Flds-&gt;Item[cdoTo]-&gt;Value      = _variant_t("example@example.com");   Flds-&gt;Item[cdoFrom]-&gt;Value    = _variant_t("example@example.com");   Flds-&gt;Item[cdoSubject]-&gt;Value = _variant_t("a test");   Flds-&gt;Item[cdoTextDescription]-&gt;Value = _variant_t("this is a test");   Flds-&gt;Update();   iMsg-&gt;Send();  }  catch( _com_error err) {   //  ...  }}  }  CoUninitialize();  return 1;}</pre><br /><img src ="http://www.cppblog.com/swo2006/aggbug/15795.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/swo2006/" target="_blank">swo</a> 2006-11-29 23:24 <a href="http://www.cppblog.com/swo2006/articles/15795.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>利用CDO实现邮件回执功能</title><link>http://www.cppblog.com/swo2006/articles/15793.html</link><dc:creator>swo</dc:creator><author>swo</author><pubDate>Wed, 29 Nov 2006 15:12:00 GMT</pubDate><guid>http://www.cppblog.com/swo2006/articles/15793.html</guid><wfw:comment>http://www.cppblog.com/swo2006/comments/15793.html</wfw:comment><comments>http://www.cppblog.com/swo2006/articles/15793.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/swo2006/comments/commentRss/15793.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/swo2006/services/trackbacks/15793.html</trackback:ping><description><![CDATA[http://blog.csdn.net/irvine007/archive/2006/02/22/606117.aspx<br /><br /><div class="postTitle"><a href="http://blog.csdn.net/greystar/archive/2004/08/28/87316.aspx"><img src="http://blog.csdn.net/images/authorship.gif" border="0" height="13" width="15" /> 使用CDO发送邮件</a></div><p>引用CDO组件，SYSTEM32下的CDOSYS。DLL，增加一个包装器</p><p>using CDO;</p><p> //本例使用CDO来实现发送邮件，可带验证,此示例在活动目录内向外网发送邮件成功  profession2k office2k office2k3下通过 VS2,2,VS2k3,要引用CDOSYS<br />   Configuration conf=new Configuration();<br />   //以下部分设置参数(服务器,端号，用户名，密码，发送邮件帐号，回复邮箱帐号)<br />   conf.Fields[CdoConfiguration.cdoSendUsingMethod].Value=CdoSendUsing.cdoSendUsingPort;<br />   conf.Fields[CdoConfiguration.cdoSMTPServer].Value="smtp.21cn.com";<br />   conf.Fields[CdoConfiguration.cdoSMTPServerPort].Value=25;<br />   conf.Fields[CdoConfiguration.cdoSMTPAccountName].Value="<a href="mailto:greystar@21cn.com">greystar@21cn.com</a>";<br />   conf.Fields[CdoConfiguration.cdoSendUserReplyEmailAddress].Value="\"greystar\" &lt;<a href="mailto:Greystar@skyregister.com">Greystar@skyregister.com</a>&gt;";<br />   conf.Fields[CdoConfiguration.cdoSendEmailAddress].Value="\"greystar\" &lt;<a href="mailto:greystar@21cn.com">greystar@21cn.com</a>&gt;";<br />   conf.Fields[CdoConfiguration.cdoSMTPAuthenticate].Value=CdoProtocolsAuthentication.cdoBasic;<br />   conf.Fields[CdoConfiguration.cdoSendUserName].Value="<a href="mailto:greystar@21cn.com">greystar@21cn.com</a>";<br />   conf.Fields[CdoConfiguration.cdoSendPassword].Value="XXXXXXX";</p><p>   conf.Fields.Update();<br />   MessageClass msg=new MessageClass();</p><p>   msg.Configuration=conf;<br />  <br />   msg.To="<a href="mailto:greystar@21cn.com">greystar@21cn.com</a>";<br />   msg.Subject= "注册确认通知";<br />   msg.HTMLBody="注册信息"<br />     msg.From="<a href="mailto:greystar@21cn.com">greystar@21cn.com</a>";</p><p>   msg.Send();   </p><br /><img src ="http://www.cppblog.com/swo2006/aggbug/15793.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/swo2006/" target="_blank">swo</a> 2006-11-29 23:12 <a href="http://www.cppblog.com/swo2006/articles/15793.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>A Complete ActiveX Web Control Tutorial</title><link>http://www.cppblog.com/swo2006/articles/15760.html</link><dc:creator>swo</dc:creator><author>swo</author><pubDate>Tue, 28 Nov 2006 16:37:00 GMT</pubDate><guid>http://www.cppblog.com/swo2006/articles/15760.html</guid><wfw:comment>http://www.cppblog.com/swo2006/comments/15760.html</wfw:comment><comments>http://www.cppblog.com/swo2006/articles/15760.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/swo2006/comments/commentRss/15760.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/swo2006/services/trackbacks/15760.html</trackback:ping><description><![CDATA[http://www.codeproject.com/com/CompleteActiveX.asp<img src ="http://www.cppblog.com/swo2006/aggbug/15760.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/swo2006/" target="_blank">swo</a> 2006-11-29 00:37 <a href="http://www.cppblog.com/swo2006/articles/15760.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Office2000下内部COM插件的编程实现</title><link>http://www.cppblog.com/swo2006/articles/15756.html</link><dc:creator>swo</dc:creator><author>swo</author><pubDate>Tue, 28 Nov 2006 15:42:00 GMT</pubDate><guid>http://www.cppblog.com/swo2006/articles/15756.html</guid><wfw:comment>http://www.cppblog.com/swo2006/comments/15756.html</wfw:comment><comments>http://www.cppblog.com/swo2006/articles/15756.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/swo2006/comments/commentRss/15756.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/swo2006/services/trackbacks/15756.html</trackback:ping><description><![CDATA[http://www.vckbase.com/document/viewdoc/?id=539<br />http://www.codeproject.com/csharp/OutlookConnector.asp<br /><img src ="http://www.cppblog.com/swo2006/aggbug/15756.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/swo2006/" target="_blank">swo</a> 2006-11-28 23:42 <a href="http://www.cppblog.com/swo2006/articles/15756.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>INFO：使用 Visual C++ 使 Office 自动化</title><link>http://www.cppblog.com/swo2006/articles/15755.html</link><dc:creator>swo</dc:creator><author>swo</author><pubDate>Tue, 28 Nov 2006 15:03:00 GMT</pubDate><guid>http://www.cppblog.com/swo2006/articles/15755.html</guid><wfw:comment>http://www.cppblog.com/swo2006/comments/15755.html</wfw:comment><comments>http://www.cppblog.com/swo2006/articles/15755.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/swo2006/comments/commentRss/15755.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/swo2006/services/trackbacks/15755.html</trackback:ping><description><![CDATA[
		<h1 class="title">
				<font size="5">INFO：使用 Visual C++ 使 Office 自动化</font>
		</h1>
		<div class="appliesToLink">
				<a href="http://support.microsoft.com/kb/238972/zh-cn#appliesto">察看本文应用于的产品</a>
		</div>
		<script><![CDATA[unction loadTOCNode(){}]]&gt;</script>
		<div class="articleProperty">
				<table>
						<tbody>
								<tr>
										<td>文章编号</td>
										<td>:</td>
										<td>238972</td>
								</tr>
								<tr>
										<td>最后修改</td>
										<td>:</td>
										<td>2006年3月30日</td>
								</tr>
								<tr>
										<td>修订</td>
										<td>:</td>
										<td>6.1</td>
								</tr>
						</tbody>
				</table>
		</div>
		<div style="display: block;" class="toc" id="tocDiv">
				<h5>本页</h5>
				<div>
						<a href="http://support.microsoft.com/kb/238972/zh-cn#" onclick="return tocScrollTo(this);">
								<img src="http://support.microsoft.com/library/images/support/kbgraphics/public/en-us/downarrow.gif" alt="概要" />
								<span class="tocTxt">概要</span>
						</a>
				</div>
				<div>
						<a href="http://support.microsoft.com/kb/238972/zh-cn#" onclick="return tocScrollTo(this);">
								<img src="http://support.microsoft.com/library/images/support/kbgraphics/public/en-us/downarrow.gif" alt="更多信息" />
								<span class="tocTxt">更多信息</span>
						</a>
						<div class="tocLine">
								<div>
										<a href="http://support.microsoft.com/kb/238972/zh-cn#" onclick="return tocScrollTo(this);">
												<img src="http://support.microsoft.com/library/images/support/kbgraphics/public/en-us/downarrow.gif" alt="自动化和 COM" />
												<span class="tocTxt">自动化和 COM</span>
										</a>
								</div>
								<div>
										<a href="http://support.microsoft.com/kb/238972/zh-cn#" onclick="return tocScrollTo(this);">
												<img src="http://support.microsoft.com/library/images/support/kbgraphics/public/en-us/downarrow.gif" alt="从 Visual C++ 使用自动化的三种方法" />
												<span class="tocTxt">从 Visual C++ 使用自动化的三种方法</span>
										</a>
								</div>
								<div>
										<a href="http://support.microsoft.com/kb/238972/zh-cn#" onclick="return tocScrollTo(this);">
												<img src="http://support.microsoft.com/library/images/support/kbgraphics/public/en-us/downarrow.gif" alt="如何使用 Office 类型库" />
												<span class="tocTxt">如何使用 Office 类型库</span>
										</a>
								</div>
								<div>
										<a href="http://support.microsoft.com/kb/238972/zh-cn#" onclick="return tocScrollTo(this);">
												<img src="http://support.microsoft.com/library/images/support/kbgraphics/public/en-us/downarrow.gif" alt="使嵌入的 Office 组件自动运行" />
												<span class="tocTxt">使嵌入的 Office 组件自动运行</span>
										</a>
								</div>
						</div>
				</div>
				<div>
						<a href="http://support.microsoft.com/kb/238972/zh-cn#" onclick="return tocScrollTo(this);">
								<img src="http://support.microsoft.com/library/images/support/kbgraphics/public/en-us/downarrow.gif" alt="参考" />
								<span class="tocTxt">参考</span>
						</a>
				</div>
		</div>
		<script type="text/javascript"><![CDATA[
      var sectionFilter = "type != 'notice' && type != 'securedata' && type != 'querywords'";
      var tocArrow = "/library/images/support/kbgraphics/public/en-us/downarrow.gif";
      var depthLimit = 10;
      var depth3Limit = 10;
      var depth4Limit = 5;
      var depth5Limit = 3;
      var tocEntryMinimum = 1;
    ]]&gt;</script>
		<script type="text/javascript" src="http://support.microsoft.com/common/script/gsfx/kbtoc.js??4">
		</script>
		<noscript>
		</noscript>
		<h2 class="subTitle" id="tocHeadRef">概要</h2>
		<script type="text/javascript"><![CDATA[oadTOCNode(1, 'summary');]]&gt;</script>
		<div class="sbody"> 您可以使用自动化功能从 Visual C++ 应用程序中控制 Microsoft Office 组件。本文提供使 Office 自动运行所需的基本信息以及指向相关资源和示例代码的指针。<div class="topOfPage"><table><tbody><tr><td class="image"><a href="http://support.microsoft.com/kb/238972/zh-cn#top"><img src="http://support.microsoft.com/library/images/support/en-us/uparrow.gif" alt="回到顶端" title="回到顶端" /></a></td><td class="text"><a href="http://support.microsoft.com/kb/238972/zh-cn#top">回到顶端</a></td></tr></tbody></table></div></div>
		<h2 class="subTitle" id="tocHeadRef">更多信息</h2>
		<script type="text/javascript"><![CDATA[oadTOCNode(1, 'moreinformation');]]&gt;</script>
自动化（以前称为 OLE 自动化）是一种技术，该技术允许您利用现有程序的功能并将其合并到您自己的应用程序中。例如，您可以在应用程序中使用
Microsoft Word 的拼写和语法检查功能，而不让用户看到 Microsoft Word。您甚至可以使用 Microsoft
Excel 的所有图表、打印和数据分析工具。该技术可以大大简化和加快您的开发。<div class="topOfPage"><table><tbody><tr><td class="image"><a href="http://support.microsoft.com/kb/238972/zh-cn#top"><img src="http://support.microsoft.com/library/images/support/en-us/uparrow.gif" alt="回到顶端" title="回到顶端" /></a></td><td class="text"><a href="http://support.microsoft.com/kb/238972/zh-cn#top">回到顶端</a></td></tr></tbody></table></div><h3 id="tocHeadRef">自动化和 COM</h3><script type="text/javascript"><![CDATA[oadTOCNode(2, 'moreinformation');]]&gt;</script>
自动化建立在组件对象模型 (COM) 的基础上。COM 是一种基于接口的标准软件结构，旨在将代码分离为独立的对象。可以将它看作是面向对象编程
(OOP)
范例的扩展，但是它也适用于单独的应用程序。每个对象都公开一组接口，到对象的所有通信（如初始化、通知和数据传输）都是通过这些接口进行的。<br /><br />
COM 还是随操作系统一起安装的动态链接库 (DLL)
所提供的一组服务。自动化会用到其中的许多服务。其中一个示例就是“封送处理”服务，该服务将客户端应用程序的调用打包到服务器应用程序接口的成员函数
中，然后将这些函数及其参数传递给服务器应用程序。服务器的接口可能会在客户端的内存空间中公开，但是，如果客户端是 .exe
文件，而且在自己的进程空间运行，则不会出现这种情况。封送处理还可以跨越进程边界从服务器的方法中获取返回值，并将这些值安全地传递给客户端调用。<br /><br /> 各种 COM 库提供了对自动化非常重要的许多其他服务。关于这些服务的信息来源包括：
<table class="list ul"><tbody><tr><td class="bullet">•</td><td class="text">“Inside OLE - Second Edition”，Kraig Brockschmidt 著，ISBN 1-55615-843-2</td></tr><tr><td class="bullet">•</td><td class="text">“Inside COM”，Dale Rogerson 著，ISBN 1-57231-349-8</td></tr><tr><td class="bullet">•</td><td class="text">“Automation Programmer's Reference”，ISBN 1-57231-584-9</td></tr></tbody></table><div class="topOfPage"><table><tbody><tr><td class="image"><a href="http://support.microsoft.com/kb/238972/zh-cn#top"><img src="http://support.microsoft.com/library/images/support/en-us/uparrow.gif" alt="回到顶端" title="回到顶端" /></a></td><td class="text"><a href="http://support.microsoft.com/kb/238972/zh-cn#top">回到顶端</a></td></tr></tbody></table></div><h3 id="tocHeadRef">从 Visual C++ 使用自动化的三种方法</h3><script type="text/javascript"><![CDATA[oadTOCNode(2, 'moreinformation');]]&gt;</script> 可通过以下三种基本方法来使用自动化：MFC、#import 和 C/C++：
<table class="list ul"><tbody><tr><td class="bullet">•</td><td class="text">借
助于 MFC，您可以使用 Visual C++ ClassWizard 从 Microsoft Office
类型库生成“包装类”。这些类以及诸如 COleVariant、COleSafeArray 和 COleException 之类的其他 MFC
类可简化自动化任务。此方法优于其他方法，通常建议使用该方法，并且大部分 Microsoft 知识库示例都使用 MFC。</td></tr><tr><td class="bullet">•</td><td class="text">#import 是 Visual C++ 5.0 中引入的一个新指令，它可以从指定的类型库创建 VC++“智能指针”。它的功能非常强大，但通常不建议使用它，因为它与 Microsoft Office 应用程序一起使用时，经常会出现引用计数问题。</td></tr><tr><td class="bullet">•</td><td class="text">C/C++
自动化要困难得多，但有时为了避免由于使用 MFC 时所造成的开销或避免使用 #import 时所出现的问题，需要使用该方法。基本上，您会用到
CoCreateInstance() 这样的 API 以及诸如 IDispatch 和 IUnknown 之类的 COM 接口。</td></tr></tbody></table> 必须注意，C++ 中的自动化与普通的 C 中的自动化稍有不同，因为 COM 是围绕 C++ 类设计的。

有关使用 C 进行自动化的其他信息，请单击下面的文章编号，以查看 Microsoft 知识库中相应的文章：

<div class="indent"><a class="KBlink" href="http://support.microsoft.com/kb/181473/">181473</a><span class="pLink"> (http://support.microsoft.com/kb/181473/)</span>

如何在 C 应用程序中而不是在 C++ 中使用 OLE 自动化

</div><div class="topOfPage"><table><tbody><tr><td class="image"><a href="http://support.microsoft.com/kb/238972/zh-cn#top"><img src="http://support.microsoft.com/library/images/support/en-us/uparrow.gif" alt="回到顶端" title="回到顶端" /></a></td><td class="text"><a href="http://support.microsoft.com/kb/238972/zh-cn#top">回到顶端</a></td></tr></tbody></table></div><h3 id="tocHeadRef">如何使用 Office 类型库</h3><script type="text/javascript"><![CDATA[oadTOCNode(2, 'moreinformation');]]&gt;</script>
类型库与 C/C++ 头文件类似。它包含服务器发布的接口、方法和属性。您可以使用 Visual C++ 附带的 OLE/COM 对象查看器
(Oleview.exe) 来查看类型库。下面列出了 Microsoft Office 95、Microsoft Office
97、Microsoft Office 2000 和 Microsoft Office XP 的类型库文件名：<br /><br /><table class="table" cellspacing="1"><tbody><tr><th>Office 应用程序</th><th>类型库</th></tr><tr><td>Word 95 及更低版本</td><td>wb70en32.tlb</td></tr><tr><td>Excel 95 及更低版本</td><td>xl5en32.olb</td></tr><tr><td>PowerPoint 95 及更低版本</td><td>PowerPoint.tlb</td></tr><tr><td>Access 95 及更低版本</td><td>msaccess.tlb</td></tr><tr><td>Binder 95</td><td>binder.tlb</td></tr><tr><td>Schedule+</td><td>sp7en32.olb</td></tr></tbody></table><img src ="http://www.cppblog.com/swo2006/aggbug/15755.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/swo2006/" target="_blank">swo</a> 2006-11-28 23:03 <a href="http://www.cppblog.com/swo2006/articles/15755.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>实现Office的COM插件</title><link>http://www.cppblog.com/swo2006/articles/15754.html</link><dc:creator>swo</dc:creator><author>swo</author><pubDate>Tue, 28 Nov 2006 14:55:00 GMT</pubDate><guid>http://www.cppblog.com/swo2006/articles/15754.html</guid><wfw:comment>http://www.cppblog.com/swo2006/comments/15754.html</wfw:comment><comments>http://www.cppblog.com/swo2006/articles/15754.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/swo2006/comments/commentRss/15754.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/swo2006/services/trackbacks/15754.html</trackback:ping><description><![CDATA[
		<table border="0" cellpadding="4" cellspacing="0" width="95%">
				<tbody>
						<tr>
								<td class="textblack">
										<b>实现Office的COM插件</b>
								</td>
						</tr>
						<tr>
								<td class="textblack"> 作者： ZDNet China <br />2003-08-11  01:43 PM</td>
						</tr>
						<tr>
								<td class="textgray">
										<p>当软件开发者考虑扩展Microsoft Office时，最常想到方法就是是使用VB了。实际上，用C++和ATL扩展Office是相当容易的。<br /><br />
    我将向你演示如何建立项目以及如何把Office插件作为COM对象注册到Office中去。（本文用Outlook来作为插件的主程序。）<br /></p>
										<p>
										</p>
										<h5 align="left">项目的建立<br /></h5>
										<p align="left">让我们建立一个新的ATL项目。首先，添加一个叫着Plugin的简单COM对象。用类向导把_IDTExtensibility2接口添加到Plugin类中。（别忘了选中IsupportErrorInfo复选框。）<br /><br />
类向导会把下述方法添加到Plugin类中：OnConnection、OnDisconnection、OnAddinsUpdate、
OnStartupComplete、OnBeginShutdown。本文只处理OnConnection和OnDisconnection方法。<br /><br />
    然后，在Plugin头文件中创建一个类型定义（typedef，它只是用来简化代码的），如下所示：</p>
										<p align="left">
												<font color="#0066ff">#define APPID 102<br />
    class CPlugin;<br />
    typedef IDispEventImpl&lt;APPID, CPlugin, &amp;DIID_ApplicationEvents,<br />
    &amp;LIBID_Outlook,9,0&gt; OutLookSink; </font>
										</p>
										<p align="left">我们现在需要在Plugin类的继承列表中添加OutLookSink类：</p>
										<p align="left">
												<font color="#0066ff">class ATL_NO_VTABLE CPlugin :<br />
           public IPlugin,<br />
           public IDispatchImpl&lt;_IDTExtensibility2, 
    &amp;__uuidof(_IDTExtensibility2),<br />
                   &amp;LIBID_AddInDesignerObjects, 
    /* wMajor = */ 1, /* wMinor = */ 0&gt;,<br />
        public OutLookSink </font>
										</p>
										<p align="left">在Plugin.h文件中为Mso9.dll和Msoutl9.olb引入声明，如下所示：</p>
										<p align="left">
												<font color="#0066ff">#import "C:\Program Files\Common Files\Designer\msaddndr.dll" 
    \<br />
    raw_interfaces_only, \<br />
    raw_native_types, no_namespace, named_guids, auto_search<br /><br />
    #import "C:\Program Files\Microsoft Office\Office\mso9.dll" \<br />
    rename_namespace("Office") named_guids<br /><br />
    #import "C:\Program Files\Microsoft \<br />
     Office\Office\msoutl9.olb" \<br />
    rename_namespace("Outlook"), raw_interfaces_only, \<br />
     named_guids<br /><br />
    using namespace Office;<br />
    using namespace Outlook; </font>
										</p>
										<p align="left">注意，你需要按照你的系统中的文件路径来修正上面那些被引入文件的路径。</p>
										<br />
										<p align="left">
												<br />
										</p>
										<p align="left">你必须把Office扩展作为COM组件注册到Office中去。Visual C++自动产生.rgs文件来控制COM注册。我们将需要添加额外的项目加到.rgs文件来支持Office的自动注册。<br /><br />
    在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office键下，有若干个子键，每一个子键对应于系统中安装的每一个Office应用程序。在这些键中有插件关键字（add-in 
    key）。<br /></p>
										<br />
										<p>
    为了在Office中注册我们的COM对象，我们需要在插件键中添加新键。在HKEY_CURRENT_USER下同样有对应的树来控制单个用户的插件，而HKEY_LOCAL_MACHINE控制整个机器的插件。<br /><br />
    下面是.rgs文件中Outlook的插件注册码：</p>
										<p align="left">
												<font color="#0066ff">HKCU<br />
    {<br />
        NoRemove Software<br />
        {<br />
            NoRemove Microsoft<br />
            {<br />
                NoRemove 
    Office<br />
                {<br />
                    NoRemove 
    Outlook<br />
                    {<br />
                        NoRemove 
    Addins<br />
                        {<br />
                            ForceRemove 
    OutlookDemo.Plugin.1<br />
                            {<br />
                                val 
    FriendlyName = s 'Outlook Plugin'<br />
                                val 
    Description = s 'An Outlook plugin'<br />
                                val 
    LoadBehavior = d 3<br />
                                val 
    CommandLineSafe = d 0<br />
                            }<br />
                            <br />
                        }<br />
                    }<br />
                }<br />
            }<br />
        }<br />
    } </font>
										</p>
  这套注册项是为特定用户注册插件的，为了把插件设置为整个系统范围之内可用，只需把HKCU改为HKLM。<br /><br /><br /><br /><p>
LoadBehavior的值控制了主程序运行后插件的行为。为了让主程序开始运行后插件自动运行，把LoadBehavior的值设置为3。如果想让用户手工载入插件，就把LoadBehavior设置为8。<br /><br />如果你编译了这个项目，你就有了一个Outlook 插件；这个插件实际上没有做任何事，但是它的确是一个可以工作的插件。<br /><br />我们现在向这个插件添加一些功能。首先，添加一个新的成员变量：</p><p align="left">     <font color="#0066ff">_ApplicationPtr 
    m_pApp; </font></p><p align="left">然后设置OnConnection方法：</p><p align="left">    <font color="#0066ff">STDMETHOD(OnConnection)(LPDISPATCH 
    Application,<br />
                                                           
         ext_ConnectMode ConnectMode,<br />
                                                           
         LPDISPATCH AddInInst,<br />
                                                           
         SAFEARRAY * * custom)<br />
        {<br />
                 HRESULT 
    rslt = S_OK;<br />
                 try{<br />
                      m_pApp 
    = Application;<br />
                      
    OutLookSynch::DispEventAdvise(m_pApp);<br />
                 }catch(_com_error 
    &amp;e){<br />
                      
    OutputDebugString(e.ErrorMessage());<br />
                                        rslt 
    = E_UNEXPECTED;                <br />
                 }<br />
                 return 
    rslt;<br />
        } </font></p><p align="left">再设置与之对应的OnDisconnection方法，如下所示：</p><p align="left">    <font color="#0066ff">STDMETHOD(OnDisconnection)(ext_DisconnectMode 
    RemoveMode,SAFEARRAY<br />
    * * custom)<br />
          {<br />
                     HRESULT 
    rslt = S_OK;<br />
                     try{<br />
                           
    OutLookSynch::DispEventUnadvise(m_pApp);<br />
                     }catch(_com_error 
    &amp;e){<br />
                           
    OutputDebugString(e.ErrorMessage());<br />
                           rslt 
    = E_UNEXPECTED;<br />
                     }<br />
                     return 
    rslt;<br />
        } <br /></font></p><p>现在我们可以收到好几种事件，例如，OnNewMail事件。得到事件的信息以及它们的ID的最好方法就是打开MSVC工具菜单上的OLE/COM观察器（viewer）。</p><ol start="1" type="1"><li>进入File菜单并选择View Typelib。</li><li>浏览Msoutl9.olb文件。</li><li>Scroll down ApplicationEvents的dispinterface。注意OnNewMail事件的ID号为0x0000f003.。</li><li>向Cplugin类添加一个叫着OnNewMail的方法。</li><li>建立一个Sink映射来把OnNewMail方法关联到OnNewMail事件。</li></ol><p align="left">    <font color="#0066ff">BEGIN_SINK_MAP(CPlugin)<br />
                  SINK_ENTRY_EX(APPID, 
    Outlook::DIID_ApplicationEvents, /<br />
    0x0000f003, OnNewMail)<br />
        END_SINK_MAP() </font></p><p align="left">现在我们只需要完成OnNewMail事件处理函数了。</p><p>    <font color="#0066ff">void _stdcall OnNewMail(){<br />
               MessageBox(NULL, 
    "New Mail", NULL, MB_OK);<br />
        } </font></p><p align="left">如果你想消除这些讨厌的弹出式对话框（由该项目所创建），那么最简单方法就是遵循下面的步骤：</p><ol start="1" type="1"><li>进入Outlook的Tools | Options菜单项。</li><li>选择Other标签。</li><li>点击Advanced Options按钮。</li><li>点击COM 的插件按钮。</li><li>选中Outlook的Plugin项并点击Remove。</li></ol>

  
如你所见，Office的COM插件实现起来相对来说并不麻烦甚至可以说很轻松。创建一个COM Office插件最困难的计算出所有参数的初值。不过一旦你发现可以在OLE/COM查看器中得到这些信息，这也就不成问题了。<p align="left"><font color="#0066ff"><br /></font></p><br /><p align="left"></p></td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.cppblog.com/swo2006/aggbug/15754.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/swo2006/" target="_blank">swo</a> 2006-11-28 22:55 <a href="http://www.cppblog.com/swo2006/articles/15754.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>