📄 csdn_文档中心_创建更易理解的动态注释用户界面.htm
字号:
<TD align=middle width=500></TD></TR>
<TR>
<TD align=middle bgColor=#003399 height=10><FONT
color=#ffffff>出处</FONT></TD>
<TD height=10> <A
href="http://www.microsoft.com/china/msdn/technic/library/techart/dynmicannot.asp">http://www.microsoft.com/china/msdn/technic/library/techart/dynmicannot.asp</A></TD></TR>
<TR>
<TD align=middle height=10></TD>
<TD height=10></TD></TR></TBODY></TABLE><!--文章说明信息结束//-->
<TABLE border=0 width=600>
<TBODY>
<TR>
<TD align=left><BR><FONT face=宋体 size=2>Rob Sinclair 和 Brendan
McKeon <BR>Microsoft Corporation <BR>2000年9月 </FONT>
<P></P>
<P><B>摘要:</B> :作为 Microsoft Active Accessibility 2.0
系列的第一篇文章,本文论述了动态注释 (DA),一种使开发人员提高用户界面可用性的新技术。
<P><B>目录</B>
<UL>
<LI><A
href="http://www.microsoft.com/china/msdn/technic/library/techart/dynmicannot.asp#1">简介</A>
<LI><A
href="http://www.microsoft.com/china/msdn/technic/library/techart/dynmicannot.asp#2">什么是动态注释</A>
<LI><A
href="http://www.microsoft.com/china/msdn/technic/library/techart/dynmicannot.asp#3">动态注释的替代方法</A>
<LI><A
href="http://www.microsoft.com/china/msdn/technic/library/techart/dynmicannot.asp#4">为用户界面添加注释</A>
<LI><A
href="http://www.microsoft.com/china/msdn/technic/library/techart/dynmicannot.asp#5">可用性和其它资源</A>
</LI></UL>
<HR SIZE=1>
<P><BR><FONT class=105v><B><A name=#1></A><FONT
size=3>简介</FONT></B></FONT>
<P>前面的文章介绍了作为 Microsoft Active Accessibility 1.0 的一部分的 <FONT
face=arial><B>IAccessible</FONT></B> 界面,并说明了 oleacc.dll 为标准控件(USER 和
ComCtl)提供了该界面的默认实现。这些文章使开发人员在使用自己绘制的和自定义控件时避免破坏默认实现。有关详细信息,请参阅 <A
href="http://msdn.microsoft.com/library/techart/actvaccess.htm">Microsoft
Active Accessibility: Part 1</A>(英文)(另在 <I>MSDN News</I> 的 2000 年
5/6 月刊)<I> </I>和 <A
href="http://msdn.microsoft.com/library/techart/msaa_sa.htm">Microsoft
Active Accessibility: Part 2</A>(英文)(另在 <I>MSDN News</I> 的 2000 年
7/8 月刊)。
<P>本文是讨论 Active Accessibility 2.0 及其新功能系列文章的第一篇。作为这些功能之一的动态注释 (DA)
与前面文章中讨论的技术相比,为自定义辅助功能信息提供了更好的灵活性并明显降低了开发成本。</P>
<HR SIZE=1>
<P><BR><FONT class=105v><B><A name=#2></A><FONT
size=3>什么是动态注释</FONT></B></FONT>
<P>Active Accessibility 组件 oleacc.dll 创建代表标准 Microsoft Windows? 控件实现
<B><FONT face=arial>IAccessible</FONT></B> 的代理对象。由于这些代理使用标准 Windows
消息和控件专用 API 收集每个控件的信息,因此没有直接的机制自定义这些代理通过 <B><FONT
face=arial>IAccessible</FONT></B> 提供的信息。</P>
<P>动态注释允许开发人员将提示和其他有用信息传递给 OLEACC 来自定义其提供的信息。该功能本身将降低支持 Active
Accessibility 的成本,使开发人员大大改进用户界面的辅助功能。</P>
<HR SIZE=1>
<P><BR><FONT class=105v><B><A name=#3></A><FONT
size=3>动态注释的替代方法</FONT></B></FONT>
<P>还有其他方法可以为界面元素提供自定义 <B><FONT face=arial>IAccessible</FONT></B>
支持,在某些场合它们是正确的解决方案。实际上,在引入注释之前,这些技术是开发人员的唯一选择。</P>
<P>第一种替代方法是实现整个 <B><FONT face=arial>IAccessible</FONT></B>
界面。自定义控件或不同用户界面元素通常需要该方法,但是开发和测试成本明显太高,因此除非真正必要否则应该避免采用。如果目标是更改单个属性,则成本难以判断。</P>
<P>第二种方法是使用子类和封装技术修改指定属性的信息。这是动态注释要替代的技术。要使用子类和封装重载单个属性,开发人员必须:
<UL type=disc>
<LI>使 <B><FONT face=arial>IAccessible</FONT></B> 对象的 HWND
成为子类。<BR><BR>
<LI>截取 WM_GETOBJECT 获得正确 lParam/OBJID 值。<BR><BR>
<LI>将 WM_GETOBJECT 通过 <B><FONT face=arial>CallWndProc()</FONT></B>
传递给基类。如果返回 0,则调用 <B><FONT
face=arial>CreateStdAccessibleObject</FONT></B>;否则调用 <B><FONT
face=arial>LresultFromObject</FONT></B> 来获得控件本身的 <B><FONT
face=arial>IAccessible</FONT></B>。<BR><BR>
<LI>创建封装类,该类实现 <B><FONT face=arial>IAccessible</FONT></B>
并封装了上一步返回的 <B><FONT
face=arial>IAccessible</FONT></B>。除需要重载的之外,该封装类将所有方法和属性均传递给原始
<B><FONT face=arial>IAccessible</FONT></B>。这包括编写传递 <B><FONT
face=arial>IAccessible</FONT></B> 所有 21
种属性和方法的代码,无论实际重载多少。<BR><BR>
<LI>重载方法和属性必须只处理所需的子 ID,而将所有其他内容传递给原始 <B><FONT
face=arial>IAccessible</FONT></B>。<BR><BR>
<LI>如果且仅在原始对象支持的情况下,封装还必须传递 <B><FONT face=arial>IEnumVARIANT</B> 和
<B>IOleWindow</FONT></B> 接口。<BR><BR>
<LI>必须仔细确保正确处理引用计算,特别是如果支持其它界面的话。<BR><BR>
<LI>必须仔细正确处理 <B><FONT face=arial>IDispatch</FONT></B>,特别是 <B><FONT
face=arial>ITypeLib::Invoke()</FONT></B>,它必须随指向封装接口的接口指针一起调用,而不是指向原始
<B><FONT face=arial>IAccessible</FONT></B> 接口的指针。 </LI></UL>
<P>如前所见,这包括相当的工作量,即使只有一个或两个属性需要重载。结果代码的大部分用于子类和封装,只有一小部分结果代码实际执行真正提供重载信息的任务。</P>
<HR SIZE=1>
<P><BR><FONT class=105v><B><A name=#4></A><FONT
size=3>为用户界面添加注释</FONT></B></FONT>
<P>Active Accessibility 2.0
中支持三种动态注释:<I>直接注释</I>、<I>数值映射注释</I>和<I>回调注释</I>。每种类型都有它的优点,因此首先要理解哪一种方法适用于指定场合。</P>
<P><B>注释接口</B>
<P>在继续之前,熟悉注释所涉及的三种主要接口非常重要。由于篇幅所限,我们只对每一种进行高层次的说明。有关详细信息,包括每个界面方法的讨论,可在
Active Accessibility SDK 中找到。</P>
<P><I><B><FONT face=arial>IAccPropServices</FONT></B> 接口。</I>这是由单个类
<B><FONT face=arial>CLSID_AccPropServices</FONT></B> 实现的主要注释接口,该类位于
oleacc.dll 中。该接口包含注释访问元素的方法(请参阅表 1)。</P>
<P class=label><B>表 1. <FONT face=arial>IAccPropServices</FONT>
接口方法</B></P>
<TABLE border=1 cellPadding=5 cols=2 frame=below rules=rows>
<TBODY>
<TR vAlign=top>
<TD width="50%"><FONT class=90v><B><FONT face=arial
size=2>SetPropValue()</FONT></B></FONT></TD>
<TD width="50%"><FONT class=90v size=2>需要通过一个 VARIANT 变量传递
<B><FONT face=arial>IAccessibleIdentity</FONT></B>
和注释值。</FONT></TD></TR>
<TR vAlign=top>
<TD width="50%"><FONT class=90v><B><FONT face=arial
size=2>SetPropServer()</FONT></B></FONT></TD>
<TD width="50%"><FONT class=90v size=2>用于回调注释。</FONT></TD></TR>
<TR vAlign=top>
<TD width="50%"><FONT class=90v><B><FONT face=arial
size=2>ClearProps()</FONT></B></FONT></TD>
<TD width="50%"><FONT class=90v
size=2>阐述属性的注释值,但是这通常不需要,因为注释服务在注释元素销毁时自动清除并释放该信息。</FONT></TD></TR>
<TR vAlign=top>
<TD class=indent width="50%"><FONT class=90v><FONT
size=2><B><FONT face=arial>SetHwndProp()</FONT></B> </FONT>
<P class=indent><B><FONT
face=arial>SetHwndPropStr()</FONT></B></P>
<P><B><FONT
face=arial>SetHwndPropServer()</FONT></B></P></FONT></TD>
<TD width="50%"><FONT class=90v size=2>这些方法提供 HWND
专用注释。</FONT></TD></TR>
<TR vAlign=top>
<TD class=indent width="50%"><FONT class=90v><FONT
size=2><B><FONT face=arial>SetHmenuProp()</FONT></B> </FONT>
<P class=indent><B><FONT
face=arial>SetHmenuPropStr()</FONT></B></P>
<P><B><FONT
face=arial>SetHmenuPropServer()</FONT></B></P></FONT></TD>
<TD width="50%"><FONT class=90v size=2>这些方法提供 HMENU
专用注释。</FONT></TD></TR></TBODY></TABLE><BR>
<P><I><B><FONT face=arial>IAccIdentity</B></FONT> 接口。</I>由 <B><FONT
face=arial>IAccessible</FONT></B>
对象实现并内部用于进入注释数据库的密匙。所有希望支持动态注释的对象必须支持该接口。</P>
<P><I><B><FONT face=arial>IAccPropServer</FONT></B>
接口。</I>由在回调注释中使用的回调对象实现。</P>
<P><B>直接注释</B>
<P>动态注释的最简单形式称作<B>直接注释</B>。这种注释最适用于注释属性不依赖于控件状态的访问元素,因此不需要由<B>数值映射注释</B>和<B>回调注释</B>提供的附加支持。</P>
<P>要使用直接注释为访问元素进行注释:
<UL type=disc>
<LI>获得指向要注释的访问元素的 <B><FONT face=arial>IAccessible</FONT></B>
接口指针。<BR><BR>
<LI><B><FONT face=arial>IAccIdentity</FONT></B> 接口的 QI,并调用
<B><FONT face=arial>GetIdentityString()</FONT></B>
获得访问元素的标识字符串。<BR><BR>
<LI><B>同时创建</B> <B><FONT face=arial>AccPropServices</FONT></B>
对象。<BR><BR>
<LI>调用 <B><FONT
face=arial>IAccPropServices::SetPropValue</FONT></B>,传递标识字符串,代表要重载的属性的
GUID,一个包含新属性值的 VARIANT 变量。 </LI></UL>
<P>如果不对访问元素的标识调用 <B><FONT
face=arial>SetPropValue</FONT></B>,开发人员可以调用 <B><FONT
face=arial>SetHwndProp<I>X</I></B></FONT> 或 <B><FONT
face=arial>SetHmenuProp<I>X</I></FONT></B> 方法并提供访问元素的 HWND/HMENU、对象
ID 和子 ID。这不需要 <B><FONT face=arial>IAccIdentity</FONT></B> 的 QI,调用
<B><FONT face=arial>GetIdentityString</FONT></B> 并在 VARIANT
中包装字符串值。</P>
<P>下列属性可使用直接注释进行注释,数值必须为指定类型:</P>
<TABLE border=1 cellPadding=5 cols=2 frame=below rules=rows>
<TBODY>
<TR vAlign=top>
<TD width="74%"><FONT class=90v
size=2>PROPID_ACC_DEFAULTACTION</FONT></TD>
<TD width="26%"><FONT class=90v size=2>(VT_BSTR)</FONT></TD></TR>
<TR vAlign=top>
<TD width="74%"><FONT class=90v
size=2>PROPID_ACC_DESCRIPTION</FONT></TD>
<TD width="26%"><FONT class=90v size=2>(VT_BSTR)</FONT></TD></TR>
<TR vAlign=top>
<TD width="74%"><FONT class=90v
size=2>PROPID_ACC_HELP</FONT></TD>
<TD width="26%"><FONT class=90v size=2>(VT_BSTR)</FONT></TD></TR>
<TR vAlign=top>
<TD width="74%"><FONT class=90v
size=2>PROPID_ACC_KEYBOARDSHORTCUT</FONT></TD>
<TD width="26%"><FONT class=90v size=2>(VT_BSTR)</FONT></TD></TR>
<TR vAlign=top>
<TD width="74%"><FONT class=90v
size=2>PROPID_ACC_NAME</FONT></TD>
<TD width="26%"><FONT class=90v size=2>(VT_BSTR)</FONT></TD></TR>
<TR vAlign=top>
<TD width="74%"><FONT class=90v
size=2>PROPID_ACC_ROLE</FONT></TD>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -