当前位置: 首页 > news >正文

终于解决了悬疑好多年的低版本CAD VBA不能在高版本CAD使用的问题

本篇文章是博主怀着激动的心情写下的,因为积累十余年的CAD2007 32位 VBA程序无法在CAD2010 64位以上的高版本上使用的阴云在盘旋于众人头几年以后终于在今天消散了。

CAD 2010以后的版本分为32位和64位,32位和64位分别只能装在32位和64位操作系统,虽然通过一些变通方法,将32位CAD装在64位操作系统也是可行的,但是使用不是很方便。现在新电脑一般安装win10操作系统,而win10操作系统就是64位,在其上只能安装CAD64位版本。此时,问题出现了,在CAD2007 编写的VBA程序不能在64位高版本CAD上运行,高版本CAD加载vba程序会报如下错误:

就是这个两个报错对话框一直让博主觉得高版本不能运行32位低版本vba程序。因此,电脑的win10操作系统会安装两个版本的CAD,分别是CAD2007和高版本CAD,CAD2007用来运行CAD VBA程序,高版本CAD用来编图,因为CAD2007有一些诸如调整图元上下层失效的bug,其功能和流畅度也不如高版本CAD。这种恼人的情形持续了好几年,直到最近,一位同事说,将这些对话框点击完以后,并将程序代码中的Declare用Declare PtrSafe替换以后,VBA程序在高版本CAD中也能运行,但是程序不稳定,容易造成CAD死机。

博主尝试了一下,除了少部分程序确实能运行,大部分程序不能正常运行,有些会造成CAD死机。

1、不能正常运行的程序问题出在:CAD2007中文件打开对话框控件(CommonDialog)在高版本中的CAD找不到了。即使引用加载了COMDLG32.OC控件,工具箱和窗口都不显示CommonDialog。

用bing搜索在中文的世界中找出的答案都不可行,转到国际版,换了几次关键词,一种可行的解决方案就浮现了,见如下代码,相关连接见参考文献。

Private Declare PtrSafe Function GetOpenFileName Lib "comdlg32.dll" Alias _

"GetOpenFileNameA" (pOpenfilename As OPENFILENAME) As Long

'====== File Browsers for 64 bit VBA 7 ========

Private Function FileBrowseOpen( ByVal sInitFolder As String, ByVal sTitle As String, ByVal sFilter As String, ByVal nFilterIndex As Integer, Optional ByVal multiSelect = False) As String

Dim OpenFile As OPENFILENAME

Dim lReturn As Long

sInitFolder = CorrectPath(sInitFolder)

OpenFile.lpstrInitialDir = sInitFolder

' Swap filter separator for api separator

sFilter = Replace(sFilter, "|", Chr(0))

OpenFile.lpstrFilter = sFilter

OpenFile.nFilterIndex = nFilterIndex

OpenFile.lpstrTitle = sTitle

OpenFile.hWndOwner = 0

OpenFile.lpstrFile = String(257, 0)

OpenFile.nMaxFile = LenB(OpenFile.lpstrFile) - 1

OpenFile.lStructSize = LenB(OpenFile)

OpenFile.lpstrFileTitle = OpenFile.lpstrFile

OpenFile.nMaxFileTitle = OpenFile.nMaxFile

If Not multiSelect Then

OpenFile.flags = 0

Else

OpenFile.flags = OFS_FILE_OPEN_FLAGS + OFN_ALLOWMULTISELECT

End If

lReturn = GetOpenFileName(OpenFile)

If lReturn = 0 Then

FileBrowseOpen = ""

Else

If multiSelect Then

Dim str As String

str = Trim(Replace(Trim(OpenFile.lpstrFile), vbNullChar, ","))

Dim ed As String

ed = Mid(str, Len(str))

While (ed = ",")

str = Trim(Left(str, Len(str) - 1))

ed = Mid(str, Len(str))

Wend

FileBrowseOpen = str

Else

FileBrowseOpen = Trim(Left(OpenFile.lpstrFile, InStr(1, OpenFile.lpstrFile, vbNullChar) - 1))

End If

End If

End Function

Public Function GetFiles( ByVal sInitFolder As String, ByVal sTitle As String, ByVal sFilter As String, ByVal nFilterIndex As Integer) As String()

Dim strReturn

strReturn = FileBrowseOpen(sInitFolder, sTitle, sFilter, nFilterIndex, True)

GetFiles = Split(strReturn, ",")

End Function

Private Sub CommandButton1_Click()

Dim initFolder As String

Dim filter As String

Dim fileNames() As String

Dim i As Integer

Dim lstDwgList

initFolder = ThisDrawing.Path

filter = "AutoCAD Drawing Files (*.dwg)|*.dwg|All Files (*.*)|*.*"

fileNames = GetFiles(initFolder, "Select Drawing Files", filter, 0)

If UBound(fileNames) > 0 Then

