介绍 32 位和 64 位版本的 Microsoft Office 2010
在使用 64 位版本的 Office 2010 运行现有解决方案时存在两个基本问题:
- Office 2010 中的本机 64 位进程无法加载 32 位二进制文件。在使用现有 Microsoft ActiveX 控件和现有加载项时,这被认为是一个常见问题,
- VBA 以前不具有指针数据类型,因此,开发人员使用 32 位变量来存储指针和句柄。但现在在使用 Declare 语句时,这些变量会截断 API 调用返回的 64 位值。
介绍 VBA 7 基本代码
VBA 7 是新的基本代码,取代了早期版本的 VBA。32 位和 64 位版本的 Office 2010 中均包含 VBA 7。它提供了两个条件编译常量:VBA7 和 Win64。通过测试您的应用程序使用的是 VBA 7 还是以前版本的 VBA,VBA7 常量可帮助确保您的代码的后向兼容性。Win64 常量用于测试代码是以 32 位还是 64 位形式运行的。下文将介绍这两个编译常量。
ActiveX 控件和 COM 加载项兼容性
第三方及 Microsoft 提供的现有 32 位 ActiveX 控件与 64 位版本的 Office 2010 不兼容。对于 ActiveX 控件和 COM 对象,有三种可能的解决方案:
- 如果您有源代码,则可以自己生成 64 位版本,
- 您可以与供应商联系以获取更新版本,
- 也可以搜索其他解决方案。
应用程序编程接口兼容性
VBA 和类型库的结合为您提供了许多用于创建 Microsoft Office 应用程序的功能。不过,有时,您必须直接与计算机的操作系统及其他组件进行通信,例如在您管理内存或进程时,在使用用户界面(例如窗口和控件)时,或在修改 Windows 注册表时。在这些情况下,最好选择使用一个嵌入动态链接库 (DLL) 文件中的外部函数。为此,可在 VBA 中使用Declare 语句进行 API 调用。
![]() |
---|
Microsoft 提供了一个 Win32API.txt 文件,其中包含 1,500 个 Declare 语句以及一个用于剪切所需 Declare 语句并将其粘贴到您的代码中的工具。不过,这些语句适用于 32 位系统,必须使用下文讨论的信息将其转换为 64 位。您可以在 Excel MVP Jan Karel Pieterse 的网站 http://www.jkp-ads.com/articles/apideclarations.asp(该链接可能指向英文页面) 上找到此类型的转换示例。 |
Declare 语句类似于以下代码之一,具体取决于您调用的是子例程(没有返回值)还是函数(有返回值)。
Public/Private Declare Sub SubName Lib "LibName" Alias "AliasName" (argument list)
Public/Private Declare Function FunctionName Lib "Libname" alias "aliasname" (argument list) As Type
SubName 函数或 FunctionName 函数会被替换为 DLL 文件中过程的实际名称,表示在从 VBA 代码调用过程时所使用的名称。如果需要,您还可以为过程名称指定 AliasName 参数。包含要调用的过程的 DLL 文件的名称位于 Lib 关键字之后。最后,参数列表将包含必须传递给该过程的参数和数据类型。
下面的 Declare 语句将打开 Windows 注册表中的一个子项 并替换其值。
Declare Function RegOpenKeyA Lib "advapi32.dll" (ByVal Key As Long, ByVal SubKey As String, NewKey As Long) As Long
RegOpenKeyA 函数的 Windows.h(窗口句柄)条目如下所示:
LONG RegOpenKeyA ( HKEY hKey, LPCSTR lpSubKey, HKEY *phkResult );
在 Microsoft Visual C 和 Microsoft Visual C++ 中,前面的示例对 32 位和 64 位都能够正确编译。这是因为 HKEY 定义为指针,其大小反映了在其中编译代码的平台的内存大小。
在以前版本的 VBA 中,没有特定指针数据类型,因此使用了 Long 数据类型,而 Long 数据类型始终为 32 位,所以它在具有 64 位内存的系统上使用时会发生中断,因为前 32 位可能被截断或可能覆盖其他内存地址。以上任一情况都会导致不可预测的行为或系统崩溃。
为解决此问题,VBA 现在包含真正的指针 数据类型 LongPtr。此新数据类型使您能够正确编写原始 Declare 语句,如下所示:
Declare PtrSafe Function RegOpenKeyA Lib “advapire32.dll” (ByVal hKey as LongPtr, ByVal lpSubKey As String, phkResult As LongPtr) As Long
此数据类型和新的 PtrSafe 属性使您能够在 32 位或 64 位系统上使用此 Declare 语句。PtrSafe 属性向 VBA 编译器指示 Declare 语句面向 64 位版本的 Office 2010。如果不使用此属性,那么在 64 位系统中使用 Declare 语句会导致编译时错误。请注意,PtrSafe 属性在
32 位版本的 Office 2010 上是可选的。因此现有 Declare 语句始终能够正常运行。
下表提供了有关已讨论过的新限定符和数据类型以及另一种数据类型、两个转换运算符和三个函数的详细信息。
类型 | 项 | 说明 |
---|---|---|
限定符 |
PtrSafe |
指示 Declare 语句与 64 位兼容。此属性在 64 位系统上是必需的。 |
数据类型 |
LongPtr |
一种变量数据类型,在 32 位版本的 Office 2010 上是 4 字节数据类型,在 64 位版本上是 8 字节数据类型。这是为新代码声明指针或句柄的推荐方法,但如果它必须运行在 64 位版本的 Office 2010 中,则也为旧代码声明指针或句柄。只有 32 位和 64 位上的 VBA 7 运行时支持此数据类型。请注意,您可以为它赋予数值,但不能赋予数值类型。 |
数据类型 |
LongLong |
这是只能在 64 位版本的 Office 2010 中使用的 8 字节数据类型。您可以赋予数值,但不能赋予数值类型(以避免截断)。 |
转换运算符 |
CLngPtr |
将简单表达式转换为 LongPtr 数据类型。 |
转换运算符 |
CLngLng |
将简单表达式转换为 LongLong 数据类型。 |
函数 |
VarPtr |
变量转换器。在 64 位版本上返回 LongPtr,在 32 位版本上返回 Long(4 字节)。 |
函数 |
ObjPtr |
对象转换器。在 64 位版本上返回 LongPtr,在 32 位版本上返回 Long(4 字节)。 |
函数 |
StrPtr |
字符串转换器。在 64 位版本上返回 LongPtr,在 32 位版本上返回 Long(4 字节)。 |
下面的示例演示如何在 Declare 语句中使用其中某些项。
Declare PtrSafe Function RegOpenKeyA Lib "advapi32.dll" (ByVal Key As LongPtr, ByVal SubKey As String, NewKey As LongPtr) As Long
请注意,没有 PtrSafe 属性的 Declare 语句被假定为与 64 位版本的 Office 2010 不兼容。
如前所述,有两个新的条件编译常量:VBA7 和 Win64。为确保与以前版本的 Office 的向后兼容性,可使用 VBA7 常量(这是较典型的情况)来防止 64 位代码在早期版本的 Office 中运行。对于在 32 位版本和 64 位版本之间有所不同的代码(例如调用数学 API,它对其 64 位版本使用 LongLong,对其 32 位版本使用 Long),可使用 Win64 常量。下面的代码演示如何使用这两个常量。
#if Win64 then
Declare PtrSafe Function MyMathFunc Lib "User32" (ByVal N As LongLong) As LongLong
#else
Declare Function MyMathFunc Lib "User32" (ByVal N As Long) As Long
#end if
#if VBA7 then
Declare PtrSafe Sub MessageBeep Lib "User32" (ByVal N AS Long)
#else
Declare Sub MessageBeep Lib "User32" (ByVal N AS Long)
#end if
总而言之,如果您编写 64 位代码并打算在以前版本的 Microsoft Office 中使用它,则需要使用 VBA7 条件编译常量。不过,如果您在 Office 2010 中编写 32 位代码,则该代码的工作方式与在以前版本的 Microsoft Office 中一样,无需使用编译常量。如果希望确保对 32 位版本使用 32 位语句,对 64 位版本使用 64 位语句,则最好选择使用 Win64 条件编译常量。
使用条件编译属性
下面的代码是需要更新的旧 VBA 代码的示例。请注意旧代码中更新为使用 LongPtr 的数据类型,因为它们引用句柄或指针
旧 VBA 代码
Declare Function SHBrowseForFolder Lib "shell32.dll" _
Alias "SHBrowseForFolderA" (lpBrowseInfo As BROWSEINFO) As Long Public Type BROWSEINFO
hOwner As Long
pidlRoot As Long
pszDisplayName As String
lpszTitle As String
ulFlags As Long
lpfn As Long
lParam As Long
iImage As Long
End Type
新 VBA 代码
#if VBA7 then ' VBA7
Declare PtrSafe Function SHBrowseForFolder Lib "shell32.dll" _
Alias "SHBrowseForFolderA" (lpBrowseInfo As BROWSEINFO) As Long Public Type BROWSEINFO
hOwner As LongPtr
pidlRoot As Long
pszDisplayName As String
lpszTitle As String
ulFlags As Long
lpfn As LongPtr
lParam As LongPtr
iImage As Long
End Type #else ' Downlevel when using previous version of VBA7 Declare Function SHBrowseForFolder Lib "shell32.dll" _
Alias "SHBrowseForFolderA" (lpBrowseInfo As BROWSEINFO) As Long Public Type BROWSEINFO
hOwner As Long
pidlRoot As Long
pszDisplayName As String
lpszTitle As String
ulFlags As Long
lpfn As Long
lParam As Long
iImage As Long
End Type #end if
Sub TestSHBrowseForFolder ()
Dim bInfo As BROWSEINFO
Dim pidList As Long bInfo.pidlRoot = 0&
bInfo.ulFlags = &H1
pidList = SHBrowseForFolder(bInfo)
End Sub
结论
增加了 64 位版本的 Office 2010 后,您可以移动更多数据来增强功能。编写 32 位代码时,可以使用 64 位版本的 Microsoft Office 而无需进行任何更改。不过,在编写 64 位代码时,应确保您的代码包含特定关键字和条件编译常量,以确保代码与早期版本的 Microsoft Office 向后兼容,并确保在混合 32 位和 64 位代码时执行了正确的代码。
其他资源
有关 Declare 语句的详细信息,请参阅以下资源:
介绍 32 位和 64 位版本的 Microsoft Office 2010的更多相关文章
- 【转】Tomcat版本是32位、64位问题
转载地址:http://www.cnblogs.com/greensleeves/p/3168541.html 最近遇到一个Tomcat windows安装版本是32位还是64位问题.由于一系列原因, ...
- Tomcat版本是32位、64位问题
最近遇到一个Tomcat windows安装版本是32位还是64位问题.由于一系列原因,已经无从知晓生产系统上的该程序是32位还是64位. 后来经过仔细查阅资料,得知: 1. tomcat 从6.0. ...
- IOS是否存在32位和64位版本的区分
苹果于2013年9月推出了iPhone 5S新手机,采用的全新A7处理器其最大特色就是支持64位运算.其64位A7处理器的使用意味着iPhone性能会大有提高,性能和速度更加出色:而要到达到这样的性能 ...
- hadoop2.6.0汇总:新增功能最新编译 32位、64位安装、源码包、API下载及部署文档
相关内容: hadoop2.5.2汇总:新增功能最新编译 32位.64位安装.源码包.API.eclipse插件下载Hadoop2.5 Eclipse插件制作.连接集群视频.及hadoop-eclip ...
- hadoop2.5发布:最新编译 32位、64位安装、源码包、API以及新特性
hadoop2.5发布:最新编译 32位.64位安装.源码包.API以及新特性 http://www.aboutyun.com/thread-8751-1-1.html (出处: about云开发) ...
- 查看Linux是32位还是64位的方法
发布:JB01 来源:脚本学堂 [大 中 小] 本文介绍下,快速查看linux系统是32位还是64位的方法,有需要的朋友参考下吧. 本节内容:查看linux操作系统的位数 一,方法A:un ...
- Win7系统32位和64位的区别
Win7系统32位和64位的区别已经是一个老话题了,可是还是有很多朋友不明白.这两者到底有什么区别呢?下面本文与大家通俗的介绍下Win7系统32位和64位的区别,其他一些深入的理论讲述,大家可以看看文 ...
- 如何判断Office是32位还是64位?
对于持续学习VBA的老铁们,有必要了解Office的位数. 如果系统是32位的,则不需要判断Office位数了,因为只能安装32位Office. 下面只讨论64位系统中,Office的位数判断问题. ...
- 64位主机64位oracle下装32位客户端ODAC(NFPACS版)
64位主机64位oracle下装32位客户端ODAC(NFPACS版) by dd 1.下载Oracle Data Access Components(ODAC) Xcopy的两个版本: x86:(我 ...
随机推荐
- Shot(三分)
Shot Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- WPF qq界面(转)
原文:http://blog.csdn.net/u013981858/article/details/49130885 刚开始学WPF,自己写了个小东西,说实话写的并不好,好多东西不懂只是用现在懂的东 ...
- HDU 4548(美素数)
Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Description 小明对数的 ...
- 五毛的cocos2d-x学习笔记02-基本项目源码分析
class AppDelegate : private cocos2d::Application private表示私有继承,cocs2d是一个命名空间.私有继承下,Application类中的pri ...
- 【Visual C++】游戏开发五十六 浅墨DirectX教程二十三 打造游戏GUI界面(一)
本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/16384009 作者:毛星云 ...
- js方法中的this
比如有个function: function ServiceMy(services) { //存放this,用于调试用 var tmp_this = this; this.services = []; ...
- C# 常用参数
主函数调用 public static void Fun_Param() { ; ; ChangeValue(x, y); //外部调用Ref函数,必须初始化变量 ChangeValue(ref x, ...
- HTML5 总结-音频-2
HTML5 音频 音频格式 当前,audio 元素支持三种音频格式: IE 9 Firefox 3.5 Opera 10.5 Chrome 3.0 Safari 3.0 Ogg Vorbis ...
- C语言回溯算法解决N皇后问题
回溯算法的模型是 x++, not satisfy ? x-- : continue. 代码中x作列号,y[x]保存第x列上皇后放置的位置. #include<stdio.h> #incl ...
- QT 遍历目录查找指定文件(比较简单)
QString FindFile(const QString &strFilePath, const QString &strNameFilters){ if (strFilePath ...