📄 csdn_文档中心_microsoft windows 2000 应用程序兼容性 ( 2 ).htm
字号:
<P>下面讨论调用规则问题。资料上说,您必须为所有窗口过程使用 STDCALL。不幸的是,我们发现许多应用程序并没有为它的窗口过程使用
STDCALL,对话框过程也是如此。如果您不使用 STDCALL,您的程序可能无法正常工作。在 Windows 95 及 Windows
98 中,您可以通过使用 C_DECL 规则而避开这一问题;换句话说,如果您仅仅忘记在窗口过程中置入 C_DECL
规则,系统不会崩溃。</P>
<P>我们在 Windows 2000
中为此设置了功能区,因此我们可以尽可能地捕获它们。然而就在上一星期,我还是发现了一个错误,它跳出来对我说,“是的,我们已经使这些处理程序就位,并且,我们试着自己处理标准调用,但是因为应用程序没有使用标准调用,我们仍然没能正确截获它们。”如果您的窗口过程使用
STDCALL 而不是其他调用规则的话,事情便会简单得多。</P>
<P>我们也发现有些应用程序采用了正确的调用规则,却没有正确实施,或者是编译器中的错误显示出没有正确使用调用规则,或应用程序较快进入注册过程。因为我们正在进行进一步的优化,目的是更严格地使用注册内容并且使它占用资源更少、运行更快,因而,我们遇到过许多因未能严格遵循规则而导致应用程序不兼容的情况。</P>
<H3>非缓冲文件的文件 I/O</H3>
<P>如果您希望不使用系统提供的缓冲区处理一些文件 I/O,则需要使用 Create File
FILE_FLAG_NO_BUFFERING
上的标志(意思是,您自己提供缓冲区,而不使用系统为这些读写操作而分配的缓冲区)。您必须确认传递给 <B>ReadFile</B> 和
<B>WriteFile</B> API 的缓冲区已针对设备进行了正确对齐。这些与以前没有什么区别,但是,我们发现,这些对齐方式在
Windows 2000 上稍微有些差别,特别在对新型 Ultra 66 IDE
驱动器等新设备的支持方面。所以,您必须确认分配缓冲区的方式是否正确。实现这一目的的最简便方式是使用
<B>VirtualAlloc</B>。<B>VirtualAlloc</B> 将始终将缓冲区按偶边界对齐,因此,无论设备完成文件
I/O 所需的缓冲区大小是多少,它总可以正确对齐。记住,当您进行这些操作的时候,您必须确认您的读写操作时使用的是 I/O
设备实际扇区大小的若干倍。您可以通过 <B>GetDiskFreeSpace</B>
得到扇区大小,并且确保您仅分配和读取这些扇区大小的数倍。</P>
<H3>大型驱动器</H3>
<P>另一个与驱动器有关的问题是某些大型驱动器所带来的。显然,目前的驱动器要比 4GB 大得多,一般来说,其中的可用空间也要比 4GB
多得多。然而如果您使用 <B>GetDiskFreeSpace</B>,它将返回一串 32
位数值,该数值并不是准确值,因为实际数值要比之多得多,这种情况会在很多地方出现。我们曾发现有的应用程序返回的磁盘空间的数量是负值,由此出现了各种各样的问题。</P>
<P>您需要应用 <B>GetDiskFreeSpaceEx</B>,它采用了 ULARGE_INTEGER_
代替了INT,因此能够为您提供可用空间的真实数据。</P>
<H3>打开另一个 HKEY_CURRENT_USER</H3>
<P>有些时候有些应用程序(尤其是某些服务器应用程序),需要从其他 HKEY_CURRENT_USER 而不是它们最初或当前所使用的
HKEY_CURRENT_USER 中获取信息。问题在于 HKEY_CURRENT_USER
实际所采用的缓存方式是建立在每一进程的基础上。应用程序会试图关闭 HKEY_CURRENT_USER,模拟新的用户,然后打开
HKEY_CURRENT_USER,并希望他们获取的是正确的
HKEY_CURRENT_USER。问题是如果使用多个线程进行这一操作,其中的一个线程可能已经完成,而另一个线程可能正处于操作过程中。您无法搞清楚结束的是哪一个
HKEY_CURRENT_USER,因为第二次打开时系统会声明“我已打开了
HKEY_CURRENT_USER,我用的就是缓存中的那一个。”这种操作具有相当的危险性。为了改善这一状况,我们增加了一个新的、名为
<B>RegOpenCurrentUser</B> 的 API,有了该 API,您能够正确地实施模拟过程,以便获取真正需要的
HKEY_CURRENT_USER。 </P>
<H3>检查位 (Bit) 标志</H3>
<P>另一个低级 C 类问题:我们已发现有的应用程序在对位标志进行检查时,使用的是等式运算符,而不是实际检查某一特定位是否存在。我们会在
Windows 2000 以及 Windows 2000
以后的所有版本中添加标志,因此您需要确保检查的是位,而不是是否相等。我们已添加了不带焦点值和加速值的所有者图形,以使其带有不同类型的绘图参数。以下是检查位标志的方式:</P><PRE><CODE>if (fItemState & ODS_FOCUS)
</CODE></PRE>
<H3>消息的顺序</H3>
<P>我们一直在告诫开发人员不要使用消息的顺序或依靠应用程序接收消息的顺序去表达某种特殊含义。这是靠不住的。我们甚至发现有些应用程序在某些多线程应用中依赖消息的顺序。例如,有可能会发生下述情况:有一个线程关闭,然后向主消息循环发出一条信息,然后另一线程关闭,也发出一条消息。应用程序可能会将消息发出的顺序作为线程关闭的顺序。我们已对线程计划程序的操作方式进行了改动。理想情况下,它们完成了消息的发布,会依次将消息送入队列,以便进行处理,但实际情况并非如此。如果您尝试一下,会发现它们发出消息的顺序与线程关闭的顺序不一致,由此,就会发生各种问题。再次强调,如果您需要依靠消息的顺序(尤其是在跨线程的情况下),您不要想当然地认为消息本身就是进行同步的方式,而要增加自己的同步机制。</P>
<H3>多个监视器</H3>
<P>从 Windows 98 开始,Windows 具有了处理多个监视器的能力。Windows 2000 是第一个具有这种能力的、基于
Windows NT
的平台。由此出了一个大问题:您必须确认您的应用程序能正确处理负坐标和超大坐标或表现为超大坐标的情况。如果设置了多个监视器,而主监视器在副监视器的右侧,则副监视器将完全处于负坐标区域。如果您的应用程序调出一个应位于副监视器的窗口,而应用程序希望将窗口最大化,假设应用程序无法正确处理多监视器系统,它会因当前坐标完全为负而将窗口整个移动到主显示器中。这种情况是不应该发生的。如果您需要定位窗口,则一定要在多显示器系统中对应用程序进行测试,确认一定能正确处理这些负坐标。对于超大正向坐标也应如此处理。您需要采用图中所示的新的系统目标,确保将窗口置于它应处的位置。</P>
<P><B><IMG alt="" border=0
src="CSDN_文档中心_Microsoft Windows 2000 应用程序兼容性 ( 2 ).files/win2000appcomp01.gif"></B></P>
<H2><A name=win2000appcomp_topic5></A>Windows 平台之间的差异</H2>
<P>我将讨论最后一类问题(与其他一些问题相比,这一问题要简要得多):Windows 平台的基本差异。Windows 2000 是以
Winsows NT 为基础的。我们认定大量用户会将他们的 Windows 9x 升级到 Windows
2000。我们一直在测试一些应用程序,将它们从 Windows 9x 移到 Windows 2000 平台。您将在杂志文章和 SDK
中发现关于这个问题的大量信息。您需要确保您的应用程序并不紧密针对 Windows 9x 平台,相反它应当紧密针对 Windows NT
平台。</P>
<H3>目标严格限制的应用程序</H3>
<P>第一种目标严格限制的情况是:应用程序使用的 API 仅能在 Windows 9x 平台上实现,在 Windows NT
中不能实现。我常常使用的 Tool Help API 就是这样的一个例子。在 Windows 2000 中我们已经可以在某种程度上支持
Tool Help API,但是您会发现在 Windows 9x 中有大量的 API 还没有找到升级到 Windows NT
的途径。没有一个真正可行的方法能解决这一难题。您可以使用 SDK 中的 .csv 文件,该文件实际上只是一个电子表格,它能告诉您关于任何
API 的情况:哪里可执行、哪里不能、如何工作,除此之外还有各种其他资料。另一种方式是对应用程序进行切实的测试,确保您的应用程序能够在
Windows 98 和 Windows NT 平台之间进行迁移,确保它们能够运行。这种方式可能要简单得多,执行起来也快得多。</P>
<P>您需要注意以下事实;Windows NT 平台在其 GDI 调用中使用的是全 32 位的坐标系统,而 Windows 9x
使用的是 16 位。一定要知道这些不同之处。事实上,Windows NT 中的所有句柄用的是完全的 32
位。有些开发人员试图利用以下事实:在 Windows 9x 中句柄是 32 位,但却只用到 16 位。如果在 Windows NT
上这样使用,后果将非常糟糕。</P>
<H3>通用替换</H3>
<P>在应用替换的过程中有许多应用程序也会陷入功能障碍。Windows 9x 所采用的方式可以称之为“直接替换 (flat
thunk)”:它允许 16 位应用程序调入 32 位应用程序,也允许 32 位应用程序直接调入一个 16 位组件,或 16
位应用程序。Windows 2000 不支持这一功能,尤其是不支持 32 位应用程序直接调入 16 位应用程序。Windows 2000
和 Windows NT 所采用的方式可以称之为“通用替换 (generic thunk)”:通用替换允许 16 位应用程序调入 32
位组件,也允许 16 位应用程序启动对 32 位组件的调用过程,然后由 32 位组件回调 16 位应用程序,而不支持由 32
位代码直接调用 16 位组件,这一过程无法生效。您只能由 16 位启动对 32 位的调用,反之不能。另外针对替换过程还需要记住一点:即
Windows 9x 和 Windows NT 之间的基础进程模型都是有区别的。由通用替换中您可以看出一些区别。最简单的办法是将 16
位组件移植到 32 位组件。您需要对这两个平台的替换问题有清醒的认识。</P>
<P> </P><BR></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR>
<TABLE align=center bgColor=#006699 border=0 cellPadding=0 cellSpacing=0
width=770>
<TBODY>
<TR bgColor=#006699>
<TD align=middle bgColor=#006699 id=white><FONT
color=#ffffff>对该文的评论</FONT></TD>
<TD align=middle>
<SCRIPT
src="CSDN_文档中心_Microsoft Windows 2000 应用程序兼容性 ( 2 ).files/readnum.htm"></SCRIPT>
</TD></TR></TBODY></TABLE><BR>
<DIV align=center>
<TABLE align=center bgColor=#cccccc border=0 cellPadding=2 cellSpacing=1
width=770>
<TBODY>
<TR>
<TH bgColor=#006699 id=white><FONT
color=#ffffff>我要评论</FONT></TH></TR></TBODY></TABLE></DIV>
<SCRIPT language=javascript>
<!--
function isEmpty(s)
{
return ((s == null) || (s.length == 0))
}
function fubmitok()
{
if (isEmpty(document.add_critique.Critique_Content.value))
{
alert('评论不能为空!!!!') ;
return false;
}
document.add_critique.submit();
}
//-->
</SCRIPT>
<DIV align=center>
<TABLE border=0 width=770>
<TBODY>
<TR>
<TD>
<FORM action=Critique_Sql.asp method=post name=add_critique><INPUT
name=Critique_State type=hidden value=add> 评论人:xyj0323
评论:<BR> <TEXTAREA cols=104 name=Critique_Content rows=8></TEXTAREA><BR> <INPUT name=ubmit onclick=javascript:fubmitok(); type=button value=发表评论>
<INPUT name=Topic_id type=hidden value=1868> <INPUT name=From type=hidden
value=/Develop/Build_Article.asp?id=1868>
</FORM></TD></TR></TBODY></TABLE></DIV><BR>
<HR noShade SIZE=1 width=770>
<TABLE border=0 cellPadding=0 cellSpacing=0 width=500>
<TBODY>
<TR align=middle>
<TD height=10 vAlign=bottom><A
href="http://www.csdn.net/intro/intro.asp?id=2">网站简介</A> - <A
href="http://www.csdn.net/intro/intro.asp?id=5">广告服务</A> - <A
href="http://www.csdn.net/map/map.shtm">网站地图</A> - <A
href="http://www.csdn.net/help/help.asp">帮助信息</A> - <A
href="http://www.csdn.net/intro/intro.asp?id=2">联系方式</A> - <A
href="http://www.csdn.net/english">English</A> </TD>
<TD align=middle rowSpan=3><A
href="http://www.hd315.gov.cn/beian/view.asp?bianhao=010202001032100010"><IMG
border=0 height=48
src="CSDN_文档中心_Microsoft Windows 2000 应用程序兼容性 ( 2 ).files/biaoshi.gif"
width=40></A></TD></TR>
<TR align=middle>
<TD vAlign=top>百联美达美公司 版权所有 京ICP证020026号</TD></TR>
<TR align=middle>
<TD vAlign=top><FONT face=Verdana>Copyright © CSDN.net, Inc. All rights
reserved</FONT></TD></TR>
<TR>
<TD height=15></TD>
<TD></TD></TR></TBODY></TABLE></DIV>
<DIV></DIV><!--内容结束//--><!--结束//--></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -