Access开发培训
网站公告
·Access专家课堂QQ群号:151711184    ·Access快速开发平台下载地址及教程    ·欢迎加入Access专家课堂微信群!    ·如何快速搜索本站文章|示例|资料    
您的位置: 首页 > 技术文章 > 综合其它

32 位和 64 位版本的 Office 之间的兼容性

时 间:2016-08-03 08:04:39
作 者:宏鹏   ID:21115  城市:上海
摘 要:了解如何Office的 32 位版本是与Office的 64 位版本兼容。
正 文:

本文内容 
比较 32 位和 64 位系统 
基本 VBA 7 代码 
ActiveX 控件和 COM 加载项兼容性 
API 兼容性 
使用条件编译属性 
常见问题解答 
其他资源 

Office应用程序是在 32 位和 64 位版本中可用。

64 位版本的Office使您能够移动增强功能,例如,当您使用大量Microsoft Excel 2010中的更多数据。编写 32 位代码时,您可以使用 64 位版本的Office而不进行任何更改。但是,当编写 64 位代码时,应确保代码中包含特定关键字和条件编译常量,以确保该代码是与早期版本的Office,向后兼容和正在执行正确的代码,如果您混合使用 32 位和 64 位代码。

在 64 位版本的Office,释放的 Visual Basic for Applications 7.0 (VBA 7),其工作方式与 32 位和 64 位应用程序。本文中所述的更改仅应用于Office的 64 位版本。您可以使用解决方案使用 32 位版本的Microsoft Office启用内置的早期版本的Office不进一步进行修改。

注释 注释

默认情况下,当您安装 64 位版本的Office,您还安装 32 位版本以及 64 位系统安装。您必须明确选择Microsoft Office 64 位版本的安装选项。

在 VBA 7 中,您必须更新现有 Windows API 语句 (Declare ) 使用 64 位版本。此外,您必须更新地址指针和这些语句所使用的用户定义类型中显示窗口句柄。更多详细信息以及在本文中为 32 位和 64 位版本和建议的解决方案之间的兼容性问题所述。

生成的Office 64 位版本的应用程序可以引用比 32 位版本的较大地址空间。这意味着,您可以使用更多的物理内存数据比之前,可能会降低开销花费和物理内存注销移动数据

除了在物理内存引用 (称为指针) 的特定位置,您可以使用地址引用显示窗口标识符 (称为控点)。无论您使用的 32 位或 64 位系统取决于指针或句柄的大小 (以字节为单位)。

如果您想要运行 64 位版本的Office与您现有的解决方案,应注意下列 ︰

  • 在Office本机 64 位进程无法加载 32 位二进制文件。这将成为常见的问题,有现有 Microsoft ActiveX 控件和现有的加载项时。

  • VBA 以前没有指针数据类型,因此您必须使用 32 位变量来存储指针和控点。现在,这些变量截断 64 位 API 呼叫时使用Declare语句所返回的值。

VBA 7 替换基 Office 2007 和更早版本中的 VBA 代码。VBA 7 是Office的 32 位和 64 位版本中可用。它提供了两个条件编译的常量 ︰

  • VBA7 -有助于确保通过测试您的应用程序正在使用 VBA 7 或早期版本的 VBA 代码的向后兼容性。

  • Win64测试是否为 32 位或 64 位运行代码。

某些例外情况,在 32 位版本的应用程序中工作的文档中的宏也在 64 位版本中进行协作。

现有 32 位 ActiveX 控件,并不兼容的Office64 位版本。 ActiveX 控件和 COM 对象 ︰

  • 如果您有源代码,自行生成 64 位版本。

  • 如果您没有源代码,请更新版本与供应商联系。

在Office本机 64 位进程无法加载 32 位二进制文件。这其中包括MSComCtl (减少、 工具栏、 状态栏、 进度栏、 树视图、 列表视图、 imagelist.、 滑块,ImageComboBox) 的常见控件和MSComCt2 (动画、 上下、 月视图、 DateTimePicker,FlatScrollBar) 的控件。这些控件已安装 32 位版本的早于Office 2010Office 。您需要查找 64 位版本的Office迁移代码时,使用这些控件您现有的 VBA 解决方案的替代方法。

VBA 和类型库的组合提供了许多功能来创建Office应用程序。但是,有时您必须直接与通信的计算机操作系统和其他组件,例如,当您管理内存或过程,使用用户界面元素 linke 窗口和控件,或修改 Windows 注册表时。在这些情况下,您的最佳方法是使用外部 DLL 文件中嵌入的函数之一。执行此操作通过使 API 调用使用Declare语句中 VBA。

注释 注释

Microsoft 提供了包含 1500 Declare 语句和工具来复制到代码所需的Declare语句的 Win32API.txt 文件。不过,这些语句对于 32 位系统,必须将转换为 64 位使用本文讨论的信息。现有Declare语句不会在 64 位 VBA 编译,直到它们被标记为可安全执行 64 位使用PtrSafe属性。您可以在 Excel MVP Jan Karel Pieterse 的网站上找到这种类型的转换的示例 ︰ http://www.jkp-ads.com/articles/apideclarations.asp

Office 代码兼容性检查器用户指南非常有用,如果需要请检查PtrSafe属性中,API Declare语句的语法和相应的返回类型。

Declare语句类似于下面之一,具体取决于您呼叫的子例程 (其不返回值) 或 (具有函数返回的值)。

VBA
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 文件的名称遵循关键字。和参数列表中最后,包含参数和必须传递给该过程的数据类型。

下面的 Declare 语句将打开 Windows 注册表中的一个子项 并替换其值。

VBA
Declare Function RegOpenKeyA Lib "advapi32.dll" (ByVal Key As Long, ByVal SubKey As String, NewKey As Long) As Long

RegOpenKeyA 函数的 Windows.h(窗口句柄)条目如下所示:

VBA
LONG RegOpenKeyA ( HKEY hKey, LPCSTR lpSubKey, HKEY *phkResult );

在 Visual C 和 Microsoft Visual c + + 上, 一示例正确编译 32 位和 64 位。这是因为 HKEY 定义为一个指针,其大小反映在编译代码的平台的内存大小。

在早期版本的 VBA,没有任何特定指针数据类型以便使用Long的数据类型。然后,因为Long数据类型始终是 32 位,因为高 32 位可能会被截断或可能会覆盖其他内存地址使用 64 位内存系统上时此分页符。 任何一种情况导致无法预料的行为或系统崩溃。

若要解决此问题,VBA 包含 true指针数据类型 ︰ LongPtr。此新的数据类型,您可以编写原始Declare语句正确为 ︰

VBA
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语句仅针对Office的 64 位版本。如果没有此属性,在 64 位系统中使用Declare语句将导致编译时错误。PtrSafe属性是 Office 的可选32 位版本。此项服务使现有Declare语句它们始终可以工作。

下表提供了有关新的限定符和以及其他数据类型的数据 typeas、 两个转换运算符和三个函数的详细信息。

类型

说明

限定符

PtrSafe

指示 Declare 语句与 64 位兼容。此属性在 64 位系统上是必需的。

数据类型

LongPtr

在 32 位版本和 64 位版本的Microsoft Office8 字节数据类型是 4 字节数据类型的变量数据类型。这是 Office 的声明指针或句柄的新的代码,但也旧代码,如果有运行在 64 位版本的推荐的方法。它只是支持在 VBA 7 运行时在 32 位和 64 位。请注意,您可以分配数字值,但不是数字类型。

数据类型

LongLong

这是 Microsoft Office 的可仅在 64 位版本8 字节数据类型。您可以分配数字值,但不是数字类型 (以避免被截断)。

转换运算符

CLngPtr

将简单表达式转换为 LongPtr 数据类型。

转换运算符

CLngLng

将简单表达式转换为 LongLong 数据类型。

函数

VarPtr

变量转换器。在 64 位版本上返回 LongPtr,在 32 位版本上返回 Long(4 字节)。