For i = 1 To UBound(fileNames)

lstDwgList.AddItem fileNames(0) & "\" & fileNames(i)

Next

End If

End Sub

#End If

2、死机的原因是VBA 打开目录的功能过时了。

Private Declare Sub CoTaskMemFree Lib "ole32.dll" (ByVal hMem As Long)
Private Declare Function lstrcat Lib "kernel32" Alias "lstrcatA" (ByVal lpString1 As String, ByVal lpString2 As String) As Long

Private Declare Function SHBrowseForFolder Lib "shell32" (lpbi As BrowseInfo) As Long
Private Declare Function SHGetPathFromIDList Lib "shell32" (ByVal pidList As Long, ByVal lpBuffer As String) As Long

上面2句要改成:

Private Declare PtrSafe Sub CoTaskMemFree Lib "ole32.dll" (ByVal hMem As LongPtr)
Private Declare PtrSafe Function lstrcat Lib "kernel32" Alias "lstrcatA" (ByVal lpString1 As String, ByVal lpString2 As String) As LongPtr

Private Declare PtrSafe Function SHGetPathFromIDList Lib "shell32.dll" Alias "SHGetPathFromIDListA" (ByVal pidl As LongPtr, ByVal     pszPath As String) As LongPtr
Private Declare PtrSafe Function SHBrowseForFolder Lib "shell32.dll" Alias "SHBrowseForFolderA" (lpBrowseInfo As BrowseInfo) As LongPtr

参考文献

https://forums.autodesk.com/t5/vba/old-vba-32-bit-does-not-run-on-new-64-bit/td-p/8391555

相关文章:

  • SpringBoot 项目的创建与启动
  • 百科创建:7种有效的百科词条创建技巧
  • 天狗实战SpringBoot+Vue(二)项目结构搭建(上)
  • k8s容器集群工作负载节点跨越多个云计算厂商
  • 专题五:DFS深度优先搜索
  • 【计算机网络】从输入网址到网页显示,期间发生了什么?
  • ZMC408CE | 实现“8通道独立PSO”应用场景
  • pytorch中.data与.item(),.numpy(),.detach(),.cuda(),.cpu()的作用
  • 从参数数量视角理解深度学习神经网络算法 DNN, CNN, RNN, LSTM 以python为工具
  • 如何使用ChatGPT API 及 问题解决
  • Linux0.11 任务切换(七)
  • Lighttpd入门教程
  • 为什么汽车控制器应用层软件开发要采用AUTOSAR的架构接口
  • # 飞书APP集成平台-数字化落地
  • 【JavaScript 逆向】网易易盾滑块逆向分析
  • ES6指北【2】—— 箭头函数
  • 10个确保微服务与容器安全的最佳实践
  • HomeBrew常规使用教程
  • Java深入 - 深入理解Java集合
  • Laravel 菜鸟晋级之路
  • mysql_config not found
  • scrapy学习之路4(itemloder的使用)
  • Twitter赢在开放,三年创造奇迹
  • vue-loader 源码解析系列之 selector
  • vue--为什么data属性必须是一个函数
  • Webpack4 学习笔记 - 01:webpack的安装和简单配置
  • 大主子表关联的性能优化方法
  • 对超线程几个不同角度的解释
  • 对象管理器(defineProperty)学习笔记
  • 技术:超级实用的电脑小技巧
  • 聊聊sentinel的DegradeSlot
  • 如何在 Tornado 中实现 Middleware
  • 移动端唤起键盘时取消position:fixed定位
  • 在Mac OS X上安装 Ruby运行环境
  • 《码出高效》学习笔记与书中错误记录
  • elasticsearch-head插件安装
  • ​软考-高级-系统架构设计师教程(清华第2版)【第1章-绪论-思维导图】​
  • # Maven错误Error executing Maven
  • #define
  • ${ }的特别功能
  • (c语言)strcpy函数用法
  • (笔记)Kotlin——Android封装ViewBinding之二 优化
  • (仿QQ聊天消息列表加载)wp7 listbox 列表项逐一加载的一种实现方式,以及加入渐显动画...
  • (转)GCC在C语言中内嵌汇编 asm __volatile__
  • (转)http-server应用
  • (转)MVC3 类型“System.Web.Mvc.ModelClientValidationRule”同时存在
  • (转)自己动手搭建Nginx+memcache+xdebug+php运行环境绿色版 For windows版
  • .NET Core实战项目之CMS 第一章 入门篇-开篇及总体规划
  • .NET Framework Client Profile - a Subset of the .NET Framework Redistribution
  • .NET 中选择合适的文件打开模式(CreateNew, Create, Open, OpenOrCreate, Truncate, Append)
  • .net操作Excel出错解决
  • @NestedConfigurationProperty 注解用法
  • [Angular 基础] - 指令(directives)
  • [Ariticle] 厚黑之道 一 小狐狸听故事
  • [C++] new和delete