为了驯服wild ActiveX objects,我正在实现自定义事件处理程序,我可以将其分配给每个ActiveX控件。
我目前已经实现了一个类,例如WSCheckboxEventHandler:
Option Explicit
Private WithEvents m_ole As MSForms.CheckBox
Private m_ws As Worksheet
Public Sub init(p_SourceOLE As MSForms.CheckBox, p_ws As Worksheet)
Set m_ole = p_SourceOLE
Set m_ws = p_ws
End Sub
Private Sub m_ole_Click()
Debug.Print "Checkbox click for " + m_ole.name
m_ole.Left = m_ole.Left
m_ole.Width = m_ole.Width
m_ole.Height = m_ole.Height
m_ole.Top = m_ole.Top
m_ws.Shapes(m_ole.name).ScaleHeight 1.25, msoFalse, msoScaleFromTopLeft
m_ws.Shapes(m_ole.name).ScaleHeight 0.8, msoFalse, msoScaleFromTopLeft
End Sub
在工作表模块中,m_WSObjectEventHandler
作为私有变量,以下内容完美地设置了处理程序:
Set m_WSObjectEventHandler = New WSCheckboxEventHandler
m_WSObjectEventHandler.init Sheet1.chk_DraftMode, Sheet1
基本上这是一个黑客工作,可以直观地调整对象的大小 - 通过调用这些命令,我强制它们保持正确的大小。 linked question above details this problem。
但是,这需要我为每种类型的控件创建一个单独的事件处理程序。我现在大概有7个,所以我创建了一个单独的类,它基本上用作这些的伪工厂,传入工作表,然后遍历所有ActiveX对象并通过丑陋的select语句创建适当的处理程序: / p>
For Each mOLE In m_ws.OLEObjects
Select Case TypeName(mOLE.Object)
Case "CheckBox"
Set mCheckBoxHndlr = New WSCheckboxEventHandler
mCheckBoxHndlr.init mOLE.Object, m_ws
m_CheckBoxes.Add mCheckBoxHndlr
'etc... there are a lot of these!
Case Default
Debug.Print "Default"
End Select
Next mOLE
这让我有一个工作表变量包含所有事件处理程序作为成员集合。丑陋?是的,但它将允许更好的代码重用。
我希望能够为所有 ActiveX对象类型实现单个事件处理程序(有很多,上面的工厂类型类将会有一个巨大的丑陋的switch语句)。在上面的事件处理程序中基本上将MSForms.CheckBox
更改为MSForms.Control
。没有必要将相同的代码复制到5个以上的事件处理程序中并保持这种状态是很棒的。更不用说避免丑陋的选择陈述。
如何将控件引用为有效的MSForms.Control
对象并相应地设置事件处理程序?我基本上想将MSForms.CheckBox
类型转换为MSForms.Control
对象。
或者,是否有可能以某种方式获取MSForms.Control
对象?它似乎根本不是OLEObject.Object的一部分(我得到类型错误)。