函数

ObjPtr

对象转换器。在 64 位版本上返回 LongPtr,在 32 位版本上返回 Long(4 字节)。

函数

StrPtr

字符串转换器。在 64 位版本上返回 LongPtr,在 32 位版本上返回 Long(4 字节)。

下面的示例演示如何在 Declare 语句中使用其中某些项。

VBA
Declare PtrSafe Function RegOpenKeyA Lib "advapi32.dll" (ByVal Key As LongPtr, ByVal SubKey As String, NewKey As LongPtr) As Long

请注意,没有PtrSafe属性Declare语句假定不能够与Office的 64 位版本兼容。

有两个条件编译的常量 ︰ VBA7Win64。要确保向后兼容的早期版本的Microsoft Office,可以使用VBA7常量 (这是更常见的大小写) 以防止在早期版本的Office使用 64 位代码。32 位版本和 64 位版本,如调用数学 API 用于 64 位版本和Long其 32 位版本,其LongLong之间的差异的代码中,您将使用Win64常量。下面的代码演示如何使用这两个常量。

VBA
#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 位代码并且打算在早期版本的Office中使用它,将想要使用VBA7条件编译常量。但是,如果您在Office编写 32 位代码,该代码将运行是在早期版本的Office而无需编译的常量。如果您想要确保您使用的 32 位版本和 64 位版本的 64 位语句的 32 位语句,则最佳选择是使用Win64条件编译常量。

下面的示例显示针对需要更新的 32 位编写的 VBA 代码。请注意将更新以使用LongPtr ,因为它们引用的控点或指针旧版代码中的数据类型。

编写 32 位版本的 VBA 代码

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

写 64 位版本的 VBA 代码

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

何时应该使用Office的 64 位版本?

这是您正在使用哪个主机应用程序 (Excel、 Word 和等) 的问题的详细信息。例如,Excel 就能够处理 64 位版本的 Microsoft Office 多大的工作表。

是否可以安装 64 位和 32 位版本的Office并行?

不能。

何时要向LongPtr转换Long参数?

您需要查看您想要呼叫的函数 Microsoft 开发人员网络上的 Windows API 文档。需要将转换为LongPtr控点和指针。例如,RegOpenKeyA的文档提供以下签名 ︰

C#
LONG WINAPI RegOpenKeyEx(
  __in        HKEY hKey,
  __in_opt    LPCTSTR lpSubKey,
  __reserved  DWORD ulOptions,
  __in        REGSAM samDesired,
  __out       PHKEY phkResult
);

参数的定义如下 ︰

参数

说明

[in] hKey

处理打开注册表项。

lpSubKey [中,可选]

要打开的注册表子项名称。

ulOptions

此参数是保留,必须为零。

[in] samDesired

指定所需的访问权限的键掩码。

phkResult [出]

指向接收打开密钥的句柄的变量的指针

Win32API_PtrSafe.txt Declare语句的定义如下 ︰

Declare PtrSafe Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" (ByVal hKey As LongPtr, ByVal lpSubKey As String, ByVal ulOptions As Long, ByVal samDesired As Long, phkResult As LongPtr) As Long

应转换指针和控点结构中?

是。请参阅MSG Win32API_PtrSafe.txt 中键入 ︰

Type MSG
    hwnd As LongPtr
    message As Long
    wParam As LongPtr
    lParam As LongPtr
    time As Long
    pt As POINTAPI
End TypeF

何时应该使用strptr varptobjptr

您应该使用这些函数分别检索字符串、 变量和对象,请指向。在 64 位版本的Office,这些函数将返回 64 位LongPtr,可以传递给Declare语句。这些函数的使用不已从早期版本的 VBA。唯一的区别是它们现在返回LongPtr



Access软件网QQ交流群 (群号:483923997)       Access源码网店

常见问答:

技术分类:

相关资源:

专栏作家

关于我们 | 服务条款 | 在线投稿 | 友情链接 | 网站统计 | 网站帮助