diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 73b03af7841..6cbd8695be2 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -29,10 +29,13 @@ #define NS_OK ((nsresult)0x00000000L) #define NS_NOINTERFACE ((nsresult)0x80004002L) #define NS_ERROR_NOT_IMPLEMENTED ((nsresult)0x80004001L) +#define NS_ERROR_INVALID_ARG ((nsresult)0x80070057L) #define NS_FAILED(res) ((res) & 0x80000000) #define NS_SUCCEEDED(res) (!NS_FAILED(res)) +#define NSAPI WINAPI + typedef struct NSContainer NSContainer; typedef struct BindStatusCallback BindStatusCallback; @@ -72,11 +75,16 @@ typedef struct { } HTMLDocument; struct NSContainer { + const nsIWebBrowserChromeVtbl *lpWebBrowserChromeVtbl; + const nsIContextMenuListenerVtbl *lpContextMenuListenerVtbl; + nsIWebBrowser *webbrowser; nsIWebNavigation *navigation; nsIBaseWindow *window; nsIWebBrowserStream *stream; + HTMLDocument *doc; + HWND hwnd; }; @@ -99,6 +107,9 @@ struct NSContainer { #define CONTROL(x) ((IOleControl*) &(x)->lpOleControlVtbl) #define STATUSCLB(x) ((IBindStatusCallback*) &(x)->lpBindStatusCallbackVtbl) +#define NSWBCHROME(x) ((nsIWebBrowserChrome*) &(x)->lpWebBrowserChromeVtbl) +#define NSCML(x) ((nsIContextMenuListener*) &(x)->lpContextMenuListenerVtbl) + #define DEFINE_THIS(cls,ifc,iface) ((cls*)((BYTE*)(iface)-offsetof(cls,lp ## ifc ## Vtbl))) HRESULT HTMLDocument_Create(IUnknown*,REFIID,void**); @@ -113,6 +124,7 @@ void HTMLDocument_NSContainer_Init(HTMLDocument*); void HTMLDocument_NSContainer_Destroy(HTMLDocument*); void HTMLDocument_LockContainer(HTMLDocument*,BOOL); +void HTMLDocument_ShowContextMenu(HTMLDocument*,DWORD,POINT*); HRESULT ProtocolFactory_Create(REFCLSID,REFIID,void**); diff --git a/dlls/mshtml/nsembed.c b/dlls/mshtml/nsembed.c index ac63af71dce..5610233625f 100644 --- a/dlls/mshtml/nsembed.c +++ b/dlls/mshtml/nsembed.c @@ -329,6 +329,228 @@ nsIURI *get_nsIURI(LPCWSTR url) return ret; } +#define NSWBCHROME_THIS(iface) DEFINE_THIS(NSContainer, WebBrowserChrome, iface) + +static nsresult NSAPI nsWebBrowserChrome_QueryInterface(nsIWebBrowserChrome *iface, + nsIIDRef riid, nsQIResult result) +{ + NSContainer *This = NSWBCHROME_THIS(iface); + + *result = NULL; + if(IsEqualGUID(&IID_nsISupports, riid)) { + TRACE("(%p)->(IID_nsISupports, %p)\n", This, result); + *result = NSWBCHROME(This); + }else if(IsEqualGUID(&IID_nsIWebBrowserChrome, riid)) { + TRACE("(%p)->(IID_nsIWebBrowserChrome, %p)\n", This, result); + *result = NSWBCHROME(This); + }else if(IsEqualGUID(&IID_nsIContextMenuListener, riid)) { + TRACE("(%p)->(IID_nsIContextMenuListener, %p)\n", This, result); + *result = NSCML(This); + } + + if(*result) + return NS_OK; + + TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result); + return NS_NOINTERFACE; +} + +static nsrefcnt NSAPI nsWebBrowserChrome_AddRef(nsIWebBrowserChrome *iface) +{ + NSContainer *This = NSWBCHROME_THIS(iface); + TRACE("(%p)\n", This); + return 2; /* Should we implement ref conunting here? */ +} + +static nsrefcnt NSAPI nsWebBrowserChrome_Release(nsIWebBrowserChrome *iface) +{ + NSContainer *This = NSWBCHROME_THIS(iface); + TRACE("(%p)\n", This); + return 1; +} + +static nsresult NSAPI nsWebBrowserChrome_SetStatus(nsIWebBrowserChrome *iface, + PRUint32 statusType, const PRUnichar *status) +{ + NSContainer *This = NSWBCHROME_THIS(iface); + TRACE("(%p)->(%ld %s)\n", This, statusType, debugstr_w(status)); + return NS_ERROR_NOT_IMPLEMENTED; +} + +static nsresult NSAPI nsWebBrowserChrome_GetWebBrowser(nsIWebBrowserChrome *iface, + nsIWebBrowser **aWebBrowser) +{ + NSContainer *This = NSWBCHROME_THIS(iface); + + TRACE("(%p)->(%p)\n", This, aWebBrowser); + + if(!aWebBrowser) + return NS_ERROR_INVALID_ARG; + + *aWebBrowser = This->webbrowser; + return S_OK; +} + +static nsresult NSAPI nsWebBrowserChrome_SetWebBrowser(nsIWebBrowserChrome *iface, + nsIWebBrowser *aWebBrowser) +{ + NSContainer *This = NSWBCHROME_THIS(iface); + + TRACE("(%p)->(%p)\n", This, aWebBrowser); + + if(aWebBrowser != This->webbrowser) + ERR("Wrong nsWebBrowser!\n"); + + return NS_OK; +} + +static nsresult NSAPI nsWebBrowserChrome_GetChromeFlags(nsIWebBrowserChrome *iface, + PRUint32 *aChromeFlags) +{ + NSContainer *This = NSWBCHROME_THIS(iface); + WARN("(%p)->(%p)\n", This, aChromeFlags); + return NS_ERROR_NOT_IMPLEMENTED; +} + +static nsresult NSAPI nsWebBrowserChrome_SetChromeFlags(nsIWebBrowserChrome *iface, + PRUint32 aChromeFlags) +{ + NSContainer *This = NSWBCHROME_THIS(iface); + WARN("(%p)->(%08lx)\n", This, aChromeFlags); + return NS_ERROR_NOT_IMPLEMENTED; +} + +static nsresult NSAPI nsWebBrowserChrome_DestroyBrowserWindow(nsIWebBrowserChrome *iface) +{ + NSContainer *This = NSWBCHROME_THIS(iface); + TRACE("(%p)\n", This); + return NS_ERROR_NOT_IMPLEMENTED; +} + +static nsresult NSAPI nsWebBrowserChrome_SizeBrowserTo(nsIWebBrowserChrome *iface, + PRInt32 aCX, PRInt32 aCY) +{ + NSContainer *This = NSWBCHROME_THIS(iface); + WARN("(%p)->(%ld %ld)\n", This, aCX, aCY); + return NS_ERROR_NOT_IMPLEMENTED; +} + +static nsresult NSAPI nsWebBrowserChrome_ShowAsModal(nsIWebBrowserChrome *iface) +{ + NSContainer *This = NSWBCHROME_THIS(iface); + WARN("(%p)\n", This); + return NS_ERROR_NOT_IMPLEMENTED; +} + +static nsresult NSAPI nsWebBrowserChrome_IsWindowModal(nsIWebBrowserChrome *iface, PRBool *_retval) +{ + NSContainer *This = NSWBCHROME_THIS(iface); + WARN("(%p)->(%p)\n", This, _retval); + return NS_ERROR_NOT_IMPLEMENTED; +} + +static nsresult NSAPI nsWebBrowserChrome_ExitModalEventLoop(nsIWebBrowserChrome *iface, + nsresult aStatus) +{ + NSContainer *This = NSWBCHROME_THIS(iface); + WARN("(%p)->(%08lx)\n", This, aStatus); + return NS_ERROR_NOT_IMPLEMENTED; +} + +#undef NSWBCHROME_THIS + +static const nsIWebBrowserChromeVtbl nsWebBrowserChromeVtbl = { + nsWebBrowserChrome_QueryInterface, + nsWebBrowserChrome_AddRef, + nsWebBrowserChrome_Release, + nsWebBrowserChrome_SetStatus, + nsWebBrowserChrome_GetWebBrowser, + nsWebBrowserChrome_SetWebBrowser, + nsWebBrowserChrome_GetChromeFlags, + nsWebBrowserChrome_SetChromeFlags, + nsWebBrowserChrome_DestroyBrowserWindow, + nsWebBrowserChrome_SizeBrowserTo, + nsWebBrowserChrome_ShowAsModal, + nsWebBrowserChrome_IsWindowModal, + nsWebBrowserChrome_ExitModalEventLoop +}; + +#define NSCML_THIS(iface) DEFINE_THIS(NSContainer, ContextMenuListener, iface) + +static nsresult NSAPI nsContextMenuListener_QueryInterface(nsIContextMenuListener *iface, + nsIIDRef riid, nsQIResult result) +{ + NSContainer *This = NSCML_THIS(iface); + return nsIWebBrowserChrome_QueryInterface(NSWBCHROME(This), riid, result); +} + +static nsrefcnt NSAPI nsContextMenuListener_AddRef(nsIContextMenuListener *iface) +{ + NSContainer *This = NSCML_THIS(iface); + return nsIContextMenuListener_AddRef(NSWBCHROME(This)); +} + +static nsrefcnt NSAPI nsContextMenuListener_Release(nsIContextMenuListener *iface) +{ + NSContainer *This = NSCML_THIS(iface); + return nsIWebBrowserChrome_Release(NSWBCHROME(This)); +} + +static nsresult NSAPI nsContextMenuListener_OnShowContextMenu(nsIContextMenuListener *iface, + PRUint32 aContextFlags, nsIDOMEvent *aEvent, nsIDOMNode *aNode) +{ + NSContainer *This = NSCML_THIS(iface); + nsIDOMMouseEvent *event; + POINT pt; + DWORD dwID = CONTEXT_MENU_DEFAULT; + nsresult nsres; + + TRACE("(%p)->(%08lx %p %p)\n", This, aContextFlags, aEvent, aNode); + + nsres = nsIDOMEvent_QueryInterface(aEvent, &IID_nsIDOMMouseEvent, (void**)&event); + if(NS_FAILED(nsres)) { + ERR("Could not get nsIDOMMouseEvent interface: %08lx\n", nsres); + return nsres; + } + + nsIDOMMouseEvent_GetScreenX(event, &pt.x); + nsIDOMMouseEvent_GetScreenY(event, &pt.y); + nsIDOMMouseEvent_Release(event); + + switch(aContextFlags) { + case CONTEXT_NONE: + case CONTEXT_DOCUMENT: + case CONTEXT_TEXT: + dwID = CONTEXT_MENU_DEFAULT; + break; + case CONTEXT_IMAGE: + case CONTEXT_IMAGE|CONTEXT_LINK: + dwID = CONTEXT_MENU_IMAGE; + break; + case CONTEXT_LINK: + dwID = CONTEXT_MENU_ANCHOR; + break; + case CONTEXT_INPUT: + dwID = CONTEXT_MENU_CONTROL; + break; + default: + FIXME("aContextFlags=%08lx\n", aContextFlags); + }; + + HTMLDocument_ShowContextMenu(This->doc, dwID, &pt); + + return NS_OK; +} + +#undef NSCML_THIS + +static const nsIContextMenuListenerVtbl nsContextMenuListenerVtbl = { + nsContextMenuListener_QueryInterface, + nsContextMenuListener_AddRef, + nsContextMenuListener_Release, + nsContextMenuListener_OnShowContextMenu +}; + void HTMLDocument_NSContainer_Init(HTMLDocument *This) { nsIWebBrowserSetup *wbsetup; @@ -341,11 +563,21 @@ void HTMLDocument_NSContainer_Init(HTMLDocument *This) This->nscontainer = HeapAlloc(GetProcessHeap(), 0, sizeof(NSContainer)); + This->nscontainer->lpWebBrowserChromeVtbl = &nsWebBrowserChromeVtbl; + This->nscontainer->lpContextMenuListenerVtbl = &nsContextMenuListenerVtbl; + + This->nscontainer->doc = This; + nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr, NS_WEBBROWSER_CONTRACTID, NULL, &IID_nsIWebBrowser, (void**)&This->nscontainer->webbrowser); if(NS_FAILED(nsres)) ERR("Creating WebBrowser failed: %08lx\n", nsres); + nsres = nsIWebBrowser_SetContainerWindow(This->nscontainer->webbrowser, + NSWBCHROME(This->nscontainer)); + if(NS_FAILED(nsres)) + ERR("SetContainerWindow failed: %08lx\n", nsres); + nsres = nsIWebBrowser_QueryInterface(This->nscontainer->webbrowser, &IID_nsIBaseWindow, (void**)&This->nscontainer->window); if(NS_FAILED(nsres)) diff --git a/dlls/mshtml/nsiface.idl b/dlls/mshtml/nsiface.idl index 09106a8971c..fc517dcdf35 100644 --- a/dlls/mshtml/nsiface.idl +++ b/dlls/mshtml/nsiface.idl @@ -39,12 +39,15 @@ typedef WCHAR PRUnichar; typedef LPWSTR nswstring; typedef ULONG PRUint32; typedef LONG PRInt32; +typedef WORD PRUint16; typedef BYTE PRUint8; typedef BOOL PRBool; typedef LARGE_INTEGER PRInt64; +typedef ULARGE_INTEGER PRUint64; typedef int nsAString; typedef struct nsACString nsACString; +typedef PRUint64 DOMTimeStamp; interface nsIWebBrowserChrome; @@ -70,6 +73,10 @@ typedef nsISupports nsISimpleEnumerator; typedef nsISupports nsIWidget; typedef nsISupports nsIProtocolHandler; typedef nsISupports nsIChannel; +typedef nsISupports nsIDOMElement; +typedef nsISupports nsIDOMNode; +typedef nsISupports nsIDOMEventTarget; +typedef nsISupports nsIDOMAbstractView; [ object, @@ -303,3 +310,91 @@ interface nsIIOService : nsISupports nsresult SetOffline(PRBool aOffline); nsresult AllowPort(PRInt32 aPort, const char *aScheme, PRBool *_retval); } + +[ + object, + uuid(ba434c60-9d52-11d3-afb0-00a024ffc08c) +] +interface nsIWebBrowserChrome : nsISupports +{ + nsresult SetStatus(PRUint32 statusType, const PRUnichar *status); + nsresult GetWebBrowser(nsIWebBrowser **aWebBrowser); + nsresult SetWebBrowser(nsIWebBrowser *aWebBrowser); + nsresult GetChromeFlags(PRUint32 *aChromeFlags); + nsresult SetChromeFlags(PRUint32 aChromeFlags); + nsresult DestroyBrowserWindow(); + nsresult SizeBrowserTo(PRInt32 aCX, PRInt32 aCY); + nsresult ShowAsModal(); + nsresult IsWindowModal(PRBool *_retval); + nsresult ExitModalEventLoop(nsresult aStatus); +} + +[ + object, + uuid(a66b7b80-ff46-bd97-0080-5f8ae38add32) +] +interface nsIDOMEvent : nsISupports +{ + nsresult GetType(nsAString *aType); + nsresult GetTarget(nsIDOMEventTarget **aTarget); + nsresult GetCurrentTarget(nsIDOMEventTarget **aCurrentTarget); + nsresult GetEventPhase(PRUint16 *aEventPhase); + nsresult GetBubbles(PRBool *aBubbles); + nsresult GetCancelable(PRBool *aCancelable); + nsresult GetTimeStamp(DOMTimeStamp *aTimeStamp); + nsresult StopPropagation(); + nsresult PreventDefault(); + nsresult InitEvent(const nsAString *eventTypeArg, PRBool canBubbleArg, PRBool cancelableArg); +} + +cpp_quote("#define CONTEXT_NONE 0x00"); +cpp_quote("#define CONTEXT_LINK 0x01"); +cpp_quote("#define CONTEXT_IMAGE 0x02"); +cpp_quote("#define CONTEXT_DOCUMENT 0x04"); +cpp_quote("#define CONTEXT_TEXT 0x08"); +cpp_quote("#define CONTEXT_INPUT 0x10"); +cpp_quote("#define CONTEXT_BACKGROUND_IMAGE 0x20"); + +[ + object, + uuid(3478b6b0-3875-11d4-94ef-0020183bf181) +] +interface nsIContextMenuListener : nsISupports +{ + nsresult OnShowContextMenu(PRUint32 aContextFlags, nsIDOMEvent *aEvent, nsIDOMNode *aNode); +} + +[ + object, + uuid(a6cf90c3-15b3-11d2-932e-00805f8add32) +] +interface nsIDOMUIEvent : nsIDOMEvent +{ + nsresult GetView(nsIDOMAbstractView **aView); + nsresult GetDetail(PRInt32 *aDetail); + nsresult InitUIEvent(const nsAString *typeArg, PRBool canBubbleArg, PRBool cancelableArg, + nsIDOMAbstractView *viewArg, PRInt32 detailArg); +} + +[ + object, + uuid(ff751edc-8b02-aae7-0010-8301838a3123) +] +interface nsIDOMMouseEvent : nsIDOMUIEvent +{ + nsresult GetScreenX(PRInt32 *aScreenX); + nsresult GetScreenY(PRInt32 *aScreenY); + nsresult GetClientX(PRInt32 *aClientX); + nsresult GetClientY(PRInt32 *aClientY); + nsresult GetCtrlKey(PRBool *aCtrlKey); + nsresult GetShiftKey(PRBool *aShiftKey); + nsresult GetAltKey(PRBool *aAltKey); + nsresult GetMetaKey(PRBool *aMetaKey); + nsresult GetButton(PRUint16 *aButton); + nsresult GetRelatedTarget(nsIDOMEventTarget * *aRelatedTarget); + nsresult InitMouseEvent(const nsAString *typeArg, PRBool canBubbleArg, PRBool cancelableArg, + nsIDOMAbstractView *viewArg, PRInt32 detailArg, PRInt32 screenXArg, PRInt32 screenYArg, + PRInt32 clientXArg, PRInt32 clientYArg, PRBool ctrlKeyArg, PRBool altKeyArg, + PRBool shiftKeyArg, PRBool metaKeyArg, PRUint16 buttonArg, + nsIDOMEventTarget *relatedTargetArg); +} diff --git a/dlls/mshtml/olewnd.c b/dlls/mshtml/olewnd.c index c1fb1653858..896cdcb11be 100644 --- a/dlls/mshtml/olewnd.c +++ b/dlls/mshtml/olewnd.c @@ -255,6 +255,18 @@ static IOleInPlaceObjectWindowlessVtbl OleInPlaceObjectWindowlessVtbl = { #undef INPLACEWIN_THIS +void HTMLDocument_ShowContextMenu(HTMLDocument *This, DWORD dwID, POINT *ppt) +{ + HRESULT hres; + + hres = IDocHostUIHandler_ShowContextMenu(This->hostui, dwID, ppt, + (IUnknown*)CMDTARGET(This), (IDispatch*)HTMLDOC(This)); + if(hres == S_OK) + return; + + FIXME("Show default context menu\n"); +} + void HTMLDocument_Window_Init(HTMLDocument *This) { This->lpOleInPlaceActiveObjectVtbl = &OleInPlaceActiveObjectVtbl;