我正在使用VBA编写一个带有Canvas的InternetExplorer实例。我已经设置好了,所以我可以使用VBA中的类,如Circle和Line在画布上绘制。这一切都很好,我有一个力导向动画图。
但是,现在我正在尝试捕获用户事件,例如鼠标点击作为VBA中的事件,我遇到了一个奇怪的问题。 我创建了一个HTMLCanvasElement类型的变量,但是当我尝试将HTMLCanvasElement对象分配给它时,我收到类型不匹配错误。
注意:您需要为InternetExplorer
类对象添加对“Microsoft Internet Controls”的引用,为MSHTML类对象添加“Microsoft HTML Object Library”。
Option Compare Database
Option Explicit
Dim ie As InternetExplorer
Dim document As HTMLDocument
Dim WithEvents window As HTMLWindow2
Dim ctx As ICanvasRenderingContext2D
Dim WithEvents canvas As MSHTML.HTMLCanvasElement
Private Sub Class_Initialize()
Set ie = New InternetExplorer
ie.StatusBar = False
ie.AddressBar = False
ie.MenuBar = False
ie.Toolbar = False
ie.Navigate "about:blank"
While Not ie.ReadyState = READYSTATE_COMPLETE
DoEvents
Wend
ie.Visible = True
Set document = ie.document
document.body.innerHTML = "<div><canvas id='myCanvas' width='10' height='10' style=""border:1px solid #000000;"">" & _
"Your browser does not support the HTML5 canvas tag" & _
"</canvas></div>"
'Set canvas = document.getElementById("myCanvas") 'This line triggers a Type Mismatch!!!
Set ctx = document.getElementById("myCanvas").getContext("2d")
Set window = document.parentWindow
resizeCanvas
End Sub
Private Sub window_onload()
window_onresize
End Sub
Private Sub window_onresize()
resizeCanvas
End Sub
Public Sub resizeCanvas()
ctx.canvas.Width = window.innerWidth - 23
ctx.canvas.Height = window.innerHeight - 23
redraw
End Sub
Public Function isClosed() As Boolean
isClosed = window.closed
End Function
Private Sub redraw()
'redraw shapes using ctx
End Sub
Public Sub Clear()
ctx.clearRect 0, 0, ctx.canvas.Width, ctx.canvas.Height
End Sub
我注释掉了类型不匹配的行,因此您可以看到所有内容都以该异常运行。
我测试了一些不同的东西:
document.getElementById("myCanvas")
的类型列为HTMLCanvasElement ?TypeName(document.getElementById("myCanvas"))
返回“HTMLCanvasElement”?typeof document.getElementById("myCanvas") is HTMLCanvasElement
返回错误。这绝对是奇怪的,让我想知道是否在mshtml.tlb类型库中错误地定义了HTMLCanvasElement。答案 0 :(得分:2)
我冒昧地打开tlb去看看自己。这是如何定义的:
[id(0x00000440)]
HRESULT getElementById(
[in] BSTR v,
[out, retval] IHTMLElement** pel);
请注意,它返回一个接口指针,而不是强类型对象。这可能会给你的作品带来麻烦,因为HTMLCanvasElement
不可创造:
[
uuid(305106E5-98B5-11CF-BB82-00AA00BDCE0B),
noncreatable
]
coclass HTMLCanvasElement {
tlb中的 nothing 返回coclass的一个实例。这会产生一个声明WithEvents
的问题,因为IHTMLCanvasElement
没有来源事件 - 来自HTMLElementEvents
。
请注意,在VBA中的IHTMLElement
和HTMLCanvasElement
之间也没有投射的方法。看起来tlb的布局可能会限制你要么设法Function Declare
试图欺骗编组人员给你一个强类型的对象引用,或者通过某种类型的包装来完成它。 / p>
答案 1 :(得分:0)
您是否尝试将其声明为IHTMLCanvasElement
?
https://msdn.microsoft.com/en-us/library/ff975817(v=vs.85).aspx