lanceg 发表于 2007-8-11 13:54:56

VB6、此绘制和文档事件

大家好...我在ADesk VB / VBA论坛上尝试了一下,没有人回应....
我有一个VBA例程,可以很好地与AcadDocument_EndCommand事件配合使用,但是我在尝试将其转换为VB6时遇到问题。我已经阅读了我能找到的所有内容,但仍然无法使其正常工作。事件例程不会触发。
我创建了一个类模块,声明了一个WithEvents AcadDocument,初始化了该类,并在我的程序中放置了一个子,以将我的文档与ThisDrawing连接起来。我像这样创建了ThisDrawing:
**Class Module**
Public WithEvents Doc as AcadDocument
Private Sub Class_Initialize()
Set Doc=Application.ActiveDocument
End Sub
Private Sub Doc_EndCommand(ByVal CommandName as String)
Select Case CommandName
--------- do stuff -------
End Select
End Sub
**Main Sub**
Option Explicit
Dim X as New EventClassModule
Public Application as AcadApplication
Public ThisDrawing as AcadDocument
Sub Main()
Call InitializeEvents
End Sub
Sub InitializeEvents()
On Error Resume Next
Set Application=GetObject(, "AutoCAD.Application")
If Err.Number0 Then
Err. Clear
MsgBox "Start AutoCAD, dummy!"
End
End If
Set ThisDrawing=Application.ActiveDocument
Set X.doc=ThisDrawing
End Sub

ThisDrawing具有适当的属性,并且Doc正确显示了类模块中的事件,但是当我在AutoCAD中结束命令(使用2007)时没有任何反应,尽管它确实可以正常工作VBA版本。缺少了什么?
**** Hidden Message *****

Murph 发表于 2007-8-12 07:47:29

您可以设置Doc=Application。ActiveDocument<br>我没有用VB做任何编程,只是用VBA,但不应该用Doc=AcadApplication。动态文档

Keith™ 发表于 2007-8-12 09:58:51

您的活动编程在哪里?也许那里有问题。

lanceg 发表于 2007-8-12 10:25:51

感谢您的回复。
Murph说:
在我的Main sub中,我设置了Application=AcadApplication,所以我认为这应该可以解决它。我想知道使用像“Application”这样的变量名是否有问题,但至少我的声明应该可以解决Murph的担忧。
Keith说:
事件编程在Class Module中,这是(我认为)它需要的地方。请参阅
部分,上面写着“Private SubDoc_EndCommand(ByVal Command dName as String)”。该部分在VBA中作为Document事件一直工作得很好(从Adesk代码中获得了在VBA中使用设计中心的最初想法),所以我不认为它有什么问题。我甚至无法让第一行执行,Err.Number为0,所以我不认为这是问题所在。
我注意到类模块(或者更确切地说是我的它的实例)在我的主子结束时终止。我现在在想这是因为我没有在ACAD.DVB.中设置我的类实例这可能是整个问题,所以我今天会检查一下。
再次感谢您的回复。
Lance

Keith™ 发表于 2007-8-12 16:18:49


啊..这可能就是问题所在..当main sub实例化该类(保存在变量X中)时,当main sub终止时,保存AutoCAD实例的变量也会终止。在AutoCAD中,只要AutoCAD环境处于打开状态并且启用了VBA,任何全局变量都会保持活动状态,即使在程序结束后也是如此。全局变量不会重置,因为它们由AutoCAD保存在VBA环境中。
在AutoCAD激活期间,您的VB程序应该保持激活状态。尝试在main sub中使用计时器或循环来检查AutoCAD是否处于打开状态。
类似这样的内容:
Sub Main()
Call InitializeEvents
While Application Is Not Nothing
' --- meaningless code to keep program busy ---
Wend
'If Application is nothing (i.e. AutoCAD closed) then let the program end
End Sub

这当然会通过不断评估应用程序来利用一点处理器能力。如果你在你的程序中设置一个计时器来不断地检查应用程序是否处于活动状态,然后在应用程序什么都不是之后停止计时器,它应该会有更好的响应。

lanceg 发表于 2007-8-12 16:57:02

谢谢,基思--我想你已经完全击中了它。
我进去使用了ACAD。DVB文件来创建我的类及其实例,它的工作原理! 当然,问题是,然后我又回到了我开始的VBA。 你的想法正是我需要做的。 至少我不再被困在一个永远不会触发的事件中。 这是有趣的部分。

Keith™ 发表于 2007-8-12 18:44:10

您可以做的是创建自己的应用程序事件并将它们编译为activex dll。如果您想让它变得简单,您可以通过在lisp中创建对象来在lisp中创建您的应用程序实例。您也可以在VBA中创建对象,同时将应用程序保留在单独的dll中,或者只是创建一个activex可执行文件,您可以从Windows运行,并且只要AutoCAD运行就会保持活动状态。您可以通过多种方式来做到这一点,每种方式都有自己的优点和缺点。
如果您需要帮助,这里有很多人可以在您的endevour中帮助您。
祝你好运

lanceg 发表于 2007-8-13 12:40:32

好的,现在我意识到有很多方法可以继续。
我认为使用ACAD。DVB来设置我的事件,然后将检测到事件后运行的实际代码放入DLL或EXE中,这可能是最好的选择。另一方面(创建一个初始化事件的应用程序,然后坐在那里等待事件),我试图按照Keith的建议在我的主sub中放一个等待循环,但最终使我的系统瘫痪了!有没有一种好的方法可以让我的程序保持打开,但在等待事件触发时什么也不做?我刚刚在那里放了一个简单的变量赋值:
Sub Main()
   Call InitializeEvents
   While Not Application Is Nothing
      Set ctr=1
   Wend
   MsgBox "AutoCAD has been shut down"
End Sub
我确信有某种方法可以做到这一点,而不会耗尽我的CPU。
到目前为止,我认为在事件触发时启动单独的DLL或EXE可能更容易、更安全。有人能给我一点指导吗?
预先感谢Lance

Keith™ 发表于 2007-8-13 14:17:34


当然,创建一个用户表单,在表单上放置一个计时器,初始化表单,但是不要显示它。让用户表单上的计时器检查“Application”的值,如果没有找到,就关闭表单。
页: [1]
查看完整版本: VB6、此绘制和文档事件