Jacek Caban : mshtml: Notify IOleControlSite about focus changes.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Jun 25 07:28:23 CDT 2007


Module: wine
Branch: master
Commit: 5baf587c43f7db5cf45cc364479625de166c499f
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=5baf587c43f7db5cf45cc364479625de166c499f

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Fri Jun 22 23:33:00 2007 +0200

mshtml: Notify IOleControlSite about focus changes.

---

 dlls/mshtml/mshtml_private.h |    4 +++
 dlls/mshtml/nsevents.c       |   48 ++++++++++++++++++++++++++++++++++++++++++
 dlls/mshtml/view.c           |   14 ++++++++++++
 3 files changed, 66 insertions(+), 0 deletions(-)

diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index 1ee8148..1b8b02f 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -116,6 +116,7 @@ struct HTMLDocument {
     BOOL window_active;
     BOOL has_key_path;
     BOOL container_locked;
+    BOOL focus;
 
     DWORD update;
 
@@ -141,6 +142,8 @@ struct NSContainer {
     const nsIWeakReferenceVtbl          *lpWeakReferenceVtbl;
     const nsISupportsWeakReferenceVtbl  *lpSupportsWeakReferenceVtbl;
 
+    nsEventListener blur_listener;
+    nsEventListener focus_listener;
     nsEventListener keypress_listener;
     nsEventListener load_listener;
 
@@ -327,6 +330,7 @@ void NSContainer_Release(NSContainer*);
 
 void HTMLDocument_LockContainer(HTMLDocument*,BOOL);
 void show_context_menu(HTMLDocument*,DWORD,POINT*);
+void notif_focus(HTMLDocument*);
 
 void show_tooltip(HTMLDocument*,DWORD,DWORD,LPCWSTR);
 void hide_tooltip(HTMLDocument*);
diff --git a/dlls/mshtml/nsevents.c b/dlls/mshtml/nsevents.c
index 2a04111..255716c 100644
--- a/dlls/mshtml/nsevents.c
+++ b/dlls/mshtml/nsevents.c
@@ -72,6 +72,46 @@ static nsrefcnt NSAPI nsDOMEventListener_Release(nsIDOMEventListener *iface)
     return nsIWebBrowserChrome_Release(NSWBCHROME(This));
 }
 
+static BOOL is_doc_child_focus(NSContainer *This)
+{
+    HWND hwnd;
+
+    if(!This->doc)
+        return FALSE;
+
+    for(hwnd = GetFocus(); hwnd && hwnd != This->doc->hwnd; hwnd = GetParent(hwnd));
+
+    return hwnd == This->doc->hwnd;
+}
+
+static nsresult NSAPI handle_blur(nsIDOMEventListener *iface, nsIDOMEvent *event)
+{
+    NSContainer *This = NSEVENTLIST_THIS(iface)->This;
+
+    TRACE("(%p)\n", This);
+
+    if(This->doc && This->doc->focus && !is_doc_child_focus(This)) {
+        This->doc->focus = FALSE;
+        notif_focus(This->doc);
+    }
+
+    return NS_OK;
+}
+
+static nsresult NSAPI handle_focus(nsIDOMEventListener *iface, nsIDOMEvent *event)
+{
+    NSContainer *This = NSEVENTLIST_THIS(iface)->This;
+
+    TRACE("(%p)\n", This);
+
+    if(This->doc && !This->doc->focus) {
+        This->doc->focus = TRUE;
+        notif_focus(This->doc);
+    }
+
+    return NS_OK;
+}
+
 static nsresult NSAPI handle_keypress(nsIDOMEventListener *iface,
         nsIDOMEvent *event)
 {
@@ -129,6 +169,8 @@ static nsresult NSAPI handle_load(nsIDOMEventListener *iface, nsIDOMEvent *event
         handler, \
     };
 
+static const nsIDOMEventListenerVtbl blur_vtbl =      EVENTLISTENER_VTBL(handle_blur);
+static const nsIDOMEventListenerVtbl focus_vtbl =     EVENTLISTENER_VTBL(handle_focus);
 static const nsIDOMEventListenerVtbl keypress_vtbl =  EVENTLISTENER_VTBL(handle_keypress);
 static const nsIDOMEventListenerVtbl load_vtbl =      EVENTLISTENER_VTBL(handle_load);
 
@@ -159,9 +201,13 @@ void init_nsevents(NSContainer *This)
     nsIDOMEventTarget *target;
     nsresult nsres;
 
+    static const PRUnichar wsz_blur[]      = {'b','l','u','r',0};
+    static const PRUnichar wsz_focus[]     = {'f','o','c','u','s',0};
     static const PRUnichar wsz_keypress[]  = {'k','e','y','p','r','e','s','s',0};
     static const PRUnichar wsz_load[]      = {'l','o','a','d',0};
 
+    init_listener(&This->blur_listener,        This, &blur_vtbl);
+    init_listener(&This->focus_listener,       This, &focus_vtbl);
     init_listener(&This->keypress_listener,    This, &keypress_vtbl);
     init_listener(&This->load_listener,        This, &load_vtbl);
 
@@ -178,6 +224,8 @@ void init_nsevents(NSContainer *This)
         return;
     }
 
+    init_event(target, wsz_blur,       NSEVENTLIST(&This->blur_listener),        TRUE);
+    init_event(target, wsz_focus,      NSEVENTLIST(&This->focus_listener),       TRUE);
     init_event(target, wsz_keypress,   NSEVENTLIST(&This->keypress_listener),    FALSE);
     init_event(target, wsz_load,       NSEVENTLIST(&This->load_listener),        TRUE);
 
diff --git a/dlls/mshtml/view.c b/dlls/mshtml/view.c
index 14648c7..c51bcf1 100644
--- a/dlls/mshtml/view.c
+++ b/dlls/mshtml/view.c
@@ -164,6 +164,19 @@ static LRESULT on_timer(HTMLDocument *This)
     return 0;
 }
 
+void notif_focus(HTMLDocument *This)
+{
+    IOleControlSite *site;
+    HRESULT hres;
+
+    hres = IOleClientSite_QueryInterface(This->client, &IID_IOleControlSite, (void**)&site);
+    if(FAILED(hres))
+        return;
+
+    IOleControlSite_OnFocus(site, This->focus);
+    IOleControlSite_Release(site);
+}
+
 static LRESULT WINAPI serverwnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
     HTMLDocument *This;
@@ -771,6 +784,7 @@ void HTMLDocument_View_Init(HTMLDocument *This)
     This->in_place_active = FALSE;
     This->ui_active = FALSE;
     This->window_active = FALSE;
+    This->focus = FALSE;
 
     This->update = 0;
 }




More information about the wine-cvs mailing list