317 lines
9.1 KiB
Go
317 lines
9.1 KiB
Go
// Copyright 2010 The Walk Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// +build windows
|
|
|
|
package walk
|
|
|
|
import (
|
|
"syscall"
|
|
"unsafe"
|
|
)
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/lxn/win"
|
|
)
|
|
|
|
var webViewDWebBrowserEvents2Vtbl *win.DWebBrowserEvents2Vtbl
|
|
|
|
func init() {
|
|
AppendToWalkInit(func() {
|
|
webViewDWebBrowserEvents2Vtbl = &win.DWebBrowserEvents2Vtbl{
|
|
syscall.NewCallback(webView_DWebBrowserEvents2_QueryInterface),
|
|
syscall.NewCallback(webView_DWebBrowserEvents2_AddRef),
|
|
syscall.NewCallback(webView_DWebBrowserEvents2_Release),
|
|
syscall.NewCallback(webView_DWebBrowserEvents2_GetTypeInfoCount),
|
|
syscall.NewCallback(webView_DWebBrowserEvents2_GetTypeInfo),
|
|
syscall.NewCallback(webView_DWebBrowserEvents2_GetIDsOfNames),
|
|
syscall.NewCallback(webView_DWebBrowserEvents2_Invoke),
|
|
}
|
|
})
|
|
}
|
|
|
|
type webViewDWebBrowserEvents2 struct {
|
|
win.DWebBrowserEvents2
|
|
}
|
|
|
|
func webView_DWebBrowserEvents2_QueryInterface(wbe2 *webViewDWebBrowserEvents2, riid win.REFIID, ppvObject *unsafe.Pointer) uintptr {
|
|
// Just reuse the QueryInterface implementation we have for IOleClientSite.
|
|
// We need to adjust object, which initially points at our
|
|
// webViewDWebBrowserEvents2, so it refers to the containing
|
|
// webViewIOleClientSite for the call.
|
|
var clientSite win.IOleClientSite
|
|
var webViewInPlaceSite webViewIOleInPlaceSite
|
|
var docHostUIHandler webViewIDocHostUIHandler
|
|
|
|
ptr := uintptr(unsafe.Pointer(wbe2)) -
|
|
uintptr(unsafe.Sizeof(clientSite)) -
|
|
uintptr(unsafe.Sizeof(webViewInPlaceSite)) -
|
|
uintptr(unsafe.Sizeof(docHostUIHandler))
|
|
|
|
return webView_IOleClientSite_QueryInterface((*webViewIOleClientSite)(unsafe.Pointer(ptr)), riid, ppvObject)
|
|
}
|
|
|
|
func webView_DWebBrowserEvents2_AddRef(args *uintptr) uintptr {
|
|
return 1
|
|
}
|
|
|
|
func webView_DWebBrowserEvents2_Release(args *uintptr) uintptr {
|
|
return 1
|
|
}
|
|
|
|
func webView_DWebBrowserEvents2_GetTypeInfoCount(args *uintptr) uintptr {
|
|
/* p := (*struct {
|
|
wbe2 *webViewDWebBrowserEvents2
|
|
pctinfo *uint
|
|
})(unsafe.Pointer(args))
|
|
|
|
*p.pctinfo = 0
|
|
|
|
return S_OK*/
|
|
|
|
return win.E_NOTIMPL
|
|
}
|
|
|
|
func webView_DWebBrowserEvents2_GetTypeInfo(args *uintptr) uintptr {
|
|
/* p := (*struct {
|
|
wbe2 *webViewDWebBrowserEvents2
|
|
})(unsafe.Pointer(args))
|
|
|
|
unsigned int iTInfo,
|
|
LCID lcid,
|
|
ITypeInfo FAR* FAR* ppTInfo*/
|
|
|
|
return win.E_NOTIMPL
|
|
}
|
|
|
|
func webView_DWebBrowserEvents2_GetIDsOfNames(args *uintptr) uintptr {
|
|
/* p := (*struct {
|
|
wbe2 *webViewDWebBrowserEvents2
|
|
riid REFIID
|
|
rgszNames **uint16
|
|
cNames uint32
|
|
lcid LCID
|
|
rgDispId *DISPID
|
|
})(unsafe.Pointer(args))*/
|
|
|
|
return win.E_NOTIMPL
|
|
}
|
|
|
|
/*
|
|
func webView_DWebBrowserEvents2_Invoke(
|
|
wbe2 *webViewDWebBrowserEvents2,
|
|
dispIdMember win.DISPID,
|
|
riid win.REFIID,
|
|
lcid uint32, // LCID
|
|
wFlags uint16,
|
|
pDispParams *win.DISPPARAMS,
|
|
pVarResult *win.VARIANT,
|
|
pExcepInfo unsafe.Pointer, // *EXCEPINFO
|
|
puArgErr *uint32) uintptr {
|
|
*/
|
|
func webView_DWebBrowserEvents2_Invoke(
|
|
arg0 uintptr,
|
|
arg1 uintptr,
|
|
arg2 uintptr,
|
|
arg3 uintptr,
|
|
arg4 uintptr,
|
|
arg5 uintptr,
|
|
arg6 uintptr,
|
|
arg7 uintptr,
|
|
arg8 uintptr) uintptr {
|
|
|
|
wbe2 := (*webViewDWebBrowserEvents2)(unsafe.Pointer(arg0))
|
|
dispIdMember := *(*win.DISPID)(unsafe.Pointer(&arg1))
|
|
//riid := *(*win.REFIID)(unsafe.Pointer(&arg2))
|
|
//lcid := *(*uint32)(unsafe.Pointer(&arg3))
|
|
//wFlags := *(*uint16)(unsafe.Pointer(&arg4))
|
|
pDispParams := (*win.DISPPARAMS)(unsafe.Pointer(arg5))
|
|
//pVarResult := (*win.VARIANT)(unsafe.Pointer(arg6))
|
|
//pExcepInfo := unsafe.Pointer(arg7)
|
|
//puArgErr := (*uint32)(unsafe.Pointer(arg8))
|
|
|
|
var wb WidgetBase
|
|
var wvcs webViewIOleClientSite
|
|
|
|
wv := (*WebView)(unsafe.Pointer(uintptr(unsafe.Pointer(wbe2)) +
|
|
uintptr(unsafe.Sizeof(*wbe2)) -
|
|
uintptr(unsafe.Sizeof(wvcs)) -
|
|
uintptr(unsafe.Sizeof(wb))))
|
|
|
|
switch dispIdMember {
|
|
case win.DISPID_BEFORENAVIGATE2:
|
|
rgvargPtr := (*[7]win.VARIANTARG)(unsafe.Pointer(pDispParams.Rgvarg))
|
|
eventData := &WebViewNavigatingEventData{
|
|
pDisp: (*rgvargPtr)[6].MustPDispatch(),
|
|
url: (*rgvargPtr)[5].MustPVariant(),
|
|
flags: (*rgvargPtr)[4].MustPVariant(),
|
|
targetFrameName: (*rgvargPtr)[3].MustPVariant(),
|
|
postData: (*rgvargPtr)[2].MustPVariant(),
|
|
headers: (*rgvargPtr)[1].MustPVariant(),
|
|
cancel: (*rgvargPtr)[0].MustPBool(),
|
|
}
|
|
wv.navigatingPublisher.Publish(eventData)
|
|
|
|
case win.DISPID_NAVIGATECOMPLETE2:
|
|
rgvargPtr := (*[2]win.VARIANTARG)(unsafe.Pointer(pDispParams.Rgvarg))
|
|
url := (*rgvargPtr)[0].MustPVariant()
|
|
urlStr := ""
|
|
if url != nil && url.MustBSTR() != nil {
|
|
urlStr = win.BSTRToString(url.MustBSTR())
|
|
}
|
|
wv.navigatedPublisher.Publish(urlStr)
|
|
|
|
wv.urlChangedPublisher.Publish()
|
|
|
|
case win.DISPID_DOWNLOADBEGIN:
|
|
wv.downloadingPublisher.Publish()
|
|
|
|
case win.DISPID_DOWNLOADCOMPLETE:
|
|
wv.downloadedPublisher.Publish()
|
|
|
|
case win.DISPID_DOCUMENTCOMPLETE:
|
|
rgvargPtr := (*[2]win.VARIANTARG)(unsafe.Pointer(pDispParams.Rgvarg))
|
|
url := (*rgvargPtr)[0].MustPVariant()
|
|
urlStr := ""
|
|
if url != nil && url.MustBSTR() != nil {
|
|
urlStr = win.BSTRToString(url.MustBSTR())
|
|
}
|
|
|
|
// FIXME: Horrible hack to avoid glitch where the document is not displayed.
|
|
time.AfterFunc(time.Millisecond*100, func() {
|
|
wv.Synchronize(func() {
|
|
b := wv.BoundsPixels()
|
|
b.Width++
|
|
wv.SetBoundsPixels(b)
|
|
b.Width--
|
|
wv.SetBoundsPixels(b)
|
|
})
|
|
})
|
|
|
|
wv.documentCompletedPublisher.Publish(urlStr)
|
|
|
|
case win.DISPID_NAVIGATEERROR:
|
|
rgvargPtr := (*[5]win.VARIANTARG)(unsafe.Pointer(pDispParams.Rgvarg))
|
|
eventData := &WebViewNavigatedErrorEventData{
|
|
pDisp: (*rgvargPtr)[4].MustPDispatch(),
|
|
url: (*rgvargPtr)[3].MustPVariant(),
|
|
targetFrameName: (*rgvargPtr)[2].MustPVariant(),
|
|
statusCode: (*rgvargPtr)[1].MustPVariant(),
|
|
cancel: (*rgvargPtr)[0].MustPBool(),
|
|
}
|
|
wv.navigatedErrorPublisher.Publish(eventData)
|
|
|
|
case win.DISPID_NEWWINDOW3:
|
|
rgvargPtr := (*[5]win.VARIANTARG)(unsafe.Pointer(pDispParams.Rgvarg))
|
|
eventData := &WebViewNewWindowEventData{
|
|
ppDisp: (*rgvargPtr)[4].MustPPDispatch(),
|
|
cancel: (*rgvargPtr)[3].MustPBool(),
|
|
dwFlags: (*rgvargPtr)[2].MustULong(),
|
|
bstrUrlContext: (*rgvargPtr)[1].MustBSTR(),
|
|
bstrUrl: (*rgvargPtr)[0].MustBSTR(),
|
|
}
|
|
wv.newWindowPublisher.Publish(eventData)
|
|
|
|
case win.DISPID_ONQUIT:
|
|
wv.quittingPublisher.Publish()
|
|
|
|
case win.DISPID_WINDOWCLOSING:
|
|
rgvargPtr := (*[2]win.VARIANTARG)(unsafe.Pointer(pDispParams.Rgvarg))
|
|
eventData := &WebViewWindowClosingEventData{
|
|
bIsChildWindow: (*rgvargPtr)[1].MustBool(),
|
|
cancel: (*rgvargPtr)[0].MustPBool(),
|
|
}
|
|
wv.windowClosingPublisher.Publish(eventData)
|
|
|
|
case win.DISPID_ONSTATUSBAR:
|
|
rgvargPtr := (*[1]win.VARIANTARG)(unsafe.Pointer(pDispParams.Rgvarg))
|
|
statusBar := (*rgvargPtr)[0].MustBool()
|
|
if statusBar != win.VARIANT_FALSE {
|
|
wv.statusBarVisible = true
|
|
} else {
|
|
wv.statusBarVisible = false
|
|
}
|
|
wv.statusBarVisibleChangedPublisher.Publish()
|
|
|
|
case win.DISPID_ONTHEATERMODE:
|
|
rgvargPtr := (*[1]win.VARIANTARG)(unsafe.Pointer(pDispParams.Rgvarg))
|
|
theaterMode := (*rgvargPtr)[0].MustBool()
|
|
if theaterMode != win.VARIANT_FALSE {
|
|
wv.isTheaterMode = true
|
|
} else {
|
|
wv.isTheaterMode = false
|
|
}
|
|
wv.theaterModeChangedPublisher.Publish()
|
|
|
|
case win.DISPID_ONTOOLBAR:
|
|
rgvargPtr := (*[1]win.VARIANTARG)(unsafe.Pointer(pDispParams.Rgvarg))
|
|
toolBar := (*rgvargPtr)[0].MustBool()
|
|
if toolBar != win.VARIANT_FALSE {
|
|
wv.toolBarVisible = true
|
|
} else {
|
|
wv.toolBarVisible = false
|
|
}
|
|
wv.toolBarVisibleChangedPublisher.Publish()
|
|
|
|
case win.DISPID_ONVISIBLE:
|
|
rgvargPtr := (*[1]win.VARIANTARG)(unsafe.Pointer(pDispParams.Rgvarg))
|
|
vVisible := (*rgvargPtr)[0].MustBool()
|
|
if vVisible != win.VARIANT_FALSE {
|
|
wv.browserVisible = true
|
|
} else {
|
|
wv.browserVisible = false
|
|
}
|
|
wv.browserVisibleChangedPublisher.Publish()
|
|
|
|
case win.DISPID_COMMANDSTATECHANGE:
|
|
rgvargPtr := (*[2]win.VARIANTARG)(unsafe.Pointer(pDispParams.Rgvarg))
|
|
command := (*rgvargPtr)[1].MustLong()
|
|
enable := (*rgvargPtr)[0].MustBool()
|
|
enableBool := (enable != win.VARIANT_FALSE)
|
|
switch command {
|
|
case win.CSC_UPDATECOMMANDS:
|
|
wv.toolBarEnabled = enableBool
|
|
wv.toolBarEnabledChangedPublisher.Publish()
|
|
|
|
case win.CSC_NAVIGATEFORWARD:
|
|
wv.canGoForward = enableBool
|
|
wv.canGoForwardChangedPublisher.Publish()
|
|
|
|
case win.CSC_NAVIGATEBACK:
|
|
wv.canGoBack = enableBool
|
|
wv.canGoBackChangedPublisher.Publish()
|
|
}
|
|
|
|
case win.DISPID_PROGRESSCHANGE:
|
|
rgvargPtr := (*[2]win.VARIANTARG)(unsafe.Pointer(pDispParams.Rgvarg))
|
|
wv.progressValue = (*rgvargPtr)[1].MustLong()
|
|
wv.progressMax = (*rgvargPtr)[0].MustLong()
|
|
wv.progressChangedPublisher.Publish()
|
|
|
|
case win.DISPID_STATUSTEXTCHANGE:
|
|
rgvargPtr := (*[1]win.VARIANTARG)(unsafe.Pointer(pDispParams.Rgvarg))
|
|
sText := (*rgvargPtr)[0].MustBSTR()
|
|
if sText != nil {
|
|
wv.statusText = win.BSTRToString(sText)
|
|
} else {
|
|
wv.statusText = ""
|
|
}
|
|
wv.statusTextChangedPublisher.Publish()
|
|
|
|
case win.DISPID_TITLECHANGE:
|
|
rgvargPtr := (*[1]win.VARIANTARG)(unsafe.Pointer(pDispParams.Rgvarg))
|
|
sText := (*rgvargPtr)[0].MustBSTR()
|
|
if sText != nil {
|
|
wv.documentTitle = win.BSTRToString(sText)
|
|
} else {
|
|
wv.documentTitle = ""
|
|
}
|
|
wv.documentTitleChangedPublisher.Publish()
|
|
}
|
|
|
|
return win.DISP_E_MEMBERNOTFOUND
|
|
}
|