diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c
index 3aae813312..25bb78004d 100644
--- a/dlls/mshtml/htmldoc.c
+++ b/dlls/mshtml/htmldoc.c
@@ -140,8 +140,12 @@ static ULONG WINAPI HTMLDocument_Release(IHTMLDocument2 *iface)
IOleInPlaceObjectWindowless_InPlaceDeactivate(INPLACEWIN(This));
if(This->ipsite)
IOleDocumentView_SetInPlaceSite(DOCVIEW(This), NULL);
+
+ if(This->tooltips_hwnd)
+ DestroyWindow(This->tooltips_hwnd);
if(This->hwnd)
DestroyWindow(This->hwnd);
+
release_nodes(This);
if(This->nscontainer)
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index 9a9ac1ed22..478f15206d 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -73,6 +73,7 @@ typedef struct {
IOleInPlaceFrame *frame;
HWND hwnd;
+ HWND tooltips_hwnd;
BOOL in_place_active;
BOOL ui_active;
@@ -86,11 +87,14 @@ typedef struct {
} HTMLDocument;
struct NSContainer {
- const nsIWebBrowserChromeVtbl *lpWebBrowserChromeVtbl;
- const nsIContextMenuListenerVtbl *lpContextMenuListenerVtbl;
- const nsIURIContentListenerVtbl *lpURIContentListenerVtbl;
- const nsIEmbeddingSiteWindowVtbl *lpEmbeddingSiteWindowVtbl;
- const nsIInterfaceRequestorVtbl *lpInterfaceRequestorVtbl;
+ const nsIWebBrowserChromeVtbl *lpWebBrowserChromeVtbl;
+ const nsIContextMenuListenerVtbl *lpContextMenuListenerVtbl;
+ const nsIURIContentListenerVtbl *lpURIContentListenerVtbl;
+ const nsIEmbeddingSiteWindowVtbl *lpEmbeddingSiteWindowVtbl;
+ const nsITooltipListenerVtbl *lpTooltipListenerVtbl;
+ const nsIInterfaceRequestorVtbl *lpInterfaceRequestorVtbl;
+ const nsIWeakReferenceVtbl *lpWeakReferenceVtbl;
+ const nsISupportsWeakReferenceVtbl *lpSupportsWeakReferenceVtbl;
nsIWebBrowser *webbrowser;
nsIWebNavigation *navigation;
@@ -167,6 +171,9 @@ typedef struct {
#define NSURICL(x) ((nsIURIContentListener*) &(x)->lpURIContentListenerVtbl)
#define NSEMBWNDS(x) ((nsIEmbeddingSiteWindow*) &(x)->lpEmbeddingSiteWindowVtbl)
#define NSIFACEREQ(x) ((nsIInterfaceRequestor*) &(x)->lpInterfaceRequestorVtbl)
+#define NSTOOLTIP(x) ((nsITooltipListener*) &(x)->lpTooltipListenerVtbl)
+#define NSWEAKREF(x) ((nsIWeakReference*) &(x)->lpWeakReferenceVtbl)
+#define NSSUPWEAKREF(x) ((nsISupportsWeakReference*) &(x)->lpSupportsWeakReferenceVtbl)
#define HTMLELEM(x) ((IHTMLElement*) &(x)->lpHTMLElementVtbl)
#define HTMLELEM2(x) ((IHTMLElement2*) &(x)->lpHTMLElement2Vtbl)
@@ -190,6 +197,9 @@ void NSContainer_Release(NSContainer*);
void HTMLDocument_LockContainer(HTMLDocument*,BOOL);
void HTMLDocument_ShowContextMenu(HTMLDocument*,DWORD,POINT*);
+void show_tooltip(HTMLDocument*,DWORD,DWORD,LPCWSTR);
+void hide_tooltip(HTMLDocument*);
+
HRESULT ProtocolFactory_Create(REFCLSID,REFIID,void**);
void close_gecko(void);
@@ -200,6 +210,9 @@ void hlink_frame_navigate(HTMLDocument*,IHlinkFrame*,LPCWSTR,nsIInputStream*,DWO
nsIURI *get_nsIURI(LPCWSTR);
+void *nsalloc(size_t);
+void nsfree(void*);
+
void nsACString_Init(nsACString*,const char*);
PRUint32 nsACString_GetData(const nsACString*,const char**,PRBool*);
void nsACString_Finish(nsACString*);
diff --git a/dlls/mshtml/nsembed.c b/dlls/mshtml/nsembed.c
index 9cabc7112b..a64f6a5551 100644
--- a/dlls/mshtml/nsembed.c
+++ b/dlls/mshtml/nsembed.c
@@ -38,6 +38,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
#define NS_APPSTARTUPNOTIFIER_CONTRACTID "@mozilla.org/embedcomp/appstartup-notifier;1"
#define NS_WEBBROWSER_CONTRACTID "@mozilla.org/embedding/browser/nsWebBrowser;1"
#define NS_PROFILE_CONTRACTID "@mozilla.org/profile/manager;1"
+#define NS_MEMORY_CONTRACTID "@mozilla.org/xpcom/memory-service;1"
#define NS_STRINGSTREAM_CONTRACTID "@mozilla.org/io/string-input-stream;1"
#define APPSTARTUP_TOPIC "app-startup"
@@ -68,6 +69,7 @@ static HINSTANCE hXPCOM = NULL;
static nsIServiceManager *pServMgr = NULL;
static nsIComponentManager *pCompMgr = NULL;
+static nsIMemory *nsmem = NULL;
static const WCHAR wszNsContainer[] = {'N','s','C','o','n','t','a','i','n','e','r',0};
@@ -353,6 +355,11 @@ static BOOL load_gecko(void)
set_profile();
+ nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr, NS_MEMORY_CONTRACTID,
+ NULL, &IID_nsIMemory, (void**)&nsmem);
+ if(NS_FAILED(nsres))
+ ERR("Could not get nsIMemory: %08lx\n", nsres);
+
if(registrar) {
register_nsservice(registrar, pServMgr);
nsIComponentRegistrar_Release(registrar);
@@ -361,6 +368,16 @@ static BOOL load_gecko(void)
return TRUE;
}
+void *nsalloc(size_t size)
+{
+ return nsIMemory_Alloc(nsmem, size);
+}
+
+void nsfree(void *mem)
+{
+ nsIMemory_Free(nsmem, mem);
+}
+
void nsACString_Init(nsACString *str, const char *data)
{
NS_CStringContainerInit(str);
@@ -431,6 +448,9 @@ void close_gecko()
if(pServMgr)
nsIServiceManager_Release(pServMgr);
+ if(nsmem)
+ nsIMemory_Release(nsmem);
+
if(hXPCOM)
FreeLibrary(hXPCOM);
}
@@ -462,9 +482,18 @@ static nsresult NSAPI nsWebBrowserChrome_QueryInterface(nsIWebBrowserChrome *ifa
}else if(IsEqualGUID(&IID_nsIEmbeddingSiteWindow, riid)) {
TRACE("(%p)->(IID_nsIEmbeddingSiteWindow %p)\n", This, result);
*result = NSEMBWNDS(This);
+ }else if(IsEqualGUID(&IID_nsITooltipListener, riid)) {
+ TRACE("(%p)->(IID_nsITooltipListener %p)\n", This, result);
+ *result = NSTOOLTIP(This);
}else if(IsEqualGUID(&IID_nsIInterfaceRequestor, riid)) {
TRACE("(%p)->(IID_nsIInterfaceRequestor %p)\n", This, result);
*result = NSIFACEREQ(This);
+ }else if(IsEqualGUID(&IID_nsIWeakReference, riid)) {
+ TRACE("(%p)->(IID_nsIWeakReference %p)\n", This, result);
+ *result = NSWEAKREF(This);
+ }else if(IsEqualGUID(&IID_nsISupportsWeakReference, riid)) {
+ TRACE("(%p)->(IID_nsISupportsWeakReference %p)\n", This, result);
+ *result = NSSUPWEAKREF(This);
}
if(*result) {
@@ -928,6 +957,56 @@ static const nsIEmbeddingSiteWindowVtbl nsEmbeddingSiteWindowVtbl = {
nsEmbeddingSiteWindow_GetSiteWindow
};
+#define NSTOOLTIP_THIS(iface) DEFINE_THIS(NSContainer, TooltipListener, iface)
+
+static nsresult NSAPI nsTooltipListener_QueryInterface(nsITooltipListener *iface, nsIIDRef riid,
+ nsQIResult result)
+{
+ NSContainer *This = NSTOOLTIP_THIS(iface);
+ return nsIWebBrowserChrome_QueryInterface(NSWBCHROME(This), riid, result);
+}
+
+static nsrefcnt NSAPI nsTooltipListener_AddRef(nsITooltipListener *iface)
+{
+ NSContainer *This = NSTOOLTIP_THIS(iface);
+ return nsIWebBrowserChrome_AddRef(NSWBCHROME(This));
+}
+
+static nsrefcnt NSAPI nsTooltipListener_Release(nsITooltipListener *iface)
+{
+ NSContainer *This = NSTOOLTIP_THIS(iface);
+ return nsIWebBrowserChrome_AddRef(NSWBCHROME(This));
+}
+
+static nsresult NSAPI nsTooltipListener_OnShowTooltip(nsITooltipListener *iface,
+ PRInt32 aXCoord, PRInt32 aYCoord, const PRUnichar *aTipText)
+{
+ NSContainer *This = NSTOOLTIP_THIS(iface);
+
+ show_tooltip(This->doc, aXCoord, aYCoord, aTipText);
+
+ return NS_OK;
+}
+
+static nsresult NSAPI nsTooltipListener_OnHideTooltip(nsITooltipListener *iface)
+{
+ NSContainer *This = NSTOOLTIP_THIS(iface);
+
+ hide_tooltip(This->doc);
+
+ return NS_OK;
+}
+
+#undef NSTOOLTIM_THIS
+
+static const nsITooltipListenerVtbl nsTooltipListenerVtbl = {
+ nsTooltipListener_QueryInterface,
+ nsTooltipListener_AddRef,
+ nsTooltipListener_Release,
+ nsTooltipListener_OnShowTooltip,
+ nsTooltipListener_OnHideTooltip
+};
+
#define NSIFACEREQ_THIS(iface) DEFINE_THIS(NSContainer, InterfaceRequestor, iface)
static nsresult NSAPI nsInterfaceRequestor_QueryInterface(nsIInterfaceRequestor *iface,
@@ -971,6 +1050,85 @@ static const nsIInterfaceRequestorVtbl nsInterfaceRequestorVtbl = {
nsInterfaceRequestor_GetInterface
};
+#define NSWEAKREF_THIS(iface) DEFINE_THIS(NSContainer, WeakReference, iface)
+
+static nsresult NSAPI nsWeakReference_QueryInterface(nsIWeakReference *iface,
+ nsIIDRef riid, nsQIResult result)
+{
+ NSContainer *This = NSWEAKREF_THIS(iface);
+ return nsIWebBrowserChrome_QueryInterface(NSWBCHROME(This), riid, result);
+}
+
+static nsrefcnt NSAPI nsWeakReference_AddRef(nsIWeakReference *iface)
+{
+ NSContainer *This = NSWEAKREF_THIS(iface);
+ return nsIWebBrowserChrome_AddRef(NSWBCHROME(This));
+}
+
+static nsrefcnt NSAPI nsWeakReference_Release(nsIWeakReference *iface)
+{
+ NSContainer *This = NSWEAKREF_THIS(iface);
+ return nsIWebBrowserChrome_Release(NSWBCHROME(This));
+}
+
+static nsresult NSAPI nsWeakReference_QueryReferent(nsIWeakReference *iface,
+ const nsIID *riid, void **result)
+{
+ NSContainer *This = NSWEAKREF_THIS(iface);
+ return nsIWebBrowserChrome_QueryInterface(NSWBCHROME(This), riid, result);
+}
+
+#undef NSWEAKREF_THIS
+
+static const nsIWeakReferenceVtbl nsWeakReferenceVtbl = {
+ nsWeakReference_QueryInterface,
+ nsWeakReference_AddRef,
+ nsWeakReference_Release,
+ nsWeakReference_QueryReferent
+};
+
+#define NSSUPWEAKREF_THIS(iface) DEFINE_THIS(NSContainer, SupportsWeakReference, iface)
+
+static nsresult NSAPI nsSupportsWeakReference_QueryInterface(nsISupportsWeakReference *iface,
+ nsIIDRef riid, nsQIResult result)
+{
+ NSContainer *This = NSSUPWEAKREF_THIS(iface);
+ return nsIWebBrowserChrome_QueryInterface(NSWBCHROME(This), riid, result);
+}
+
+static nsrefcnt NSAPI nsSupportsWeakReference_AddRef(nsISupportsWeakReference *iface)
+{
+ NSContainer *This = NSSUPWEAKREF_THIS(iface);
+ return nsIWebBrowserChrome_AddRef(NSWBCHROME(This));
+}
+
+static nsrefcnt NSAPI nsSupportsWeakReference_Release(nsISupportsWeakReference *iface)
+{
+ NSContainer *This = NSSUPWEAKREF_THIS(iface);
+ return nsIWebBrowserChrome_Release(NSWBCHROME(This));
+}
+
+static nsresult NSAPI nsSupportsWeakReference_GetWeakReference(nsISupportsWeakReference *iface,
+ nsIWeakReference **_retval)
+{
+ NSContainer *This = NSSUPWEAKREF_THIS(iface);
+
+ TRACE("(%p)->(%p)\n", This, _retval);
+
+ *_retval = NSWEAKREF(This);
+ return NS_OK;
+}
+
+#undef NSWEAKREF_THIS
+
+const nsISupportsWeakReferenceVtbl nsSupportsWeakReferenceVtbl = {
+ nsSupportsWeakReference_QueryInterface,
+ nsSupportsWeakReference_AddRef,
+ nsSupportsWeakReference_Release,
+ nsSupportsWeakReference_GetWeakReference
+};
+
+
NSContainer *NSContainer_Create(HTMLDocument *doc, NSContainer *parent)
{
nsIWebBrowserSetup *wbsetup;
@@ -982,11 +1140,15 @@ NSContainer *NSContainer_Create(HTMLDocument *doc, NSContainer *parent)
ret = HeapAlloc(GetProcessHeap(), 0, sizeof(NSContainer));
- ret->lpWebBrowserChromeVtbl = &nsWebBrowserChromeVtbl;
- ret->lpContextMenuListenerVtbl = &nsContextMenuListenerVtbl;
- ret->lpURIContentListenerVtbl = &nsURIContentListenerVtbl;
- ret->lpEmbeddingSiteWindowVtbl = &nsEmbeddingSiteWindowVtbl;
- ret->lpInterfaceRequestorVtbl = &nsInterfaceRequestorVtbl;
+ ret->lpWebBrowserChromeVtbl = &nsWebBrowserChromeVtbl;
+ ret->lpContextMenuListenerVtbl = &nsContextMenuListenerVtbl;
+ ret->lpURIContentListenerVtbl = &nsURIContentListenerVtbl;
+ ret->lpEmbeddingSiteWindowVtbl = &nsEmbeddingSiteWindowVtbl;
+ ret->lpTooltipListenerVtbl = &nsTooltipListenerVtbl;
+ ret->lpInterfaceRequestorVtbl = &nsInterfaceRequestorVtbl;
+ ret->lpWeakReferenceVtbl = &nsWeakReferenceVtbl;
+ ret->lpSupportsWeakReferenceVtbl = &nsSupportsWeakReferenceVtbl;
+
ret->doc = doc;
ret->ref = 1;
diff --git a/dlls/mshtml/nsiface.idl b/dlls/mshtml/nsiface.idl
index 176ef9b753..e77090b0e7 100644
--- a/dlls/mshtml/nsiface.idl
+++ b/dlls/mshtml/nsiface.idl
@@ -81,7 +81,6 @@ interface nsISupports
}
/* Currently we don't need a full declaration of these interfaces */
-typedef nsISupports nsIWeakReference;
typedef nsISupports nsISHistory;
typedef nsISupports nsISimpleEnumerator;
typedef nsISupports nsIWidget;
@@ -154,6 +153,37 @@ interface nsIComponentManager : nsISupports
nsIIDRef aIID, nsQIResult result);
}
+[
+ object,
+ uuid(59e7e77a-38e4-11d4-8cf5-0060b0fc14a3)
+]
+interface nsIMemory : nsISupports
+{
+ void *Alloc(/*size_t*/ int size);
+ void *Realloc(void *_ptr, /*size_t*/ int newSize);
+ void Free(void *_ptr);
+ nsresult HeapMinimize(PRBool immediate);
+ nsresult IsLowMemory(PRBool *_retval);
+}
+
+[
+ object,
+ uuid(9188bc85-f92e-11d2-81ef-0060083a0bcf)
+]
+interface nsIWeakReference : nsISupports
+{
+ nsresult QueryReferent(const nsIID *riid, void **result);
+}
+
+[
+ object,
+ uuid(9188bc86-f92e-11d2-81ef-0060083a0bcf)
+]
+interface nsISupportsWeakReference : nsISupports
+{
+ nsresult GetWeakReference(nsIWeakReference **_retval);
+}
+
[
object,
uuid(033a1470-8b2a-11d3-af88-00a024ffc08c)
@@ -615,6 +645,16 @@ interface nsIURIContentListener : nsISupports
nsresult SetParentContentListener(nsIURIContentListener *aParentContentListener);
}
+[
+ object,
+ uuid(44b78386-1dd2-11b2-9ad2-e4eee2ca1916)
+]
+interface nsITooltipListener : nsISupports
+{
+ nsresult OnShowTooltip(PRInt32 aXCoords, PRInt32 aYCoords, const PRUnichar *aTipText);
+ nsresult OnHideTooltip();
+}
+
[
object,
uuid(69e5df00-7b8b-11d3-af61-00a024ffc08c)
@@ -958,6 +998,15 @@ interface nsIPromptService : nsISupports
PRInt32 *aOutSelection, PRBool *_retval);
}
+[
+ object,
+ uuid(b128a1e6-44f3-4331-8fbe-5af360ff21ee)
+]
+interface nsITooltipTextProvider : nsISupports
+{
+ nsresult GetNodeText(nsIDOMNode *aNode, PRUnichar **aText, PRBool *_retval);
+}
+
[
object,
uuid(02b0625a-e7f3-11d2-9f5a-006008a6efe9)
diff --git a/dlls/mshtml/nsservice.c b/dlls/mshtml/nsservice.c
index 62e5a27d54..44550ad080 100644
--- a/dlls/mshtml/nsservice.c
+++ b/dlls/mshtml/nsservice.c
@@ -37,9 +37,14 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
#define NS_PROMPTSERVICE_CONTRACTID "@mozilla.org/embedcomp/prompt-service;1"
#define NS_WINDOWWATCHER_CONTRACTID "@mozilla.org/embedcomp/window-watcher;1"
+#define NS_TOOLTIPTEXTPROVIDER_CONTRACTID "@mozilla.org/embedcomp/tooltiptextprovider;1"
+
+#define NS_TOOLTIPTEXTPROVIDER_CLASSNAME "nsTooltipTextProvider"
static const nsIID NS_PROMPTSERVICE_CID =
{0xa2112d6a,0x0e28,0x421f,{0xb4,0x6a,0x25,0xc0,0xb3,0x8,0xcb,0xd0}};
+static const nsIID NS_TOOLTIPTEXTPROVIDER_CID =
+ {0x0b666e3e,0x569a,0x462c,{0xa7,0xf0,0xb1,0x6b,0xb1,0x5d,0x42,0xff}};
static nsresult NSAPI nsWindowCreator_QueryInterface(nsIWindowCreator2 *iface, nsIIDRef riid,
nsQIResult result)
@@ -260,6 +265,104 @@ static const nsIPromptServiceVtbl PromptServiceVtbl = {
static nsIPromptService nsPromptService = { &PromptServiceVtbl };
+static nsresult NSAPI nsTooltipTextProvider_QueryInterface(nsITooltipTextProvider *iface,
+ nsIIDRef riid, nsQIResult result)
+{
+ *result = NULL;
+
+ if(IsEqualGUID(&IID_nsISupports, riid)) {
+ TRACE("(IID_nsISupports %p)\n", result);
+ *result = iface;
+ }else if(IsEqualGUID(&IID_nsITooltipTextProvider, riid)) {
+ TRACE("(IID_nsITooltipTextProvider %p)\n", result);
+ *result = iface;
+ }
+
+ if(*result) {
+ nsITooltipTextProvider_AddRef(iface);
+ return NS_OK;
+ }
+
+ WARN("(%s %p)\n", debugstr_guid(riid), result);
+ return NS_NOINTERFACE;
+}
+
+static nsrefcnt NSAPI nsTooltipTextProvider_AddRef(nsITooltipTextProvider *iface)
+{
+ return 2;
+}
+
+static nsrefcnt NSAPI nsTooltipTextProvider_Release(nsITooltipTextProvider *iface)
+{
+ return 1;
+}
+
+static nsresult NSAPI nsTooltipTextProvider_GetNodeText(nsITooltipTextProvider *iface,
+ nsIDOMNode *aNode, PRUnichar **aText, PRBool *_retval)
+{
+ nsIDOMHTMLElement *nselem;
+ nsIDOMNode *node = aNode, *parent;
+ nsAString title_str;
+ const PRUnichar *title = NULL;
+ nsresult nsres;
+
+ TRACE("(%p %p %p)\n", aNode, aText, _retval);
+
+ *aText = NULL;
+
+ nsAString_Init(&title_str, NULL);
+
+ do {
+ nsres = nsIDOMNode_QueryInterface(node, &IID_nsIDOMHTMLElement, (void**)&nselem);
+ if(NS_SUCCEEDED(nsres)) {
+ title = NULL;
+
+ nsIDOMHTMLElement_GetTitle(nselem, &title_str);
+ nsIDOMHTMLElement_Release(nselem);
+
+ nsAString_GetData(&title_str, &title, NULL);
+ if(title && *title) {
+ if(node != aNode)
+ nsIDOMNode_Release(node);
+ break;
+ }
+ }
+
+ nsres = nsIDOMNode_GetParentNode(node, &parent);
+ if(NS_FAILED(nsres))
+ parent = NULL;
+
+ if(node != aNode)
+ nsIDOMNode_Release(node);
+ node = parent;
+ } while(node);
+
+ if(title && *title) {
+ int size = (strlenW(title)+1)*sizeof(PRUnichar);
+
+ *aText = nsalloc(size);
+ memcpy(*aText, title, size);
+ TRACE("aText = %s\n", debugstr_w(*aText));
+
+ *_retval = TRUE;
+ }else {
+ *_retval = FALSE;
+ }
+
+ nsAString_Finish(&title_str);
+
+ return NS_OK;
+}
+
+static const nsITooltipTextProviderVtbl nsTooltipTextProviderVtbl = {
+ nsTooltipTextProvider_QueryInterface,
+ nsTooltipTextProvider_AddRef,
+ nsTooltipTextProvider_Release,
+ nsTooltipTextProvider_GetNodeText
+};
+
+static nsITooltipTextProvider nsTooltipTextProvider = { &nsTooltipTextProviderVtbl };
+
typedef struct {
const nsIFactoryVtbl *lpFactoryVtbl;
nsISupports *service;
@@ -333,6 +436,11 @@ static nsServiceFactory nsPromptServiceFactory = {
(nsISupports*)&nsPromptService
};
+static nsServiceFactory nsTooltipTextFactory = {
+ &nsServiceFactoryVtbl,
+ (nsISupports*)&nsTooltipTextProvider
+};
+
void register_nsservice(nsIComponentRegistrar *registrar, nsIServiceManager *service_manager)
{
nsIWindowWatcher *window_watcher;
@@ -354,4 +462,10 @@ void register_nsservice(nsIComponentRegistrar *registrar, nsIServiceManager *ser
}else {
ERR("Could not get WindowWatcher object: %08lx\n", nsres);
}
+
+ nsres = nsIComponentRegistrar_RegisterFactory(registrar, &NS_TOOLTIPTEXTPROVIDER_CID,
+ NS_TOOLTIPTEXTPROVIDER_CLASSNAME, NS_TOOLTIPTEXTPROVIDER_CONTRACTID,
+ NSFACTORY(&nsTooltipTextFactory));
+ if(NS_FAILED(nsres))
+ ERR("RegisterFactory failed: %08lx\n", nsres);
}
diff --git a/dlls/mshtml/view.c b/dlls/mshtml/view.c
index dda2f4bc7a..31e0b07770 100644
--- a/dlls/mshtml/view.c
+++ b/dlls/mshtml/view.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2005 Jacek Caban
+ * Copyright 2005-2006 Jacek Caban for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -27,6 +27,7 @@
#include "winbase.h"
#include "winuser.h"
#include "wingdi.h"
+#include "commctrl.h"
#include "ole2.h"
#include "resource.h"
@@ -39,8 +40,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
static const WCHAR wszInternetExplorer_Server[] =
{'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','_','S','e','r','v','e','r',0};
+static const WCHAR wszTooltipData[] = {'t','o','o','l','t','i','p','_','d','a','t','a',0};
+
static ATOM serverwnd_class = 0;
+typedef struct {
+ HTMLDocument *doc;
+ WNDPROC proc;
+} tooltip_data;
+
static void paint_disabled(HWND hwnd) {
HDC hdc;
PAINTSTRUCT ps;
@@ -149,6 +157,7 @@ static HRESULT activate_window(HTMLDocument *This)
WARN("GetWindowContext failed: %08lx\n", hres);
return hres;
}
+
if(pIPWnd)
IOleInPlaceUIWindow_Release(pIPWnd);
TRACE("got window context: %p %p {%ld %ld %ld %ld} {%ld %ld %ld %ld} {%d %x %p %p %d}\n",
@@ -221,6 +230,77 @@ static HRESULT activate_window(HTMLDocument *This)
return S_OK;
}
+static LRESULT tooltips_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ tooltip_data *data = GetPropW(hwnd, wszTooltipData);
+
+ TRACE("%d %p\n", msg, data);
+
+ if(msg == TTM_WINDOWFROMPOINT) {
+ RECT rect;
+ POINT *pt = (POINT*)lParam;
+
+ TRACE("TTM_WINDOWFROMPOINT (%ld,%ld)\n", pt->x, pt->y);
+
+ GetWindowRect(data->doc->hwnd, &rect);
+
+ if(rect.left <= pt->x && pt->x <= rect.right
+ && rect.top <= pt->y && pt->y <= rect.bottom)
+ return (LPARAM)data->doc->hwnd;
+ }
+
+ return CallWindowProcW(data->proc, hwnd, msg, wParam, lParam);
+}
+
+static void create_tooltips_window(HTMLDocument *This)
+{
+ tooltip_data *data = HeapAlloc(GetProcessHeap(), 0, sizeof(*data));
+
+ This->tooltips_hwnd = CreateWindowExW(0, TOOLTIPS_CLASSW, NULL, TTS_NOPREFIX | WS_POPUP,
+ CW_USEDEFAULT, CW_USEDEFAULT, 10, 10, This->hwnd, NULL, hInst, NULL);
+
+ data->doc = This;
+ data->proc = (WNDPROC)GetWindowLongPtrW(This->tooltips_hwnd, GWLP_WNDPROC);
+
+ SetPropW(This->tooltips_hwnd, wszTooltipData, data);
+
+ SetWindowLongPtrW(This->tooltips_hwnd, GWLP_WNDPROC, (LONG_PTR)tooltips_proc);
+
+ SetWindowPos(This->tooltips_hwnd, HWND_TOPMOST,0, 0, 0, 0,
+ SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+
+}
+
+void show_tooltip(HTMLDocument *This, DWORD x, DWORD y, LPCWSTR text)
+{
+ TTTOOLINFOW toolinfo = {
+ sizeof(TTTOOLINFOW), 0, This->hwnd, 0xdeadbeef,
+ {x>2 ? x-2 : 0, y>0 ? y-2 : 0, x+2, y+2}, /* FIXME */
+ NULL, (LPWSTR)text, 0};
+ MSG msg = {This->hwnd, WM_MOUSEMOVE, 0, MAKELPARAM(x,y), 0, {x,y}};
+
+ TRACE("(%p)->(%ld %ld %s)\n", This, x, y, debugstr_w(text));
+
+ if(!This->tooltips_hwnd)
+ create_tooltips_window(This);
+
+ SendMessageW(This->tooltips_hwnd, TTM_ADDTOOLW, 0, (LPARAM)&toolinfo);
+ SendMessageW(This->tooltips_hwnd, TTM_ACTIVATE, TRUE, 0);
+ SendMessageW(This->tooltips_hwnd, TTM_RELAYEVENT, 0, (LPARAM)&msg);
+}
+
+void hide_tooltip(HTMLDocument *This)
+{
+ TTTOOLINFOW toolinfo = {
+ sizeof(TTTOOLINFOW), 0, This->hwnd, 0xdeadbeef,
+ {0,0,0,0}, NULL, NULL, 0};
+
+ TRACE("(%p)\n", This);
+
+ SendMessageW(This->tooltips_hwnd, TTM_DELTOOLW, 0, (LPARAM)&toolinfo);
+ SendMessageW(This->tooltips_hwnd, TTM_ACTIVATE, FALSE, 0);
+}
+
/**********************************************************
* IOleDocumentView implementation
*/
@@ -579,6 +659,7 @@ void HTMLDocument_View_Init(HTMLDocument *This)
This->ipsite = NULL;
This->frame = NULL;
This->hwnd = NULL;
+ This->tooltips_hwnd = NULL;
This->in_place_active = FALSE;
This->ui_active = FALSE;