MSHTML: Beginning implementation of context menu

Jacek Caban jack at itma.pwr.wroc.pl
Thu Aug 25 09:24:41 CDT 2005


Changelog:
    - Beginning implementation of context menu
    - Set nsIWebBrowserChrome of nsIWebBrowser
-------------- next part --------------
Index: dlls/mshtml/mshtml_private.h
===================================================================
RCS file: /home/wine/wine/dlls/mshtml/mshtml_private.h,v
retrieving revision 1.25
diff -u -p -r1.25 mshtml_private.h
--- dlls/mshtml/mshtml_private.h	22 Aug 2005 14:07:49 -0000	1.25
+++ dlls/mshtml/mshtml_private.h	25 Aug 2005 12:19:53 -0000
@@ -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(HTMLD
 void HTMLDocument_NSContainer_Destroy(HTMLDocument*);
 
 void HTMLDocument_LockContainer(HTMLDocument*,BOOL);
+void HTMLDocument_ShowContextMenu(HTMLDocument*,DWORD,POINT*);
 
 HRESULT ProtocolFactory_Create(REFCLSID,REFIID,void**);
 
Index: dlls/mshtml/nsembed.c
===================================================================
RCS file: /home/wine/wine/dlls/mshtml/nsembed.c,v
retrieving revision 1.7
diff -u -p -r1.7 nsembed.c
--- dlls/mshtml/nsembed.c	22 Aug 2005 10:05:29 -0000	1.7
+++ dlls/mshtml/nsembed.c	25 Aug 2005 12:19:53 -0000
@@ -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,10 +563,20 @@ void HTMLDocument_NSContainer_Init(HTMLD
 
     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);
Index: dlls/mshtml/nsiface.idl
===================================================================
RCS file: /home/wine/wine/dlls/mshtml/nsiface.idl,v
retrieving revision 1.2
diff -u -p -r1.2 nsiface.idl
--- dlls/mshtml/nsiface.idl	11 Aug 2005 18:36:48 -0000	1.2
+++ dlls/mshtml/nsiface.idl	25 Aug 2005 12:19:53 -0000
@@ -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,
@@ -302,4 +309,92 @@ interface nsIIOService : nsISupports
     nsresult GetOffline(PRBool *aOffline);
     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);
 }
Index: dlls/mshtml/olewnd.c
===================================================================
RCS file: /home/wine/wine/dlls/mshtml/olewnd.c,v
retrieving revision 1.7
diff -u -p -r1.7 olewnd.c
--- dlls/mshtml/olewnd.c	16 Aug 2005 11:13:01 -0000	1.7
+++ dlls/mshtml/olewnd.c	25 Aug 2005 12:19:53 -0000
@@ -255,6 +255,18 @@ static IOleInPlaceObjectWindowlessVtbl O
 
 #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;


More information about the wine-patches mailing list