HTMLCanvasElement类型不匹配

时间:2016-09-22 21:00:55

标签: vba mshtml type-mismatch

我正在使用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。

2 个答案:

答案 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中的IHTMLElementHTMLCanvasElement之间也没有投射的方法。看起来tlb的布局可能会限制你要么设法Function Declare试图欺骗编组人员给你一个强类型的对象引用,或者通过某种类型的包装来完成它。 / p>

答案 1 :(得分:0)

您是否尝试将其声明为IHTMLCanvasElement

https://msdn.microsoft.com/en-us/library/ff975817(v=vs.85).aspx