--- a/caps/include/nsScriptSecurityManager.h
+++ b/caps/include/nsScriptSecurityManager.h
@@ -583,16 +583,23 @@ private:
nsresult
InitDomainPolicy(JSContext* cx, const char* aPolicyName,
DomainPolicy* aDomainPolicy);
nsresult
InitPrincipals(PRUint32 prefCount, const char** prefNames);
+
+#ifdef XPC_IDISPATCH_SUPPORT
+ // While this header is included outside of caps, this class isn't
+ // referenced so this should be fine.
+ nsresult
+ CheckComponentPermissions(JSContext *cx, const nsCID &aCID);
+#endif
#ifdef DEBUG_CAPS_HACKER
void
PrintPolicyDB();
#endif
struct ContextPrincipal {
ContextPrincipal(ContextPrincipal *next, JSContext *cx,
JSStackFrame *fp, nsIPrincipal *principal)
@@ -620,16 +627,20 @@ private:
nsCOMPtr<nsIPrefBranch> mPrefBranch;
nsCOMPtr<nsIPrincipal> mSystemPrincipal;
nsCOMPtr<nsIPrincipal> mSystemCertificate;
ContextPrincipal *mContextPrincipals;
nsInterfaceHashtable<PrincipalKey, nsIPrincipal> mPrincipals;
PRPackedBool mIsJavaScriptEnabled;
PRPackedBool mIsWritingPrefs;
PRPackedBool mPolicyPrefsChanged;
+#ifdef XPC_IDISPATCH_SUPPORT
+ PRPackedBool mXPCDefaultGrantAll;
+ static const char sXPCDefaultGrantAllName[];
+#endif
static PRBool sStrictFileOriginPolicy;
static nsIIOService *sIOService;
static nsIXPConnect *sXPConnect;
static nsIThreadJSContextStack* sJSContextStack;
static nsIStringBundle *sStrBundle;
static JSRuntime *sRuntime;
--- a/caps/src/Makefile.in
+++ b/caps/src/Makefile.in
@@ -53,13 +53,17 @@ CPPSRCS = \
nsSystemPrincipal.cpp \
nsNullPrincipal.cpp \
nsNullPrincipalURI.cpp \
nsJSPrincipals.cpp \
nsScriptSecurityManager.cpp \
nsSecurityManagerFactory.cpp \
$(NULL)
+ifdef XPC_IDISPATCH_SUPPORT
+DEFINES += -DXPC_IDISPATCH_SUPPORT
+endif
+
include $(topsrcdir)/config/rules.mk
INCLUDES += -I$(srcdir)/../include \
-I$(topsrcdir)/js/src/xpconnect/src
--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -3085,28 +3085,88 @@ nsScriptSecurityManager::CanCreateWrappe
{
printf("GRANTED.\n");
#endif
}
return rv;
}
+#ifdef XPC_IDISPATCH_SUPPORT
+nsresult
+nsScriptSecurityManager::CheckComponentPermissions(JSContext *cx,
+ const nsCID &aCID)
+{
+ nsresult rv;
+ nsIPrincipal* subjectPrincipal = GetSubjectPrincipal(cx, &rv);
+ if (NS_FAILED(rv))
+ return rv;
+
+ // Reformat the CID string so it's suitable for prefs
+ nsXPIDLCString cidTemp;
+ cidTemp.Adopt(aCID.ToString());
+ nsCAutoString cid(NS_LITERAL_CSTRING("CID") +
+ Substring(cidTemp, 1, cidTemp.Length() - 2));
+ ToUpperCase(cid);
+
+#ifdef DEBUG_CAPS_CheckComponentPermissions
+ printf("### CheckComponentPermissions(ClassID.%s) ",cid.get());
+#endif
+
+ // Look up the policy for this class.
+ // while this isn't a property we'll treat it as such, using ACCESS_CALL_METHOD
+ JSAutoRequest ar(cx);
+ jsid cidId = INTERNED_STRING_TO_JSID(::JS_InternString(cx, cid.get()));
+
+ ClassInfoData nameData(nsnull, "ClassID");
+ SecurityLevel securityLevel;
+ rv = LookupPolicy(subjectPrincipal, nameData, cidId,
+ nsIXPCSecurityManager::ACCESS_CALL_METHOD,
+ nsnull, &securityLevel);
+ if (NS_FAILED(rv))
+ return rv;
+
+ // If there's no policy stored, use the "security.classID.allowByDefault" pref
+ if (securityLevel.level == SCRIPT_SECURITY_UNDEFINED_ACCESS)
+ securityLevel.level = mXPCDefaultGrantAll ? SCRIPT_SECURITY_ALL_ACCESS :
+ SCRIPT_SECURITY_NO_ACCESS;
+
+ if (securityLevel.level == SCRIPT_SECURITY_ALL_ACCESS)
+ {
+#ifdef DEBUG_CAPS_CheckComponentPermissions
+ printf(" GRANTED.\n");
+#endif
+ return NS_OK;
+ }
+
+#ifdef DEBUG_CAPS_CheckComponentPermissions
+ printf(" DENIED.\n");
+#endif
+ return NS_ERROR_DOM_PROP_ACCESS_DENIED;
+}
+#endif
+
NS_IMETHODIMP
nsScriptSecurityManager::CanCreateInstance(JSContext *cx,
const nsCID &aCID)
{
#ifdef DEBUG_CAPS_CanCreateInstance
char* cidStr = aCID.ToString();
printf("### CanCreateInstance(%s) ", cidStr);
NS_Free(cidStr);
#endif
nsresult rv = CheckXPCPermissions(nsnull, nsnull, nsnull, nsnull, nsnull);
if (NS_FAILED(rv))
+#ifdef XPC_IDISPATCH_SUPPORT
+ {
+ rv = CheckComponentPermissions(cx, aCID);
+ }
+ if (NS_FAILED(rv))
+#endif
{
//-- Access denied, report an error
nsCAutoString errorMsg("Permission denied to create instance of class. CID=");
char cidStr[NSID_LENGTH];
aCID.ToProvidedString(cidStr);
errorMsg.Append(cidStr);
SetPendingException(cx, errorMsg.get());
@@ -3317,16 +3377,19 @@ nsScriptSecurityManager::Observe(nsISupp
nsScriptSecurityManager::nsScriptSecurityManager(void)
: mOriginToPolicyMap(nsnull),
mDefaultPolicy(nsnull),
mCapabilities(nsnull),
mContextPrincipals(nsnull),
mIsJavaScriptEnabled(PR_FALSE),
mIsWritingPrefs(PR_FALSE),
mPolicyPrefsChanged(PR_TRUE)
+#ifdef XPC_IDISPATCH_SUPPORT
+ , mXPCDefaultGrantAll(PR_FALSE)
+#endif
{
NS_ASSERTION(sizeof(PRWord) == sizeof(void*),
"PRWord and void* have different lengths on this platform. "
"This may cause a security failure with the SecurityLevel union.");
mPrincipals.Init(31);
}
@@ -3914,40 +3977,55 @@ nsScriptSecurityManager::InitPrincipals(
}
return NS_OK;
}
const char nsScriptSecurityManager::sJSEnabledPrefName[] =
"javascript.enabled";
const char nsScriptSecurityManager::sFileOriginPolicyPrefName[] =
"security.fileuri.strict_origin_policy";
+#ifdef XPC_IDISPATCH_SUPPORT
+const char nsScriptSecurityManager::sXPCDefaultGrantAllName[] =
+ "security.classID.allowByDefault";
+#endif
inline void
nsScriptSecurityManager::ScriptSecurityPrefChanged()
{
// JavaScript defaults to enabled in failure cases.
mIsJavaScriptEnabled = PR_TRUE;
sStrictFileOriginPolicy = PR_TRUE;
+#ifdef XPC_IDISPATCH_SUPPORT
+ // Granting XPC Priveleges defaults to disabled in failure cases.
+ mXPCDefaultGrantAll = PR_FALSE;
+#endif
+
nsresult rv;
if (!mPrefBranch) {
rv = InitPrefs();
if (NS_FAILED(rv))
return;
}
PRBool temp;
rv = mPrefBranch->GetBoolPref(sJSEnabledPrefName, &temp);
if (NS_SUCCEEDED(rv))
mIsJavaScriptEnabled = temp;
rv = mPrefBranch->GetBoolPref(sFileOriginPolicyPrefName, &temp);
if (NS_SUCCEEDED(rv))
sStrictFileOriginPolicy = NS_SUCCEEDED(rv) && temp;
+
+#ifdef XPC_IDISPATCH_SUPPORT
+ rv = mPrefBranch->GetBoolPref(sXPCDefaultGrantAllName, &temp);
+ if (NS_SUCCEEDED(rv))
+ mXPCDefaultGrantAll = temp;
+#endif
}
nsresult
nsScriptSecurityManager::InitPrefs()
{
nsresult rv;
nsCOMPtr<nsIPrefService> prefService(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
NS_ENSURE_SUCCESS(rv, rv);
@@ -3956,16 +4034,19 @@ nsScriptSecurityManager::InitPrefs()
nsCOMPtr<nsIPrefBranch2> prefBranchInternal(do_QueryInterface(mPrefBranch, &rv));
NS_ENSURE_SUCCESS(rv, rv);
// Set the initial value of the "javascript.enabled" prefs
ScriptSecurityPrefChanged();
// set observer callbacks in case the value of the prefs change
prefBranchInternal->AddObserver(sJSEnabledPrefName, this, PR_FALSE);
prefBranchInternal->AddObserver(sFileOriginPolicyPrefName, this, PR_FALSE);
+#ifdef XPC_IDISPATCH_SUPPORT
+ prefBranchInternal->AddObserver(sXPCDefaultGrantAllName, this, PR_FALSE);
+#endif
PRUint32 prefCount;
char** prefNames;
// Set a callback for policy pref changes
prefBranchInternal->AddObserver(sPolicyPrefix, this, PR_FALSE);
//-- Initialize the principals database from prefs
rv = mPrefBranch->GetChildList(sPrincipalPrefix, &prefCount, &prefNames);
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -130,17 +130,20 @@ IBMBIDI = @IBMBIDI@
MOZ_UNIVERSALCHARDET = @MOZ_UNIVERSALCHARDET@
ACCESSIBILITY = @ACCESSIBILITY@
MOZ_BRANDING_DIRECTORY = @MOZ_BRANDING_DIRECTORY@
XPCOM_USE_LEA = @XPCOM_USE_LEA@
MOZ_INSTALLER = @MOZ_INSTALLER@
MOZ_UPDATER = @MOZ_UPDATER@
MOZ_UPDATE_CHANNEL = @MOZ_UPDATE_CHANNEL@
MOZ_UPDATE_PACKAGING = @MOZ_UPDATE_PACKAGING@
+MOZ_NO_ACTIVEX_SUPPORT = @MOZ_NO_ACTIVEX_SUPPORT@
+MOZ_ACTIVEX_SCRIPTING_SUPPORT = @MOZ_ACTIVEX_SCRIPTING_SUPPORT@
MOZ_DISABLE_PARENTAL_CONTROLS = @MOZ_DISABLE_PARENTAL_CONTROLS@
+XPC_IDISPATCH_SUPPORT = @XPC_IDISPATCH_SUPPORT@
NS_ENABLE_TSF = @NS_ENABLE_TSF@
MOZ_SPELLCHECK = @MOZ_SPELLCHECK@
MOZ_PROFILELOCKING = @MOZ_PROFILELOCKING@
MOZ_FEEDS = @MOZ_FEEDS@
MOZ_TOOLKIT_SEARCH = @MOZ_TOOLKIT_SEARCH@
MOZ_PLACES = @MOZ_PLACES@
MOZ_STORAGE = @MOZ_STORAGE@
MOZ_SAFE_BROWSING = @MOZ_SAFE_BROWSING@
--- a/configure.in
+++ b/configure.in
@@ -4750,25 +4750,27 @@ dnl ====================================
dnl =
dnl = Application
dnl =
dnl ========================================================
MOZ_ARG_HEADER(Application)
ENABLE_TESTS=1
+MOZ_ACTIVEX_SCRIPTING_SUPPORT=
MOZ_BRANDING_DIRECTORY=
MOZ_OFFICIAL_BRANDING=
MOZ_FEEDS=1
MOZ_INSTALLER=1
MOZ_JSDEBUGGER=1
MOZ_CSS_ANIMATIONS=1
MOZ_MORK=
MOZ_MORKREADER=1
MOZ_AUTH_EXTENSION=1
+MOZ_NO_ACTIVEX_SUPPORT=1
MOZ_NO_FAST_LOAD=
MOZ_OGG=1
MOZ_RAW=
MOZ_SYDNEYAUDIO=
MOZ_VORBIS=
MOZ_TREMOR=
MOZ_WAVE=1
MOZ_MEDIA=
@@ -4812,16 +4814,17 @@ MOZ_PDF_PRINTING=
MOZ_DISABLE_DOMCRYPTO=
NSS_DISABLE_DBM=
NECKO_WIFI=1
NECKO_COOKIES=1
NECKO_DISK_CACHE=1
NECKO_PROTOCOLS_DEFAULT="about data file ftp http res viewsource websocket wyciwyg"
USE_ARM_KUSER=
BUILD_CTYPES=1
+XPC_IDISPATCH_SUPPORT=
case "${target}" in
*android*|*darwin*)
ACCESSIBILITY=
;;
*)
ACCESSIBILITY=1
@@ -6492,16 +6495,58 @@ AC_SUBST(MOZ_UPDATE_CHANNEL)
MOZ_ARG_ENABLE_BOOL(update-packaging,
[ --enable-update-packaging
Enable tools/update-packaging],
MOZ_UPDATE_PACKAGING=1,
MOZ_UPDATE_PACKAGING= )
AC_SUBST(MOZ_UPDATE_PACKAGING)
dnl ========================================================
+dnl ActiveX
+dnl ========================================================
+
+MOZ_ARG_DISABLE_BOOL(xpconnect-idispatch,
+[ --disable-xpconnect-idispatch
+ Disable building of xpconnect support for IDispatch
+ (win32 only)],
+ XPC_IDISPATCH_SUPPORT=,
+ XPC_IDISPATCH_SUPPORT=1)
+AC_SUBST(XPC_IDISPATCH_SUPPORT)
+
+MOZ_ARG_DISABLE_BOOL(activex,
+[ --disable-activex Disable building of ActiveX control (win32 only)],
+ MOZ_NO_ACTIVEX_SUPPORT=1,
+ MOZ_NO_ACTIVEX_SUPPORT= )
+AC_SUBST(MOZ_NO_ACTIVEX_SUPPORT)
+
+MOZ_ARG_ENABLE_BOOL(activex-scripting,
+[ --enable-activex-scripting
+ Enable building of ActiveX scripting support (win32)],
+ MOZ_ACTIVEX_SCRIPTING_SUPPORT=1,
+ MOZ_ACTIVEX_SCRIPTING_SUPPORT=)
+AC_SUBST(MOZ_ACTIVEX_SCRIPTING_SUPPORT)
+
+if test -n "$MOZ_NO_ACTIVEX_SUPPORT" -a -n "$MOZ_ACTIVEX_SCRIPTING_SUPPORT";
+then
+ AC_MSG_ERROR([Cannot enable ActiveX scripting support when ActiveX support is disabled.])
+fi
+
+if test "$COMPILE_ENVIRONMENT" = "1"; then
+if test -n "$XPC_IDISPATCH_SUPPORT" -o -n "$MOZ_ACTIVEX_SCRIPTING_SUPPORT" -o -z "$MOZ_NO_ACTIVEX_SUPPORT"; then
+case "$target" in
+*-mingw*)
+ if test "$ac_cv_header_atlbase_h" = "no"; then
+ AC_MSG_ERROR([System header atlbase.h is not available. See http://developer.mozilla.org/en/docs/atlbase.h for details on fixing this problem.])
+ fi
+ ;;
+esac
+fi
+fi
+
+dnl ========================================================
dnl leaky
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(leaky,
[ --enable-leaky Build leaky memory tool],
MOZ_LEAKY=1,
MOZ_LEAKY=)
--- a/embedding/browser/Makefile.in
+++ b/embedding/browser/Makefile.in
@@ -40,9 +40,15 @@ DEPTH = ../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = webBrowser build
+ifeq ($(OS_ARCH),WINNT)
+ifndef MOZ_NO_ACTIVEX_SUPPORT
+TOOL_DIRS += activex/src
+endif
+endif
+
include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/embedding/browser/activex/src/Makefile.in
@@ -0,0 +1,59 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Mozilla browser.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications, Inc.
+# Portions created by the Initial Developer are Copyright (C) 2001
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH = ../../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE = activex
+
+DIRS = $(NULL)
+
+# Common
+DIRS += common
+
+# ActiveX plugin
+ifdef MOZ_ACTIVEX_SCRIPTING_SUPPORT
+DIRS += plugin
+endif
+
+# The ActiveX control is now built in tier 99 from mozilla/Makefile.in
+
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/embedding/browser/activex/src/common/CPMozillaControl.h
@@ -0,0 +1,949 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+#ifndef CPMOZILLACONTROL_H
+#define CPMOZILLACONTROL_H
+
+//////////////////////////////////////////////////////////////////////////////
+// CProxyDWebBrowserEvents
+template <class T>
+class CProxyDWebBrowserEvents : public IConnectionPointImpl<T, &DIID_DWebBrowserEvents, CComDynamicUnkArray>
+{
+public:
+//methods:
+//DWebBrowserEvents : IDispatch
+public:
+ void Fire_BeforeNavigate(
+ BSTR URL,
+ long Flags,
+ BSTR TargetFrameName,
+ VARIANT * PostData,
+ BSTR Headers,
+ VARIANT_BOOL * Cancel)
+ {
+ VARIANTARG* pvars = new VARIANTARG[6];
+ for (int i = 0; i < 6; i++)
+ VariantInit(&pvars[i]);
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ pvars[5].vt = VT_BSTR;
+ pvars[5].bstrVal= URL;
+ pvars[4].vt = VT_I4;
+ pvars[4].lVal= Flags;
+ pvars[3].vt = VT_BSTR;
+ pvars[3].bstrVal= TargetFrameName;
+ pvars[2].vt = VT_VARIANT | VT_BYREF;
+ pvars[2].byref= PostData;
+ pvars[1].vt = VT_BSTR;
+ pvars[1].bstrVal= Headers;
+ pvars[0].vt = VT_BOOL | VT_BYREF;
+ pvars[0].byref= Cancel;
+ DISPPARAMS disp = { pvars, NULL, 6, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0x64, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ delete[] pvars;
+ }
+ void Fire_NavigateComplete(
+ BSTR URL)
+ {
+ VARIANTARG* pvars = new VARIANTARG[1];
+ for (int i = 0; i < 1; i++)
+ VariantInit(&pvars[i]);
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ pvars[0].vt = VT_BSTR;
+ pvars[0].bstrVal= URL;
+ DISPPARAMS disp = { pvars, NULL, 1, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0x65, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ delete[] pvars;
+ }
+ void Fire_StatusTextChange(
+ BSTR Text)
+ {
+ VARIANTARG* pvars = new VARIANTARG[1];
+ for (int i = 0; i < 1; i++)
+ VariantInit(&pvars[i]);
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ pvars[0].vt = VT_BSTR;
+ pvars[0].bstrVal= Text;
+ DISPPARAMS disp = { pvars, NULL, 1, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0x66, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ delete[] pvars;
+ }
+ void Fire_ProgressChange(
+ long Progress,
+ long ProgressMax)
+ {
+ VARIANTARG* pvars = new VARIANTARG[2];
+ for (int i = 0; i < 2; i++)
+ VariantInit(&pvars[i]);
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ pvars[1].vt = VT_I4;
+ pvars[1].lVal= Progress;
+ pvars[0].vt = VT_I4;
+ pvars[0].lVal= ProgressMax;
+ DISPPARAMS disp = { pvars, NULL, 2, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0x6c, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ delete[] pvars;
+ }
+ void Fire_DownloadComplete()
+ {
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ DISPPARAMS disp = { NULL, NULL, 0, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0x68, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ }
+ void Fire_CommandStateChange(
+ long Command,
+ VARIANT_BOOL Enable)
+ {
+ VARIANTARG* pvars = new VARIANTARG[2];
+ for (int i = 0; i < 2; i++)
+ VariantInit(&pvars[i]);
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ pvars[1].vt = VT_I4;
+ pvars[1].lVal= Command;
+ pvars[0].vt = VT_BOOL;
+ pvars[0].boolVal= Enable;
+ DISPPARAMS disp = { pvars, NULL, 2, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0x69, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ delete[] pvars;
+ }
+ void Fire_DownloadBegin()
+ {
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ DISPPARAMS disp = { NULL, NULL, 0, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0x6a, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ }
+ void Fire_NewWindow(
+ BSTR URL,
+ long Flags,
+ BSTR TargetFrameName,
+ VARIANT * PostData,
+ BSTR Headers,
+ VARIANT_BOOL * Processed)
+ {
+ VARIANTARG* pvars = new VARIANTARG[6];
+ for (int i = 0; i < 6; i++)
+ VariantInit(&pvars[i]);
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ pvars[5].vt = VT_BSTR;
+ pvars[5].bstrVal= URL;
+ pvars[4].vt = VT_I4;
+ pvars[4].lVal= Flags;
+ pvars[3].vt = VT_BSTR;
+ pvars[3].bstrVal= TargetFrameName;
+ pvars[2].vt = VT_VARIANT | VT_BYREF;
+ pvars[2].byref= PostData;
+ pvars[1].vt = VT_BSTR;
+ pvars[1].bstrVal= Headers;
+ pvars[0].vt = VT_BOOL | VT_BYREF;
+ pvars[0].byref= Processed;
+ DISPPARAMS disp = { pvars, NULL, 6, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0x6b, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ delete[] pvars;
+ }
+ void Fire_TitleChange(
+ BSTR Text)
+ {
+ VARIANTARG* pvars = new VARIANTARG[1];
+ for (int i = 0; i < 1; i++)
+ VariantInit(&pvars[i]);
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ pvars[0].vt = VT_BSTR;
+ pvars[0].bstrVal= Text;
+ DISPPARAMS disp = { pvars, NULL, 1, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0x71, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ delete[] pvars;
+ }
+ void Fire_FrameBeforeNavigate(
+ BSTR URL,
+ long Flags,
+ BSTR TargetFrameName,
+ VARIANT * PostData,
+ BSTR Headers,
+ VARIANT_BOOL * Cancel)
+ {
+ VARIANTARG* pvars = new VARIANTARG[6];
+ for (int i = 0; i < 6; i++)
+ VariantInit(&pvars[i]);
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ pvars[5].vt = VT_BSTR;
+ pvars[5].bstrVal= URL;
+ pvars[4].vt = VT_I4;
+ pvars[4].lVal= Flags;
+ pvars[3].vt = VT_BSTR;
+ pvars[3].bstrVal= TargetFrameName;
+ pvars[2].vt = VT_VARIANT | VT_BYREF;
+ pvars[2].byref= PostData;
+ pvars[1].vt = VT_BSTR;
+ pvars[1].bstrVal= Headers;
+ pvars[0].vt = VT_BOOL | VT_BYREF;
+ pvars[0].byref= Cancel;
+ DISPPARAMS disp = { pvars, NULL, 6, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0xc8, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ delete[] pvars;
+ }
+ void Fire_FrameNavigateComplete(
+ BSTR URL)
+ {
+ VARIANTARG* pvars = new VARIANTARG[1];
+ for (int i = 0; i < 1; i++)
+ VariantInit(&pvars[i]);
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ pvars[0].vt = VT_BSTR;
+ pvars[0].bstrVal= URL;
+ DISPPARAMS disp = { pvars, NULL, 1, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0xc9, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ delete[] pvars;
+ }
+ void Fire_FrameNewWindow(
+ BSTR URL,
+ long Flags,
+ BSTR TargetFrameName,
+ VARIANT * PostData,
+ BSTR Headers,
+ VARIANT_BOOL * Processed)
+ {
+ VARIANTARG* pvars = new VARIANTARG[6];
+ for (int i = 0; i < 6; i++)
+ VariantInit(&pvars[i]);
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ pvars[5].vt = VT_BSTR;
+ pvars[5].bstrVal= URL;
+ pvars[4].vt = VT_I4;
+ pvars[4].lVal= Flags;
+ pvars[3].vt = VT_BSTR;
+ pvars[3].bstrVal= TargetFrameName;
+ pvars[2].vt = VT_VARIANT | VT_BYREF;
+ pvars[2].byref= PostData;
+ pvars[1].vt = VT_BSTR;
+ pvars[1].bstrVal= Headers;
+ pvars[0].vt = VT_BOOL | VT_BYREF;
+ pvars[0].byref= Processed;
+ DISPPARAMS disp = { pvars, NULL, 6, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0xcc, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ delete[] pvars;
+ }
+ void Fire_Quit(
+ VARIANT_BOOL * Cancel)
+ {
+ VARIANTARG* pvars = new VARIANTARG[1];
+ for (int i = 0; i < 1; i++)
+ VariantInit(&pvars[i]);
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ pvars[0].vt = VT_BOOL | VT_BYREF;
+ pvars[0].byref= Cancel;
+ DISPPARAMS disp = { pvars, NULL, 1, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0x67, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ delete[] pvars;
+ }
+ void Fire_WindowMove()
+ {
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ DISPPARAMS disp = { NULL, NULL, 0, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0x6d, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ }
+ void Fire_WindowResize()
+ {
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ DISPPARAMS disp = { NULL, NULL, 0, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0x6e, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ }
+ void Fire_WindowActivate()
+ {
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ DISPPARAMS disp = { NULL, NULL, 0, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0x6f, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ }
+ void Fire_PropertyChange(
+ BSTR Property)
+ {
+ VARIANTARG* pvars = new VARIANTARG[1];
+ for (int i = 0; i < 1; i++)
+ VariantInit(&pvars[i]);
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ pvars[0].vt = VT_BSTR;
+ pvars[0].bstrVal= Property;
+ DISPPARAMS disp = { pvars, NULL, 1, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0x70, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ delete[] pvars;
+ }
+
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+// CProxyDWebBrowserEvents2
+template <class T>
+class CProxyDWebBrowserEvents2 : public IConnectionPointImpl<T, &DIID_DWebBrowserEvents2, CComDynamicUnkArray>
+{
+public:
+//methods:
+//DWebBrowserEvents2 : IDispatch
+public:
+ void Fire_StatusTextChange(
+ BSTR Text)
+ {
+ VARIANTARG* pvars = new VARIANTARG[1];
+ for (int i = 0; i < 1; i++)
+ VariantInit(&pvars[i]);
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ pvars[0].vt = VT_BSTR;
+ pvars[0].bstrVal= Text;
+ DISPPARAMS disp = { pvars, NULL, 1, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0x66, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ delete[] pvars;
+ }
+ void Fire_ProgressChange(
+ long Progress,
+ long ProgressMax)
+ {
+ VARIANTARG* pvars = new VARIANTARG[2];
+ for (int i = 0; i < 2; i++)
+ VariantInit(&pvars[i]);
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ pvars[1].vt = VT_I4;
+ pvars[1].lVal= Progress;
+ pvars[0].vt = VT_I4;
+ pvars[0].lVal= ProgressMax;
+ DISPPARAMS disp = { pvars, NULL, 2, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0x6c, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ delete[] pvars;
+ }
+ void Fire_CommandStateChange(
+ long Command,
+ VARIANT_BOOL Enable)
+ {
+ VARIANTARG* pvars = new VARIANTARG[2];
+ for (int i = 0; i < 2; i++)
+ VariantInit(&pvars[i]);
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ pvars[1].vt = VT_I4;
+ pvars[1].lVal= Command;
+ pvars[0].vt = VT_BOOL;
+ pvars[0].boolVal= Enable;
+ DISPPARAMS disp = { pvars, NULL, 2, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0x69, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ delete[] pvars;
+ }
+ void Fire_DownloadBegin()
+ {
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ DISPPARAMS disp = { NULL, NULL, 0, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0x6a, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ }
+ void Fire_DownloadComplete()
+ {
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ DISPPARAMS disp = { NULL, NULL, 0, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0x68, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ }
+ void Fire_TitleChange(
+ BSTR Text)
+ {
+ VARIANTARG* pvars = new VARIANTARG[1];
+ for (int i = 0; i < 1; i++)
+ VariantInit(&pvars[i]);
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ pvars[0].vt = VT_BSTR;
+ pvars[0].bstrVal= Text;
+ DISPPARAMS disp = { pvars, NULL, 1, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0x71, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ delete[] pvars;
+ }
+ void Fire_PropertyChange(
+ BSTR szProperty)
+ {
+ VARIANTARG* pvars = new VARIANTARG[1];
+ for (int i = 0; i < 1; i++)
+ VariantInit(&pvars[i]);
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ pvars[0].vt = VT_BSTR;
+ pvars[0].bstrVal= szProperty;
+ DISPPARAMS disp = { pvars, NULL, 1, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0x70, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ delete[] pvars;
+ }
+ void Fire_BeforeNavigate2(
+ IDispatch * pDisp,
+ VARIANT * URL,
+ VARIANT * Flags,
+ VARIANT * TargetFrameName,
+ VARIANT * PostData,
+ VARIANT * Headers,
+ VARIANT_BOOL * Cancel)
+ {
+ VARIANTARG* pvars = new VARIANTARG[7];
+ for (int i = 0; i < 7; i++)
+ VariantInit(&pvars[i]);
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ pvars[6].vt = VT_DISPATCH;
+ pvars[6].pdispVal= pDisp;
+ pvars[5].vt = VT_VARIANT | VT_BYREF;
+ pvars[5].byref= URL;
+ pvars[4].vt = VT_VARIANT | VT_BYREF;
+ pvars[4].byref= Flags;
+ pvars[3].vt = VT_VARIANT | VT_BYREF;
+ pvars[3].byref= TargetFrameName;
+ pvars[2].vt = VT_VARIANT | VT_BYREF;
+ pvars[2].byref= PostData;
+ pvars[1].vt = VT_VARIANT | VT_BYREF;
+ pvars[1].byref= Headers;
+ pvars[0].vt = VT_BOOL | VT_BYREF;
+ pvars[0].byref= Cancel;
+ DISPPARAMS disp = { pvars, NULL, 7, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0xfa, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ delete[] pvars;
+ }
+ void Fire_NewWindow2(
+ IDispatch * * ppDisp,
+ VARIANT_BOOL * Cancel)
+ {
+ VARIANTARG* pvars = new VARIANTARG[2];
+ for (int i = 0; i < 2; i++)
+ VariantInit(&pvars[i]);
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ pvars[1].vt = VT_DISPATCH | VT_BYREF;
+ pvars[1].byref= ppDisp;
+ pvars[0].vt = VT_BOOL | VT_BYREF;
+ pvars[0].byref= Cancel;
+ DISPPARAMS disp = { pvars, NULL, 2, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0xfb, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ delete[] pvars;
+ }
+ void Fire_NavigateComplete2(
+ IDispatch * pDisp,
+ VARIANT * URL)
+ {
+ VARIANTARG* pvars = new VARIANTARG[2];
+ for (int i = 0; i < 2; i++)
+ VariantInit(&pvars[i]);
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ pvars[1].vt = VT_DISPATCH;
+ pvars[1].pdispVal= pDisp;
+ pvars[0].vt = VT_VARIANT | VT_BYREF;
+ pvars[0].byref= URL;
+ DISPPARAMS disp = { pvars, NULL, 2, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0xfc, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ delete[] pvars;
+ }
+ void Fire_DocumentComplete(
+ IDispatch * pDisp,
+ VARIANT * URL)
+ {
+ VARIANTARG* pvars = new VARIANTARG[2];
+ for (int i = 0; i < 2; i++)
+ VariantInit(&pvars[i]);
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ pvars[1].vt = VT_DISPATCH;
+ pvars[1].pdispVal= pDisp;
+ pvars[0].vt = VT_VARIANT | VT_BYREF;
+ pvars[0].byref= URL;
+ DISPPARAMS disp = { pvars, NULL, 2, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0x103, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ delete[] pvars;
+ }
+ void Fire_OnQuit()
+ {
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ DISPPARAMS disp = { NULL, NULL, 0, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0xfd, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ }
+ void Fire_OnVisible(
+ VARIANT_BOOL Visible)
+ {
+ VARIANTARG* pvars = new VARIANTARG[1];
+ for (int i = 0; i < 1; i++)
+ VariantInit(&pvars[i]);
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ pvars[0].vt = VT_BOOL;
+ pvars[0].boolVal= Visible;
+ DISPPARAMS disp = { pvars, NULL, 1, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0xfe, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ delete[] pvars;
+ }
+ void Fire_OnToolBar(
+ VARIANT_BOOL ToolBar)
+ {
+ VARIANTARG* pvars = new VARIANTARG[1];
+ for (int i = 0; i < 1; i++)
+ VariantInit(&pvars[i]);
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ pvars[0].vt = VT_BOOL;
+ pvars[0].boolVal= ToolBar;
+ DISPPARAMS disp = { pvars, NULL, 1, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0xff, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ delete[] pvars;
+ }
+ void Fire_OnMenuBar(
+ VARIANT_BOOL MenuBar)
+ {
+ VARIANTARG* pvars = new VARIANTARG[1];
+ for (int i = 0; i < 1; i++)
+ VariantInit(&pvars[i]);
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ pvars[0].vt = VT_BOOL;
+ pvars[0].boolVal= MenuBar;
+ DISPPARAMS disp = { pvars, NULL, 1, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0x100, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ delete[] pvars;
+ }
+ void Fire_OnStatusBar(
+ VARIANT_BOOL StatusBar)
+ {
+ VARIANTARG* pvars = new VARIANTARG[1];
+ for (int i = 0; i < 1; i++)
+ VariantInit(&pvars[i]);
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ pvars[0].vt = VT_BOOL;
+ pvars[0].boolVal= StatusBar;
+ DISPPARAMS disp = { pvars, NULL, 1, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0x101, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ delete[] pvars;
+ }
+ void Fire_OnFullScreen(
+ VARIANT_BOOL FullScreen)
+ {
+ VARIANTARG* pvars = new VARIANTARG[1];
+ for (int i = 0; i < 1; i++)
+ VariantInit(&pvars[i]);
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ pvars[0].vt = VT_BOOL;
+ pvars[0].boolVal= FullScreen;
+ DISPPARAMS disp = { pvars, NULL, 1, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0x102, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ delete[] pvars;
+ }
+ void Fire_OnTheaterMode(
+ VARIANT_BOOL TheaterMode)
+ {
+ VARIANTARG* pvars = new VARIANTARG[1];
+ for (int i = 0; i < 1; i++)
+ VariantInit(&pvars[i]);
+ T* pT = (T*)this;
+ pT->Lock();
+ IUnknown** pp = m_vec.begin();
+ while (pp < m_vec.end())
+ {
+ if (*pp != NULL)
+ {
+ pvars[0].vt = VT_BOOL;
+ pvars[0].boolVal= TheaterMode;
+ DISPPARAMS disp = { pvars, NULL, 1, 0 };
+ IDispatch* pDispatch = reinterpret_cast<IDispatch*>(*pp);
+ pDispatch->Invoke(0x104, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
+ }
+ pp++;
+ }
+ pT->Unlock();
+ delete[] pvars;
+ }
+
+};
+
+
+#endif
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/embedding/browser/activex/src/common/ControlEventSink.cpp
@@ -0,0 +1,216 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Adam Lock <adamlock@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "StdAfx.h"
+
+#include "ControlEventSink.h"
+
+CControlEventSink::CControlEventSink() :
+ m_dwEventCookie(0),
+ m_EventIID(GUID_NULL)
+{
+}
+
+CControlEventSink::~CControlEventSink()
+{
+ UnsubscribeFromEvents();
+}
+
+BOOL
+CControlEventSink::GetEventSinkIID(IUnknown *pControl, IID &iid, ITypeInfo **typeInfo)
+{
+ iid = GUID_NULL;
+ if (!pControl)
+ {
+ return E_INVALIDARG;
+ }
+
+ // IProvideClassInfo2 way is easiest
+// CComQIPtr<IProvideClassInfo2> classInfo2 = pControl;
+// if (classInfo2)
+// {
+// classInfo2->GetGUID(GUIDKIND_DEFAULT_SOURCE_DISP_IID, &iid);
+// if (!::IsEqualIID(iid, GUID_NULL))
+// {
+// return TRUE;
+// }
+// }
+
+ // Yuck, the hard way
+ CComQIPtr<IProvideClassInfo> classInfo = pControl;
+ if (!classInfo)
+ {
+ return FALSE;
+ }
+
+ // Search the class type information for the default source interface
+ // which is the outgoing event sink.
+
+ CComPtr<ITypeInfo> classTypeInfo;
+ classInfo->GetClassInfo(&classTypeInfo);
+ if (!classTypeInfo)
+ {
+ return FALSE;
+ }
+ TYPEATTR *classAttr = NULL;
+ if (FAILED(classTypeInfo->GetTypeAttr(&classAttr)))
+ {
+ return FALSE;
+ }
+ INT implFlags = 0;
+ for (UINT i = 0; i < classAttr->cImplTypes; i++)
+ {
+ // Search for the interface with the [default, source] attr
+ if (SUCCEEDED(classTypeInfo->GetImplTypeFlags(i, &implFlags)) &&
+ implFlags == (IMPLTYPEFLAG_FDEFAULT | IMPLTYPEFLAG_FSOURCE))
+ {
+ CComPtr<ITypeInfo> eventSinkTypeInfo;
+ HREFTYPE hRefType;
+ if (SUCCEEDED(classTypeInfo->GetRefTypeOfImplType(i, &hRefType)) &&
+ SUCCEEDED(classTypeInfo->GetRefTypeInfo(hRefType, &eventSinkTypeInfo)))
+ {
+ TYPEATTR *eventSinkAttr = NULL;
+ if (SUCCEEDED(eventSinkTypeInfo->GetTypeAttr(&eventSinkAttr)))
+ {
+ iid = eventSinkAttr->guid;
+ if (typeInfo)
+ {
+ *typeInfo = eventSinkTypeInfo.p;
+ (*typeInfo)->AddRef();
+ }
+ eventSinkTypeInfo->ReleaseTypeAttr(eventSinkAttr);
+ }
+ }
+ break;
+ }
+ }
+ classTypeInfo->ReleaseTypeAttr(classAttr);
+
+ return (!::IsEqualIID(iid, GUID_NULL));
+}
+
+void CControlEventSink::UnsubscribeFromEvents()
+{
+ if (m_spEventCP)
+ {
+ // Unsubscribe and reset
+ m_spEventCP->Unadvise(m_dwEventCookie);
+ m_dwEventCookie = 0;
+ m_spEventCP.Release();
+ }
+}
+
+HRESULT CControlEventSink::SubscribeToEvents(IUnknown *pControl)
+{
+ if (!pControl)
+ {
+ return E_INVALIDARG;
+ }
+
+ // Throw away any existing connections
+ UnsubscribeFromEvents();
+
+ // Grab the outgoing event sink IID which will be used to subscribe
+ // to events via the connection point container.
+
+ IID iidEventSink;
+ CComPtr<ITypeInfo> typeInfo;
+ if (!GetEventSinkIID(pControl, iidEventSink, &typeInfo))
+ {
+ return E_FAIL;
+ }
+
+ // Get the connection point
+ CComQIPtr<IConnectionPointContainer> ccp = pControl;
+ CComPtr<IConnectionPoint> cp;
+ if (!ccp)
+ {
+ return E_FAIL;
+ }
+
+ // Custom IID
+ m_EventIID = iidEventSink;
+ DWORD dwCookie = 0;
+ if (!ccp ||
+ FAILED(ccp->FindConnectionPoint(m_EventIID, &cp)) ||
+ FAILED(cp->Advise(this, &dwCookie)))
+ {
+ return E_FAIL;
+ }
+
+ m_spEventCP = cp;
+ m_dwEventCookie = dwCookie;
+ m_spEventSinkTypeInfo = typeInfo;
+ return S_OK;
+}
+
+HRESULT
+CControlEventSink::InternalInvoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
+{
+ // Override me!
+ return E_NOTIMPL;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// IDispatch implementation
+
+
+HRESULT STDMETHODCALLTYPE CControlEventSink::GetTypeInfoCount(/* [out] */ UINT __RPC_FAR *pctinfo)
+{
+ return E_NOTIMPL;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlEventSink::GetTypeInfo(/* [in] */ UINT iTInfo, /* [in] */ LCID lcid, /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo)
+{
+ return E_NOTIMPL;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlEventSink::GetIDsOfNames(/* [in] */ REFIID riid, /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames, /* [in] */ UINT cNames, /* [in] */ LCID lcid, /* [size_is][out] */ DISPID __RPC_FAR *rgDispId)
+{
+ return E_NOTIMPL;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlEventSink::Invoke(/* [in] */ DISPID dispIdMember, /* [in] */ REFIID riid, /* [in] */ LCID lcid, /* [in] */ WORD wFlags, /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams, /* [out] */ VARIANT __RPC_FAR *pVarResult, /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo, /* [out] */ UINT __RPC_FAR *puArgErr)
+{
+ return InternalInvoke(dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
+}
+
+
new file mode 100644
--- /dev/null
+++ b/embedding/browser/activex/src/common/ControlEventSink.h
@@ -0,0 +1,92 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Adam Lock <adamlock@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef CONTROLEVENTSINK_H
+#define CONTROLEVENTSINK_H
+
+// This class listens for events from the specified control
+
+class CControlEventSink :
+ public CComObjectRootEx<CComSingleThreadModel>,
+ public IDispatch
+{
+public:
+ CControlEventSink();
+
+ // Current event connection point
+ CComPtr<IConnectionPoint> m_spEventCP;
+ CComPtr<ITypeInfo> m_spEventSinkTypeInfo;
+ DWORD m_dwEventCookie;
+ IID m_EventIID;
+
+protected:
+ virtual ~CControlEventSink();
+
+ static HRESULT WINAPI SinkQI(void* pv, REFIID riid, LPVOID* ppv, DWORD_PTR dw)
+ {
+ CControlEventSink *pThis = (CControlEventSink *) pv;
+ if (!IsEqualIID(pThis->m_EventIID, GUID_NULL) &&
+ IsEqualIID(pThis->m_EventIID, riid))
+ {
+ return pThis->QueryInterface(__uuidof(IDispatch), ppv);
+ }
+ return E_NOINTERFACE;
+ }
+
+public:
+
+BEGIN_COM_MAP(CControlEventSink)
+ COM_INTERFACE_ENTRY(IDispatch)
+ COM_INTERFACE_ENTRY_FUNC_BLIND(0, SinkQI)
+END_COM_MAP()
+
+ virtual HRESULT SubscribeToEvents(IUnknown *pControl);
+ virtual void UnsubscribeFromEvents();
+ virtual BOOL GetEventSinkIID(IUnknown *pControl, IID &iid, ITypeInfo **typeInfo);
+ virtual HRESULT InternalInvoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr);
+
+// IDispatch
+ virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(/* [out] */ UINT __RPC_FAR *pctinfo);
+ virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(/* [in] */ UINT iTInfo, /* [in] */ LCID lcid, /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
+ virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(/* [in] */ REFIID riid, /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames, /* [in] */ UINT cNames, /* [in] */ LCID lcid, /* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
+ virtual /* [local] */ HRESULT STDMETHODCALLTYPE Invoke(/* [in] */ DISPID dispIdMember, /* [in] */ REFIID riid, /* [in] */ LCID lcid, /* [in] */ WORD wFlags, /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams, /* [out] */ VARIANT __RPC_FAR *pVarResult, /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo, /* [out] */ UINT __RPC_FAR *puArgErr);
+};
+
+typedef CComObject<CControlEventSink> CControlEventSinkInstance;
+
+#endif
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/embedding/browser/activex/src/common/ControlSite.cpp
@@ -0,0 +1,1421 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Adam Lock <adamlock@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "StdAfx.h"
+
+#include <Objsafe.h>
+
+#include "ControlSite.h"
+#include "PropertyBag.h"
+#include "ControlSiteIPFrame.h"
+
+class CDefaultControlSiteSecurityPolicy : public CControlSiteSecurityPolicy
+{
+ // Test if the specified class id implements the specified category
+ BOOL ClassImplementsCategory(const CLSID & clsid, const CATID &catid, BOOL &bClassExists);
+public:
+ // Test if the class is safe to host
+ virtual BOOL IsClassSafeToHost(const CLSID & clsid);
+ // Test if the specified class is marked safe for scripting
+ virtual BOOL IsClassMarkedSafeForScripting(const CLSID & clsid, BOOL &bClassExists);
+ // Test if the instantiated object is safe for scripting on the specified interface
+ virtual BOOL IsObjectSafeForScripting(IUnknown *pObject, const IID &iid);
+};
+
+BOOL
+CDefaultControlSiteSecurityPolicy::ClassImplementsCategory(const CLSID &clsid, const CATID &catid, BOOL &bClassExists)
+{
+ bClassExists = FALSE;
+
+ // Test if there is a CLSID entry. If there isn't then obviously
+ // the object doesn't exist and therefore doesn't implement any category.
+ // In this situation, the function returns REGDB_E_CLASSNOTREG.
+
+ CRegKey key;
+ if (key.Open(HKEY_CLASSES_ROOT, _T("CLSID"), KEY_READ) != ERROR_SUCCESS)
+ {
+ // Must fail if we can't even open this!
+ return FALSE;
+ }
+ LPOLESTR szCLSID = NULL;
+ if (FAILED(StringFromCLSID(clsid, &szCLSID)))
+ {
+ return FALSE;
+ }
+ USES_CONVERSION;
+ CRegKey keyCLSID;
+ LONG lResult = keyCLSID.Open(key, W2CT(szCLSID), KEY_READ);
+ CoTaskMemFree(szCLSID);
+ if (lResult != ERROR_SUCCESS)
+ {
+ // Class doesn't exist
+ return FALSE;
+ }
+ keyCLSID.Close();
+
+ // CLSID exists, so try checking what categories it implements
+ bClassExists = TRUE;
+ CComQIPtr<ICatInformation> spCatInfo;
+ HRESULT hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_ICatInformation, (LPVOID*) &spCatInfo);
+ if (spCatInfo == NULL)
+ {
+ // Must fail if we can't open the category manager
+ return FALSE;
+ }
+
+ // See what categories the class implements
+ CComQIPtr<IEnumCATID> spEnumCATID;
+ if (FAILED(spCatInfo->EnumImplCategoriesOfClass(clsid, &spEnumCATID)))
+ {
+ // Can't enumerate classes in category so fail
+ return FALSE;
+ }
+
+ // Search for matching categories
+ BOOL bFound = FALSE;
+ CATID catidNext = GUID_NULL;
+ while (spEnumCATID->Next(1, &catidNext, NULL) == S_OK)
+ {
+ if (::IsEqualCATID(catid, catidNext))
+ {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+// Test if the class is safe to host
+BOOL CDefaultControlSiteSecurityPolicy::IsClassSafeToHost(const CLSID & clsid)
+{
+ return TRUE;
+}
+
+// Test if the specified class is marked safe for scripting
+BOOL CDefaultControlSiteSecurityPolicy::IsClassMarkedSafeForScripting(const CLSID & clsid, BOOL &bClassExists)
+{
+ // Test the category the object belongs to
+ return ClassImplementsCategory(clsid, CATID_SafeForScripting, bClassExists);
+}
+
+// Test if the instantiated object is safe for scripting on the specified interface
+BOOL CDefaultControlSiteSecurityPolicy::IsObjectSafeForScripting(IUnknown *pObject, const IID &iid)
+{
+ if (!pObject) {
+ return FALSE;
+ }
+ // Ask the control if its safe for scripting
+ CComQIPtr<IObjectSafety> spObjectSafety = pObject;
+ if (!spObjectSafety)
+ {
+ return FALSE;
+ }
+
+ DWORD dwSupported = 0; // Supported options (mask)
+ DWORD dwEnabled = 0; // Enabled options
+
+ // Assume scripting via IDispatch
+ if (FAILED(spObjectSafety->GetInterfaceSafetyOptions(
+ iid, &dwSupported, &dwEnabled)))
+ {
+ // Interface is not safe or failure.
+ return FALSE;
+ }
+
+ // Test if safe for scripting
+ if (!(dwEnabled & dwSupported) & INTERFACESAFE_FOR_UNTRUSTED_CALLER)
+ {
+ // Object says it is not set to be safe, but supports unsafe calling,
+ // try enabling it and asking again.
+
+ if(!(dwSupported & INTERFACESAFE_FOR_UNTRUSTED_CALLER) ||
+ FAILED(spObjectSafety->SetInterfaceSafetyOptions(
+ iid, INTERFACESAFE_FOR_UNTRUSTED_CALLER, INTERFACESAFE_FOR_UNTRUSTED_CALLER)) ||
+ FAILED(spObjectSafety->GetInterfaceSafetyOptions(
+ iid, &dwSupported, &dwEnabled)) ||
+ !(dwEnabled & dwSupported) & INTERFACESAFE_FOR_UNTRUSTED_CALLER)
+ {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+// Constructor
+CControlSite::CControlSite()
+{
+ TRACE_METHOD(CControlSite::CControlSite);
+
+ m_hWndParent = NULL;
+ m_CLSID = CLSID_NULL;
+ m_bSetClientSiteFirst = FALSE;
+ m_bVisibleAtRuntime = TRUE;
+ memset(&m_rcObjectPos, 0, sizeof(m_rcObjectPos));
+
+ m_bInPlaceActive = FALSE;
+ m_bUIActive = FALSE;
+ m_bInPlaceLocked = FALSE;
+ m_bWindowless = FALSE;
+ m_bSupportWindowlessActivation = TRUE;
+ m_bSafeForScriptingObjectsOnly = FALSE;
+ m_pSecurityPolicy = GetDefaultControlSecurityPolicy();
+
+ // Initialise ambient properties
+ m_nAmbientLocale = 0;
+ m_clrAmbientForeColor = ::GetSysColor(COLOR_WINDOWTEXT);
+ m_clrAmbientBackColor = ::GetSysColor(COLOR_WINDOW);
+ m_bAmbientUserMode = true;
+ m_bAmbientShowHatching = true;
+ m_bAmbientShowGrabHandles = true;
+ m_bAmbientAppearance = true; // 3d
+
+ // Windowless variables
+ m_hDCBuffer = NULL;
+ m_hRgnBuffer = NULL;
+ m_hBMBufferOld = NULL;
+ m_hBMBuffer = NULL;
+}
+
+
+// Destructor
+CControlSite::~CControlSite()
+{
+ TRACE_METHOD(CControlSite::~CControlSite);
+ Detach();
+}
+
+// Create the specified control, optionally providing properties to initialise
+// it with and a name.
+HRESULT CControlSite::Create(REFCLSID clsid, PropertyList &pl,
+ LPCWSTR szCodebase, IBindCtx *pBindContext)
+{
+ TRACE_METHOD(CControlSite::Create);
+
+ m_CLSID = clsid;
+ m_ParameterList = pl;
+
+ // See if security policy will allow the control to be hosted
+ if (m_pSecurityPolicy && !m_pSecurityPolicy->IsClassSafeToHost(clsid))
+ {
+ return E_FAIL;
+ }
+
+ // See if object is script safe
+ BOOL checkForObjectSafety = FALSE;
+ if (m_pSecurityPolicy && m_bSafeForScriptingObjectsOnly)
+ {
+ BOOL bClassExists = FALSE;
+ BOOL bIsSafe = m_pSecurityPolicy->IsClassMarkedSafeForScripting(clsid, bClassExists);
+ if (!bClassExists && szCodebase)
+ {
+ // Class doesn't exist, so allow code below to fetch it
+ }
+ else if (!bIsSafe)
+ {
+ // The class is not flagged as safe for scripting, so
+ // we'll have to create it to ask it if its safe.
+ checkForObjectSafety = TRUE;
+ }
+ }
+
+ // Create the object
+ CComPtr<IUnknown> spObject;
+ HRESULT hr = CoCreateInstance(clsid, NULL, CLSCTX_ALL, IID_IUnknown, (void **) &spObject);
+ if (SUCCEEDED(hr) && checkForObjectSafety)
+ {
+ // Assume scripting via IDispatch
+ if (!m_pSecurityPolicy->IsObjectSafeForScripting(spObject, __uuidof(IDispatch)))
+ {
+ return E_FAIL;
+ }
+ // Drop through, success!
+ }
+
+ // Do we need to download the control?
+ if (FAILED(hr) && szCodebase)
+ {
+ wchar_t *szURL = NULL;
+
+ // Test if the code base ends in #version=a,b,c,d
+ DWORD dwFileVersionMS = 0xffffffff;
+ DWORD dwFileVersionLS = 0xffffffff;
+ const wchar_t *szHash = wcsrchr(szCodebase, wchar_t('#'));
+ if (szHash)
+ {
+ if (wcsnicmp(szHash, L"#version=", 9) == 0)
+ {
+ int a, b, c, d;
+ if (swscanf(szHash + 9, L"%d,%d,%d,%d", &a, &b, &c, &d) == 4)
+ {
+ dwFileVersionMS = MAKELONG(b,a);
+ dwFileVersionLS = MAKELONG(d,c);
+ }
+ }
+ szURL = _wcsdup(szCodebase);
+ // Terminate at the hash mark
+ if (szURL)
+ szURL[szHash - szCodebase] = wchar_t('\0');
+ }
+ else
+ {
+ szURL = _wcsdup(szCodebase);
+ }
+ if (!szURL)
+ return E_OUTOFMEMORY;
+
+ CComPtr<IBindCtx> spBindContext;
+ CComPtr<IBindStatusCallback> spBindStatusCallback;
+ CComPtr<IBindStatusCallback> spOldBSC;
+
+ // Create our own bind context or use the one provided?
+ BOOL useInternalBSC = FALSE;
+ if (!pBindContext)
+ {
+ useInternalBSC = TRUE;
+ hr = CreateBindCtx(0, &spBindContext);
+ if (FAILED(hr))
+ {
+ free(szURL);
+ return hr;
+ }
+ spBindStatusCallback = dynamic_cast<IBindStatusCallback *>(this);
+ hr = RegisterBindStatusCallback(spBindContext, spBindStatusCallback, &spOldBSC, 0);
+ if (FAILED(hr))
+ {
+ free(szURL);
+ return hr;
+ }
+ }
+ else
+ {
+ spBindContext = pBindContext;
+ }
+
+ hr = CoGetClassObjectFromURL(clsid, szURL, dwFileVersionMS, dwFileVersionLS,
+ NULL, spBindContext, CLSCTX_ALL, NULL, IID_IUnknown, (void **) &m_spObject);
+
+ free(szURL);
+
+ // Handle the internal binding synchronously so the object exists
+ // or an error code is available when the method returns.
+ if (useInternalBSC)
+ {
+ if (MK_S_ASYNCHRONOUS == hr)
+ {
+ m_bBindingInProgress = TRUE;
+ m_hrBindResult = E_FAIL;
+
+ // Spin around waiting for binding to complete
+ HANDLE hFakeEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
+ while (m_bBindingInProgress)
+ {
+ MSG msg;
+ // Process pending messages
+ while (::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
+ {
+ if (!::GetMessage(&msg, NULL, 0, 0))
+ {
+ m_bBindingInProgress = FALSE;
+ break;
+ }
+ ::TranslateMessage(&msg);
+ ::DispatchMessage(&msg);
+ }
+ if (!m_bBindingInProgress)
+ break;
+ // Sleep for a bit or the next msg to appear
+ ::MsgWaitForMultipleObjects(1, &hFakeEvent, FALSE, 500, QS_ALLEVENTS);
+ }
+ ::CloseHandle(hFakeEvent);
+
+ // Set the result
+ hr = m_hrBindResult;
+ }
+
+ // Destroy the bind status callback & context
+ if (spBindStatusCallback)
+ {
+ RevokeBindStatusCallback(spBindContext, spBindStatusCallback);
+ spBindContext.Release();
+ }
+ }
+ }
+
+ if (spObject)
+ m_spObject = spObject;
+
+ return hr;
+}
+
+
+// Attach the created control to a window and activate it
+HRESULT CControlSite::Attach(HWND hwndParent, const RECT &rcPos, IUnknown *pInitStream)
+{
+ TRACE_METHOD(CControlSite::Attach);
+
+ if (hwndParent == NULL)
+ {
+ NS_ERROR("No parent hwnd");
+ return E_INVALIDARG;
+ }
+
+ m_hWndParent = hwndParent;
+ m_rcObjectPos = rcPos;
+
+ // Object must have been created
+ if (m_spObject == NULL)
+ {
+ return E_UNEXPECTED;
+ }
+
+ m_spIViewObject = m_spObject;
+ m_spIOleObject = m_spObject;
+
+ if (m_spIOleObject == NULL)
+ {
+ return E_FAIL;
+ }
+
+ DWORD dwMiscStatus;
+ m_spIOleObject->GetMiscStatus(DVASPECT_CONTENT, &dwMiscStatus);
+
+ if (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)
+ {
+ m_bSetClientSiteFirst = TRUE;
+ }
+ if (dwMiscStatus & OLEMISC_INVISIBLEATRUNTIME)
+ {
+ m_bVisibleAtRuntime = FALSE;
+ }
+
+ // Some objects like to have the client site as the first thing
+ // to be initialised (for ambient properties and so forth)
+ if (m_bSetClientSiteFirst)
+ {
+ m_spIOleObject->SetClientSite(this);
+ }
+
+ // If there is a parameter list for the object and no init stream then
+ // create one here.
+ CPropertyBagInstance *pPropertyBag = NULL;
+ if (pInitStream == NULL && m_ParameterList.GetSize() > 0)
+ {
+ CPropertyBagInstance::CreateInstance(&pPropertyBag);
+ pPropertyBag->AddRef();
+ for (unsigned long i = 0; i < m_ParameterList.GetSize(); i++)
+ {
+ pPropertyBag->Write(m_ParameterList.GetNameOf(i),
+ const_cast<VARIANT *>(m_ParameterList.GetValueOf(i)));
+ }
+ pInitStream = (IPersistPropertyBag *) pPropertyBag;
+ }
+
+ // Initialise the control from store if one is provided
+ if (pInitStream)
+ {
+ CComQIPtr<IPropertyBag, &IID_IPropertyBag> spPropertyBag = pInitStream;
+ CComQIPtr<IStream, &IID_IStream> spStream = pInitStream;
+ CComQIPtr<IPersistStream, &IID_IPersistStream> spIPersistStream = m_spIOleObject;
+ CComQIPtr<IPersistPropertyBag, &IID_IPersistPropertyBag> spIPersistPropertyBag = m_spIOleObject;
+
+ if (spIPersistPropertyBag && spPropertyBag)
+ {
+ spIPersistPropertyBag->Load(spPropertyBag, NULL);
+ }
+ else if (spIPersistStream && spStream)
+ {
+ spIPersistStream->Load(spStream);
+ }
+ }
+ else
+ {
+ // Initialise the object if possible
+ CComQIPtr<IPersistStreamInit, &IID_IPersistStreamInit> spIPersistStreamInit = m_spIOleObject;
+ if (spIPersistStreamInit)
+ {
+ spIPersistStreamInit->InitNew();
+ }
+ }
+
+ m_spIOleInPlaceObject = m_spObject;
+ m_spIOleInPlaceObjectWindowless = m_spObject;
+
+ // In-place activate the object
+ if (m_bVisibleAtRuntime)
+ {
+ DoVerb(OLEIVERB_INPLACEACTIVATE);
+ }
+
+ m_spIOleInPlaceObject->SetObjectRects(&m_rcObjectPos, &m_rcObjectPos);
+
+ // For those objects which haven't had their client site set yet,
+ // it's done here.
+ if (!m_bSetClientSiteFirst)
+ {
+ m_spIOleObject->SetClientSite(this);
+ }
+
+ return S_OK;
+}
+
+
+// Unhook the control from the window and throw it all away
+HRESULT CControlSite::Detach()
+{
+ TRACE_METHOD(CControlSite::Detach);
+
+ if (m_spIOleInPlaceObjectWindowless)
+ {
+ m_spIOleInPlaceObjectWindowless.Release();
+ }
+
+ if (m_spIOleInPlaceObject)
+ {
+ m_spIOleInPlaceObject->InPlaceDeactivate();
+ m_spIOleInPlaceObject.Release();
+ }
+
+ if (m_spIOleObject)
+ {
+ m_spIOleObject->Close(OLECLOSE_NOSAVE);
+ m_spIOleObject->SetClientSite(NULL);
+ m_spIOleObject.Release();
+ }
+
+ m_spIViewObject.Release();
+ m_spObject.Release();
+
+ return S_OK;
+}
+
+
+// Return the IUnknown of the contained control
+HRESULT CControlSite::GetControlUnknown(IUnknown **ppObject)
+{
+ *ppObject = NULL;
+ if (m_spObject)
+ {
+ m_spObject->QueryInterface(IID_IUnknown, (void **) ppObject);
+ }
+ return S_OK;
+}
+
+
+// Subscribe to an event sink on the control
+HRESULT CControlSite::Advise(IUnknown *pIUnkSink, const IID &iid, DWORD *pdwCookie)
+{
+ if (m_spObject == NULL)
+ {
+ return E_UNEXPECTED;
+ }
+
+ if (pIUnkSink == NULL || pdwCookie == NULL)
+ {
+ return E_INVALIDARG;
+ }
+
+ return AtlAdvise(m_spObject, pIUnkSink, iid, pdwCookie);
+}
+
+
+// Unsubscribe event sink from the control
+HRESULT CControlSite::Unadvise(const IID &iid, DWORD dwCookie)
+{
+ if (m_spObject == NULL)
+ {
+ return E_UNEXPECTED;
+ }
+
+ return AtlUnadvise(m_spObject, iid, dwCookie);
+}
+
+
+// Draw the control
+HRESULT CControlSite::Draw(HDC hdc)
+{
+ TRACE_METHOD(CControlSite::Draw);
+
+ // Draw only when control is windowless or deactivated
+ if (m_spIViewObject)
+ {
+ if (m_bWindowless || !m_bInPlaceActive)
+ {
+ RECTL *prcBounds = (m_bWindowless) ? NULL : (RECTL *) &m_rcObjectPos;
+ m_spIViewObject->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdc, prcBounds, NULL, NULL, 0);
+ }
+ }
+ else
+ {
+ // Draw something to indicate no control is there
+ HBRUSH hbr = CreateSolidBrush(RGB(200,200,200));
+ FillRect(hdc, &m_rcObjectPos, hbr);
+ DeleteObject(hbr);
+ }
+
+ return S_OK;
+}
+
+
+// Execute the specified verb
+HRESULT CControlSite::DoVerb(LONG nVerb, LPMSG lpMsg)
+{
+ TRACE_METHOD(CControlSite::DoVerb);
+
+ if (m_spIOleObject == NULL)
+ {
+ return E_FAIL;
+ }
+
+ return m_spIOleObject->DoVerb(nVerb, lpMsg, this, 0, m_hWndParent, &m_rcObjectPos);
+}
+
+
+// Set the position on the control
+HRESULT CControlSite::SetPosition(const RECT &rcPos)
+{
+ TRACE_METHOD(CControlSite::SetPosition);
+ m_rcObjectPos = rcPos;
+ if (m_spIOleInPlaceObject)
+ {
+ m_spIOleInPlaceObject->SetObjectRects(&m_rcObjectPos, &m_rcObjectPos);
+ }
+ return S_OK;
+}
+
+
+void CControlSite::FireAmbientPropertyChange(DISPID id)
+{
+ if (m_spObject)
+ {
+ CComQIPtr<IOleControl> spControl = m_spObject;
+ if (spControl)
+ {
+ spControl->OnAmbientPropertyChange(id);
+ }
+ }
+}
+
+
+void CControlSite::SetAmbientUserMode(BOOL bUserMode)
+{
+ bool bNewMode = bUserMode ? true : false;
+ if (m_bAmbientUserMode != bNewMode)
+ {
+ m_bAmbientUserMode = bNewMode;
+ FireAmbientPropertyChange(DISPID_AMBIENT_USERMODE);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// CControlSiteSecurityPolicy implementation
+
+CControlSiteSecurityPolicy *CControlSite::GetDefaultControlSecurityPolicy()
+{
+ static CDefaultControlSiteSecurityPolicy defaultControlSecurityPolicy;
+ return &defaultControlSecurityPolicy;
+}
+
+// Test if the class is safe to host
+BOOL CControlSite::IsClassSafeToHost(const CLSID & clsid)
+{
+ if (m_pSecurityPolicy)
+ return m_pSecurityPolicy->IsClassSafeToHost(clsid);
+ return TRUE;
+}
+
+// Test if the specified class is marked safe for scripting
+BOOL CControlSite::IsClassMarkedSafeForScripting(const CLSID & clsid, BOOL &bClassExists)
+{
+ if (m_pSecurityPolicy)
+ return m_pSecurityPolicy->IsClassMarkedSafeForScripting(clsid, bClassExists);
+ return TRUE;
+}
+
+// Test if the instantiated object is safe for scripting on the specified interface
+BOOL CControlSite::IsObjectSafeForScripting(IUnknown *pObject, const IID &iid)
+{
+ if (m_pSecurityPolicy)
+ return m_pSecurityPolicy->IsObjectSafeForScripting(pObject, iid);
+ return TRUE;
+}
+
+BOOL CControlSite::IsObjectSafeForScripting(const IID &iid)
+{
+ return IsObjectSafeForScripting(m_spObject, iid);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// IServiceProvider implementation
+
+HRESULT STDMETHODCALLTYPE CControlSite::QueryService(REFGUID guidService, REFIID riid, void** ppv)
+{
+ if (m_spServiceProvider)
+ return m_spServiceProvider->QueryService(guidService, riid, ppv);
+ return E_NOINTERFACE;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// IDispatch implementation
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::GetTypeInfoCount(/* [out] */ UINT __RPC_FAR *pctinfo)
+{
+ return E_NOTIMPL;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::GetTypeInfo(/* [in] */ UINT iTInfo, /* [in] */ LCID lcid, /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo)
+{
+ return E_NOTIMPL;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::GetIDsOfNames(/* [in] */ REFIID riid, /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames, /* [in] */ UINT cNames, /* [in] */ LCID lcid, /* [size_is][out] */ DISPID __RPC_FAR *rgDispId)
+{
+ return E_NOTIMPL;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::Invoke(/* [in] */ DISPID dispIdMember, /* [in] */ REFIID riid, /* [in] */ LCID lcid, /* [in] */ WORD wFlags, /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams, /* [out] */ VARIANT __RPC_FAR *pVarResult, /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo, /* [out] */ UINT __RPC_FAR *puArgErr)
+{
+ if (wFlags & DISPATCH_PROPERTYGET)
+ {
+ CComVariant vResult;
+
+ switch (dispIdMember)
+ {
+ case DISPID_AMBIENT_APPEARANCE:
+ vResult = CComVariant(m_bAmbientAppearance);
+ break;
+
+ case DISPID_AMBIENT_FORECOLOR:
+ vResult = CComVariant((long) m_clrAmbientForeColor);
+ break;
+
+ case DISPID_AMBIENT_BACKCOLOR:
+ vResult = CComVariant((long) m_clrAmbientBackColor);
+ break;
+
+ case DISPID_AMBIENT_LOCALEID:
+ vResult = CComVariant((long) m_nAmbientLocale);
+ break;
+
+ case DISPID_AMBIENT_USERMODE:
+ vResult = CComVariant(m_bAmbientUserMode);
+ break;
+
+ case DISPID_AMBIENT_SHOWGRABHANDLES:
+ vResult = CComVariant(m_bAmbientShowGrabHandles);
+ break;
+
+ case DISPID_AMBIENT_SHOWHATCHING:
+ vResult = CComVariant(m_bAmbientShowHatching);
+ break;
+
+ default:
+ return DISP_E_MEMBERNOTFOUND;
+ }
+
+ VariantCopy(pVarResult, &vResult);
+ return S_OK;
+ }
+
+ return E_FAIL;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// IAdviseSink implementation
+
+
+void STDMETHODCALLTYPE CControlSite::OnDataChange(/* [unique][in] */ FORMATETC __RPC_FAR *pFormatetc, /* [unique][in] */ STGMEDIUM __RPC_FAR *pStgmed)
+{
+}
+
+
+void STDMETHODCALLTYPE CControlSite::OnViewChange(/* [in] */ DWORD dwAspect, /* [in] */ LONG lindex)
+{
+ // Redraw the control
+ InvalidateRect(NULL, FALSE);
+}
+
+
+void STDMETHODCALLTYPE CControlSite::OnRename(/* [in] */ IMoniker __RPC_FAR *pmk)
+{
+}
+
+
+void STDMETHODCALLTYPE CControlSite::OnSave(void)
+{
+}
+
+
+void STDMETHODCALLTYPE CControlSite::OnClose(void)
+{
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// IAdviseSink2 implementation
+
+
+void STDMETHODCALLTYPE CControlSite::OnLinkSrcChange(/* [unique][in] */ IMoniker __RPC_FAR *pmk)
+{
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// IAdviseSinkEx implementation
+
+
+void STDMETHODCALLTYPE CControlSite::OnViewStatusChange(/* [in] */ DWORD dwViewStatus)
+{
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// IOleWindow implementation
+
+HRESULT STDMETHODCALLTYPE CControlSite::GetWindow(/* [out] */ HWND __RPC_FAR *phwnd)
+{
+ *phwnd = m_hWndParent;
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::ContextSensitiveHelp(/* [in] */ BOOL fEnterMode)
+{
+ return S_OK;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// IOleClientSite implementation
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::SaveObject(void)
+{
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::GetMoniker(/* [in] */ DWORD dwAssign, /* [in] */ DWORD dwWhichMoniker, /* [out] */ IMoniker __RPC_FAR *__RPC_FAR *ppmk)
+{
+ return E_NOTIMPL;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::GetContainer(/* [out] */ IOleContainer __RPC_FAR *__RPC_FAR *ppContainer)
+{
+ if (!ppContainer) return E_INVALIDARG;
+ *ppContainer = m_spContainer;
+ if (*ppContainer)
+ {
+ (*ppContainer)->AddRef();
+ }
+ return (*ppContainer) ? S_OK : E_NOINTERFACE;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::ShowObject(void)
+{
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::OnShowWindow(/* [in] */ BOOL fShow)
+{
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::RequestNewObjectLayout(void)
+{
+ return E_NOTIMPL;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// IOleInPlaceSite implementation
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::CanInPlaceActivate(void)
+{
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::OnInPlaceActivate(void)
+{
+ m_bInPlaceActive = TRUE;
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::OnUIActivate(void)
+{
+ m_bUIActive = TRUE;
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::GetWindowContext(/* [out] */ IOleInPlaceFrame __RPC_FAR *__RPC_FAR *ppFrame, /* [out] */ IOleInPlaceUIWindow __RPC_FAR *__RPC_FAR *ppDoc, /* [out] */ LPRECT lprcPosRect, /* [out] */ LPRECT lprcClipRect, /* [out][in] */ LPOLEINPLACEFRAMEINFO lpFrameInfo)
+{
+ *lprcPosRect = m_rcObjectPos;
+ *lprcClipRect = m_rcObjectPos;
+
+ CControlSiteIPFrameInstance *pIPFrame = NULL;
+ CControlSiteIPFrameInstance::CreateInstance(&pIPFrame);
+ pIPFrame->AddRef();
+
+ *ppFrame = (IOleInPlaceFrame *) pIPFrame;
+ *ppDoc = NULL;
+
+ lpFrameInfo->fMDIApp = FALSE;
+ lpFrameInfo->hwndFrame = NULL;
+ lpFrameInfo->haccel = NULL;
+ lpFrameInfo->cAccelEntries = 0;
+
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::Scroll(/* [in] */ SIZE scrollExtant)
+{
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::OnUIDeactivate(/* [in] */ BOOL fUndoable)
+{
+ m_bUIActive = FALSE;
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::OnInPlaceDeactivate(void)
+{
+ m_bInPlaceActive = FALSE;
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::DiscardUndoState(void)
+{
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::DeactivateAndUndo(void)
+{
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::OnPosRectChange(/* [in] */ LPCRECT lprcPosRect)
+{
+ if (lprcPosRect == NULL)
+ {
+ return E_INVALIDARG;
+ }
+ SetPosition(m_rcObjectPos);
+ return S_OK;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// IOleInPlaceSiteEx implementation
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::OnInPlaceActivateEx(/* [out] */ BOOL __RPC_FAR *pfNoRedraw, /* [in] */ DWORD dwFlags)
+{
+ m_bInPlaceActive = TRUE;
+
+ if (pfNoRedraw)
+ {
+ *pfNoRedraw = FALSE;
+ }
+ if (dwFlags & ACTIVATE_WINDOWLESS)
+ {
+ if (!m_bSupportWindowlessActivation)
+ {
+ return E_INVALIDARG;
+ }
+ m_bWindowless = TRUE;
+ }
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::OnInPlaceDeactivateEx(/* [in] */ BOOL fNoRedraw)
+{
+ m_bInPlaceActive = FALSE;
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::RequestUIActivate(void)
+{
+ return S_FALSE;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// IOleInPlaceSiteWindowless implementation
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::CanWindowlessActivate(void)
+{
+ // Allow windowless activation?
+ return (m_bSupportWindowlessActivation) ? S_OK : S_FALSE;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::GetCapture(void)
+{
+ // TODO capture the mouse for the object
+ return S_FALSE;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::SetCapture(/* [in] */ BOOL fCapture)
+{
+ // TODO capture the mouse for the object
+ return S_FALSE;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::GetFocus(void)
+{
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::SetFocus(/* [in] */ BOOL fFocus)
+{
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::GetDC(/* [in] */ LPCRECT pRect, /* [in] */ DWORD grfFlags, /* [out] */ HDC __RPC_FAR *phDC)
+{
+ if (phDC == NULL)
+ {
+ return E_INVALIDARG;
+ }
+
+ // Can't do nested painting
+ if (m_hDCBuffer != NULL)
+ {
+ return E_UNEXPECTED;
+ }
+
+ m_rcBuffer = m_rcObjectPos;
+ if (pRect != NULL)
+ {
+ m_rcBuffer = *pRect;
+ }
+
+ m_hBMBuffer = NULL;
+ m_dwBufferFlags = grfFlags;
+
+ // See if the control wants a DC that is onscreen or offscreen
+ if (m_dwBufferFlags & OLEDC_OFFSCREEN)
+ {
+ m_hDCBuffer = CreateCompatibleDC(NULL);
+ if (m_hDCBuffer == NULL)
+ {
+ // Error
+ return E_OUTOFMEMORY;
+ }
+
+ long cx = m_rcBuffer.right - m_rcBuffer.left;
+ long cy = m_rcBuffer.bottom - m_rcBuffer.top;
+
+ m_hBMBuffer = CreateCompatibleBitmap(m_hDCBuffer, cx, cy);
+ m_hBMBufferOld = (HBITMAP) SelectObject(m_hDCBuffer, m_hBMBuffer);
+ SetViewportOrgEx(m_hDCBuffer, m_rcBuffer.left, m_rcBuffer.top, NULL);
+
+ // TODO When OLEDC_PAINTBKGND we must draw every site behind this one
+ }
+ else
+ {
+ // TODO When OLEDC_PAINTBKGND we must draw every site behind this one
+
+ // Get the window DC
+ m_hDCBuffer = GetWindowDC(m_hWndParent);
+ if (m_hDCBuffer == NULL)
+ {
+ // Error
+ return E_OUTOFMEMORY;
+ }
+
+ // Clip the control so it can't trash anywhere it isn't allowed to draw
+ if (!(m_dwBufferFlags & OLEDC_NODRAW))
+ {
+ m_hRgnBuffer = CreateRectRgnIndirect(&m_rcBuffer);
+
+ // TODO Clip out opaque areas of sites behind this one
+
+ SelectClipRgn(m_hDCBuffer, m_hRgnBuffer);
+ }
+ }
+
+ *phDC = m_hDCBuffer;
+
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::ReleaseDC(/* [in] */ HDC hDC)
+{
+ // Release the DC
+ if (hDC == NULL || hDC != m_hDCBuffer)
+ {
+ return E_INVALIDARG;
+ }
+
+ // Test if the DC was offscreen or onscreen
+ if ((m_dwBufferFlags & OLEDC_OFFSCREEN) &&
+ !(m_dwBufferFlags & OLEDC_NODRAW))
+ {
+ // BitBlt the buffer into the control's object
+ SetViewportOrgEx(m_hDCBuffer, 0, 0, NULL);
+ HDC hdc = GetWindowDC(m_hWndParent);
+
+ long cx = m_rcBuffer.right - m_rcBuffer.left;
+ long cy = m_rcBuffer.bottom - m_rcBuffer.top;
+
+ BitBlt(hdc, m_rcBuffer.left, m_rcBuffer.top, cx, cy, m_hDCBuffer, 0, 0, SRCCOPY);
+
+ ::ReleaseDC(m_hWndParent, hdc);
+ }
+ else
+ {
+ // TODO If OLEDC_PAINTBKGND is set draw the DVASPECT_CONTENT of every object above this one
+ }
+
+ // Clean up settings ready for next drawing
+ if (m_hRgnBuffer)
+ {
+ SelectClipRgn(m_hDCBuffer, NULL);
+ DeleteObject(m_hRgnBuffer);
+ m_hRgnBuffer = NULL;
+ }
+
+ SelectObject(m_hDCBuffer, m_hBMBufferOld);
+ if (m_hBMBuffer)
+ {
+ DeleteObject(m_hBMBuffer);
+ m_hBMBuffer = NULL;
+ }
+
+ // Delete the DC
+ if (m_dwBufferFlags & OLEDC_OFFSCREEN)
+ {
+ ::DeleteDC(m_hDCBuffer);
+ }
+ else
+ {
+ ::ReleaseDC(m_hWndParent, m_hDCBuffer);
+ }
+ m_hDCBuffer = NULL;
+
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::InvalidateRect(/* [in] */ LPCRECT pRect, /* [in] */ BOOL fErase)
+{
+ // Clip the rectangle against the object's size and invalidate it
+ RECT rcI = { 0, 0, 0, 0 };
+ if (pRect == NULL)
+ {
+ rcI = m_rcObjectPos;
+ }
+ else
+ {
+ IntersectRect(&rcI, &m_rcObjectPos, pRect);
+ }
+ ::InvalidateRect(m_hWndParent, &rcI, fErase);
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CControlSite::InvalidateRgn(/* [in] */ HRGN hRGN, /* [in] */ BOOL fErase)
+{
+ if (hRGN == NULL)
+ {
+ ::InvalidateRect(m_hWndParent, &m_rcObjectPos, fErase);
+ }
+ else
+ {
+ // Clip the region with the object's bounding area
+ HRGN hrgnClip = CreateRectRgnIndirect(&m_rcObjectPos);
+ if (CombineRgn(hrgnClip, hrgnClip, hRGN, RGN_AND) != ERROR)
+ {
+ ::InvalidateRgn(m_hWndParent, hrgnClip, fErase);
+ }
+ DeleteObject(hrgnClip);
+ }
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CControlSite::ScrollRect(/* [in] */ INT dx, /* [in] */ INT dy, /* [in] */ LPCRECT pRectScroll, /* [in] */ LPCRECT pRectClip)
+{
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CControlSite::AdjustRect(/* [out][in] */ LPRECT prc)
+{
+ if (prc == NULL)
+ {
+ return E_INVALIDARG;
+ }
+
+ // Clip the rectangle against the object position
+ RECT rcI = { 0, 0, 0, 0 };
+ IntersectRect(&rcI, &m_rcObjectPos, prc);
+ *prc = rcI;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CControlSite::OnDefWindowMessage(/* [in] */ UINT msg, /* [in] */ WPARAM wParam, /* [in] */ LPARAM lParam, /* [out] */ LRESULT __RPC_FAR *plResult)
+{
+ if (plResult == NULL)
+ {
+ return E_INVALIDARG;
+ }
+
+ // Pass the message to the windowless control
+ if (m_bWindowless && m_spIOleInPlaceObjectWindowless)
+ {
+ return m_spIOleInPlaceObjectWindowless->OnWindowMessage(msg, wParam, lParam, plResult);
+ }
+
+ return S_FALSE;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// IOleControlSite implementation
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::OnControlInfoChanged(void)
+{
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::LockInPlaceActive(/* [in] */ BOOL fLock)
+{
+ m_bInPlaceLocked = fLock;
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::GetExtendedControl(/* [out] */ IDispatch __RPC_FAR *__RPC_FAR *ppDisp)
+{
+ return E_NOTIMPL;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::TransformCoords(/* [out][in] */ POINTL __RPC_FAR *pPtlHimetric, /* [out][in] */ POINTF __RPC_FAR *pPtfContainer, /* [in] */ DWORD dwFlags)
+{
+ HRESULT hr = S_OK;
+
+ if (pPtlHimetric == NULL)
+ {
+ return E_INVALIDARG;
+ }
+ if (pPtfContainer == NULL)
+ {
+ return E_INVALIDARG;
+ }
+
+ HDC hdc = ::GetDC(m_hWndParent);
+ ::SetMapMode(hdc, MM_HIMETRIC);
+ POINT rgptConvert[2];
+ rgptConvert[0].x = 0;
+ rgptConvert[0].y = 0;
+
+ if (dwFlags & XFORMCOORDS_HIMETRICTOCONTAINER)
+ {
+ rgptConvert[1].x = pPtlHimetric->x;
+ rgptConvert[1].y = pPtlHimetric->y;
+ ::LPtoDP(hdc, rgptConvert, 2);
+ if (dwFlags & XFORMCOORDS_SIZE)
+ {
+ pPtfContainer->x = (float)(rgptConvert[1].x - rgptConvert[0].x);
+ pPtfContainer->y = (float)(rgptConvert[0].y - rgptConvert[1].y);
+ }
+ else if (dwFlags & XFORMCOORDS_POSITION)
+ {
+ pPtfContainer->x = (float)rgptConvert[1].x;
+ pPtfContainer->y = (float)rgptConvert[1].y;
+ }
+ else
+ {
+ hr = E_INVALIDARG;
+ }
+ }
+ else if (dwFlags & XFORMCOORDS_CONTAINERTOHIMETRIC)
+ {
+ rgptConvert[1].x = (int)(pPtfContainer->x);
+ rgptConvert[1].y = (int)(pPtfContainer->y);
+ ::DPtoLP(hdc, rgptConvert, 2);
+ if (dwFlags & XFORMCOORDS_SIZE)
+ {
+ pPtlHimetric->x = rgptConvert[1].x - rgptConvert[0].x;
+ pPtlHimetric->y = rgptConvert[0].y - rgptConvert[1].y;
+ }
+ else if (dwFlags & XFORMCOORDS_POSITION)
+ {
+ pPtlHimetric->x = rgptConvert[1].x;
+ pPtlHimetric->y = rgptConvert[1].y;
+ }
+ else
+ {
+ hr = E_INVALIDARG;
+ }
+ }
+ else
+ {
+ hr = E_INVALIDARG;
+ }
+
+ ::ReleaseDC(m_hWndParent, hdc);
+
+ return hr;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::TranslateAccelerator(/* [in] */ MSG __RPC_FAR *pMsg, /* [in] */ DWORD grfModifiers)
+{
+ return E_NOTIMPL;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::OnFocus(/* [in] */ BOOL fGotFocus)
+{
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSite::ShowPropertyFrame(void)
+{
+ return E_NOTIMPL;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// IBindStatusCallback implementation
+
+HRESULT STDMETHODCALLTYPE CControlSite::OnStartBinding(DWORD dwReserved,
+ IBinding __RPC_FAR *pib)
+{
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CControlSite::GetPriority(LONG __RPC_FAR *pnPriority)
+{
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CControlSite::OnLowResource(DWORD reserved)
+{
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CControlSite::OnProgress(ULONG ulProgress,
+ ULONG ulProgressMax,
+ ULONG ulStatusCode,
+ LPCWSTR szStatusText)
+{
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CControlSite::OnStopBinding(HRESULT hresult, LPCWSTR szError)
+{
+ m_bBindingInProgress = FALSE;
+ m_hrBindResult = hresult;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CControlSite::GetBindInfo(DWORD __RPC_FAR *pgrfBINDF,
+ BINDINFO __RPC_FAR *pbindInfo)
+{
+ *pgrfBINDF = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE |
+ BINDF_GETNEWESTVERSION | BINDF_NOWRITECACHE;
+ pbindInfo->cbSize = sizeof(BINDINFO);
+ pbindInfo->szExtraInfo = NULL;
+ memset(&pbindInfo->stgmedData, 0, sizeof(STGMEDIUM));
+ pbindInfo->grfBindInfoF = 0;
+ pbindInfo->dwBindVerb = 0;
+ pbindInfo->szCustomVerb = NULL;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CControlSite::OnDataAvailable(DWORD grfBSCF,
+ DWORD dwSize,
+ FORMATETC __RPC_FAR *pformatetc,
+ STGMEDIUM __RPC_FAR *pstgmed)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CControlSite::OnObjectAvailable(REFIID riid,
+ IUnknown __RPC_FAR *punk)
+{
+ return S_OK;
+}
+
+// IWindowForBindingUI
+HRESULT STDMETHODCALLTYPE CControlSite::GetWindow(
+ /* [in] */ REFGUID rguidReason,
+ /* [out] */ HWND *phwnd)
+{
+ *phwnd = NULL;
+ return S_OK;
+}
+
+
new file mode 100644
--- /dev/null
+++ b/embedding/browser/activex/src/common/ControlSite.h
@@ -0,0 +1,393 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Adam Lock <adamlock@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+#ifndef CONTROLSITE_H
+#define CONTROLSITE_H
+
+#include "IOleCommandTargetImpl.h"
+
+#include "PropertyList.h"
+
+// If you created a class derived from CControlSite, use the following macro
+// in the interface map of the derived class to include all the necessary
+// interfaces.
+#define CCONTROLSITE_INTERFACES() \
+ COM_INTERFACE_ENTRY(IOleWindow) \
+ COM_INTERFACE_ENTRY(IOleClientSite) \
+ COM_INTERFACE_ENTRY(IOleInPlaceSite) \
+ COM_INTERFACE_ENTRY_IID(IID_IOleInPlaceSite, IOleInPlaceSiteWindowless) \
+ COM_INTERFACE_ENTRY_IID(IID_IOleInPlaceSiteEx, IOleInPlaceSiteWindowless) \
+ COM_INTERFACE_ENTRY(IOleControlSite) \
+ COM_INTERFACE_ENTRY(IDispatch) \
+ COM_INTERFACE_ENTRY_IID(IID_IAdviseSink, IAdviseSinkEx) \
+ COM_INTERFACE_ENTRY_IID(IID_IAdviseSink2, IAdviseSinkEx) \
+ COM_INTERFACE_ENTRY_IID(IID_IAdviseSinkEx, IAdviseSinkEx) \
+ COM_INTERFACE_ENTRY(IOleCommandTarget) \
+ COM_INTERFACE_ENTRY(IServiceProvider) \
+ COM_INTERFACE_ENTRY(IBindStatusCallback) \
+ COM_INTERFACE_ENTRY(IWindowForBindingUI)
+
+// Temoporarily removed by bug 200680. Stops controls misbehaving and calling
+// windowless methods when they shouldn't.
+// COM_INTERFACE_ENTRY_IID(IID_IOleInPlaceSiteWindowless, IOleInPlaceSiteWindowless) \
+
+
+// Class that defines the control's security policy with regards to
+// what controls it hosts etc.
+
+class CControlSiteSecurityPolicy
+{
+public:
+ // Test if the class is safe to host
+ virtual BOOL IsClassSafeToHost(const CLSID & clsid) = 0;
+ // Test if the specified class is marked safe for scripting
+ virtual BOOL IsClassMarkedSafeForScripting(const CLSID & clsid, BOOL &bClassExists) = 0;
+ // Test if the instantiated object is safe for scripting on the specified interface
+ virtual BOOL IsObjectSafeForScripting(IUnknown *pObject, const IID &iid) = 0;
+};
+
+//
+// Class for hosting an ActiveX control
+//
+// This class supports both windowed and windowless classes. The normal
+// steps to hosting a control are this:
+//
+// CControlSiteInstance *pSite = NULL;
+// CControlSiteInstance::CreateInstance(&pSite);
+// pSite->AddRef();
+// pSite->Create(clsidControlToCreate);
+// pSite->Attach(hwndParentWindow, rcPosition);
+//
+// Where propertyList is a named list of values to initialise the new object
+// with, hwndParentWindow is the window in which the control is being created,
+// and rcPosition is the position in window coordinates where the control will
+// be rendered.
+//
+// Destruction is this:
+//
+// pSite->Detach();
+// pSite->Release();
+// pSite = NULL;
+
+class CControlSite : public CComObjectRootEx<CComSingleThreadModel>,
+ public CControlSiteSecurityPolicy,
+ public IOleClientSite,
+ public IOleInPlaceSiteWindowless,
+ public IOleControlSite,
+ public IAdviseSinkEx,
+ public IDispatch,
+ public IServiceProvider,
+ public IOleCommandTargetImpl<CControlSite>,
+ public IBindStatusCallback,
+ public IWindowForBindingUI
+{
+public:
+// Site management values
+ // Handle to parent window
+ HWND m_hWndParent;
+ // Position of the site and the contained object
+ RECT m_rcObjectPos;
+ // Flag indicating if client site should be set early or late
+ unsigned m_bSetClientSiteFirst:1;
+ // Flag indicating whether control is visible or not
+ unsigned m_bVisibleAtRuntime:1;
+ // Flag indicating if control is in-place active
+ unsigned m_bInPlaceActive:1;
+ // Flag indicating if control is UI active
+ unsigned m_bUIActive:1;
+ // Flag indicating if control is in-place locked and cannot be deactivated
+ unsigned m_bInPlaceLocked:1;
+ // Flag indicating if the site allows windowless controls
+ unsigned m_bSupportWindowlessActivation:1;
+ // Flag indicating if control is windowless (after being created)
+ unsigned m_bWindowless:1;
+ // Flag indicating if only safely scriptable controls are allowed
+ unsigned m_bSafeForScriptingObjectsOnly:1;
+ // Pointer to an externally registered service provider
+ CComPtr<IServiceProvider> m_spServiceProvider;
+ // Pointer to the OLE container
+ CComPtr<IOleContainer> m_spContainer;
+ // Return the default security policy object
+ static CControlSiteSecurityPolicy *GetDefaultControlSecurityPolicy();
+
+protected:
+// Pointers to object interfaces
+ // Raw pointer to the object
+ CComPtr<IUnknown> m_spObject;
+ // Pointer to objects IViewObject interface
+ CComQIPtr<IViewObject, &IID_IViewObject> m_spIViewObject;
+ // Pointer to object's IOleObject interface
+ CComQIPtr<IOleObject, &IID_IOleObject> m_spIOleObject;
+ // Pointer to object's IOleInPlaceObject interface
+ CComQIPtr<IOleInPlaceObject, &IID_IOleInPlaceObject> m_spIOleInPlaceObject;
+ // Pointer to object's IOleInPlaceObjectWindowless interface
+ CComQIPtr<IOleInPlaceObjectWindowless, &IID_IOleInPlaceObjectWindowless> m_spIOleInPlaceObjectWindowless;
+ // CLSID of the control
+ CLSID m_CLSID;
+ // Parameter list
+ PropertyList m_ParameterList;
+ // Pointer to the security policy
+ CControlSiteSecurityPolicy *m_pSecurityPolicy;
+
+// Binding variables
+ // Flag indicating whether binding is in progress
+ unsigned m_bBindingInProgress;
+ // Result from the binding operation
+ HRESULT m_hrBindResult;
+
+// Double buffer drawing variables used for windowless controls
+ // Area of buffer
+ RECT m_rcBuffer;
+ // Bitmap to buffer
+ HBITMAP m_hBMBuffer;
+ // Bitmap to buffer
+ HBITMAP m_hBMBufferOld;
+ // Device context
+ HDC m_hDCBuffer;
+ // Clipping area of site
+ HRGN m_hRgnBuffer;
+ // Flags indicating how the buffer was painted
+ DWORD m_dwBufferFlags;
+
+// Ambient properties
+ // Locale ID
+ LCID m_nAmbientLocale;
+ // Foreground colour
+ COLORREF m_clrAmbientForeColor;
+ // Background colour
+ COLORREF m_clrAmbientBackColor;
+ // Flag indicating if control should hatch itself
+ bool m_bAmbientShowHatching:1;
+ // Flag indicating if control should have grab handles
+ bool m_bAmbientShowGrabHandles:1;
+ // Flag indicating if control is in edit/user mode
+ bool m_bAmbientUserMode:1;
+ // Flag indicating if control has a 3d border or not
+ bool m_bAmbientAppearance:1;
+
+protected:
+ // Notifies the attached control of a change to an ambient property
+ virtual void FireAmbientPropertyChange(DISPID id);
+
+public:
+// Construction and destruction
+ // Constructor
+ CControlSite();
+ // Destructor
+ virtual ~CControlSite();
+
+BEGIN_COM_MAP(CControlSite)
+ CCONTROLSITE_INTERFACES()
+END_COM_MAP()
+
+BEGIN_OLECOMMAND_TABLE()
+END_OLECOMMAND_TABLE()
+
+ // Returns the window used when processing ole commands
+ HWND GetCommandTargetWindow()
+ {
+ return NULL; // TODO
+ }
+
+// Object creation and management functions
+ // Creates and initialises an object
+ virtual HRESULT Create(REFCLSID clsid, PropertyList &pl = PropertyList(),
+ LPCWSTR szCodebase = NULL, IBindCtx *pBindContext = NULL);
+ // Attaches the object to the site
+ virtual HRESULT Attach(HWND hwndParent, const RECT &rcPos, IUnknown *pInitStream = NULL);
+ // Detaches the object from the site
+ virtual HRESULT Detach();
+ // Returns the IUnknown pointer for the object
+ virtual HRESULT GetControlUnknown(IUnknown **ppObject);
+ // Sets the bounding rectangle for the object
+ virtual HRESULT SetPosition(const RECT &rcPos);
+ // Draws the object using the provided DC
+ virtual HRESULT Draw(HDC hdc);
+ // Performs the specified action on the object
+ virtual HRESULT DoVerb(LONG nVerb, LPMSG lpMsg = NULL);
+ // Sets an advise sink up for changes to the object
+ virtual HRESULT Advise(IUnknown *pIUnkSink, const IID &iid, DWORD *pdwCookie);
+ // Removes an advise sink
+ virtual HRESULT Unadvise(const IID &iid, DWORD dwCookie);
+ // Register an external service provider object
+ virtual void SetServiceProvider(IServiceProvider *pSP)
+ {
+ m_spServiceProvider = pSP;
+ }
+ virtual void SetContainer(IOleContainer *pContainer)
+ {
+ m_spContainer = pContainer;
+ }
+ // Set the security policy object. Ownership of this object remains with the caller and the security
+ // policy object is meant to exist for as long as it is set here.
+ virtual void SetSecurityPolicy(CControlSiteSecurityPolicy *pSecurityPolicy)
+ {
+ m_pSecurityPolicy = pSecurityPolicy;
+ }
+ virtual CControlSiteSecurityPolicy *GetSecurityPolicy() const
+ {
+ return m_pSecurityPolicy;
+ }
+
+// Methods to set ambient properties
+ virtual void SetAmbientUserMode(BOOL bUser);
+
+// Inline helper methods
+ // Returns the object's CLSID
+ virtual const CLSID &GetObjectCLSID() const
+ {
+ return m_CLSID;
+ }
+ // Tests if the object is valid or not
+ virtual BOOL IsObjectValid() const
+ {
+ return (m_spObject) ? TRUE : FALSE;
+ }
+ // Returns the parent window to this one
+ virtual HWND GetParentWindow() const
+ {
+ return m_hWndParent;
+ }
+ // Returns the inplace active state of the object
+ virtual BOOL IsInPlaceActive() const
+ {
+ return m_bInPlaceActive;
+ }
+
+// CControlSiteSecurityPolicy
+ // Test if the class is safe to host
+ virtual BOOL IsClassSafeToHost(const CLSID & clsid);
+ // Test if the specified class is marked safe for scripting
+ virtual BOOL IsClassMarkedSafeForScripting(const CLSID & clsid, BOOL &bClassExists);
+ // Test if the instantiated object is safe for scripting on the specified interface
+ virtual BOOL IsObjectSafeForScripting(IUnknown *pObject, const IID &iid);
+ // Test if the instantiated object is safe for scripting on the specified interface
+ virtual BOOL IsObjectSafeForScripting(const IID &iid);
+
+// IServiceProvider
+ virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, REFIID riid, void** ppv);
+
+// IDispatch
+ virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(/* [out] */ UINT __RPC_FAR *pctinfo);
+ virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(/* [in] */ UINT iTInfo, /* [in] */ LCID lcid, /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
+ virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(/* [in] */ REFIID riid, /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames, /* [in] */ UINT cNames, /* [in] */ LCID lcid, /* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
+ virtual /* [local] */ HRESULT STDMETHODCALLTYPE Invoke(/* [in] */ DISPID dispIdMember, /* [in] */ REFIID riid, /* [in] */ LCID lcid, /* [in] */ WORD wFlags, /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams, /* [out] */ VARIANT __RPC_FAR *pVarResult, /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo, /* [out] */ UINT __RPC_FAR *puArgErr);
+
+// IAdviseSink implementation
+ virtual /* [local] */ void STDMETHODCALLTYPE OnDataChange(/* [unique][in] */ FORMATETC __RPC_FAR *pFormatetc, /* [unique][in] */ STGMEDIUM __RPC_FAR *pStgmed);
+ virtual /* [local] */ void STDMETHODCALLTYPE OnViewChange(/* [in] */ DWORD dwAspect, /* [in] */ LONG lindex);
+ virtual /* [local] */ void STDMETHODCALLTYPE OnRename(/* [in] */ IMoniker __RPC_FAR *pmk);
+ virtual /* [local] */ void STDMETHODCALLTYPE OnSave(void);
+ virtual /* [local] */ void STDMETHODCALLTYPE OnClose(void);
+
+// IAdviseSink2
+ virtual /* [local] */ void STDMETHODCALLTYPE OnLinkSrcChange(/* [unique][in] */ IMoniker __RPC_FAR *pmk);
+
+// IAdviseSinkEx implementation
+ virtual /* [local] */ void STDMETHODCALLTYPE OnViewStatusChange(/* [in] */ DWORD dwViewStatus);
+
+// IOleWindow implementation
+ virtual /* [input_sync] */ HRESULT STDMETHODCALLTYPE GetWindow(/* [out] */ HWND __RPC_FAR *phwnd);
+ virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(/* [in] */ BOOL fEnterMode);
+
+// IOleClientSite implementation
+ virtual HRESULT STDMETHODCALLTYPE SaveObject(void);
+ virtual HRESULT STDMETHODCALLTYPE GetMoniker(/* [in] */ DWORD dwAssign, /* [in] */ DWORD dwWhichMoniker, /* [out] */ IMoniker __RPC_FAR *__RPC_FAR *ppmk);
+ virtual HRESULT STDMETHODCALLTYPE GetContainer(/* [out] */ IOleContainer __RPC_FAR *__RPC_FAR *ppContainer);
+ virtual HRESULT STDMETHODCALLTYPE ShowObject(void);
+ virtual HRESULT STDMETHODCALLTYPE OnShowWindow(/* [in] */ BOOL fShow);
+ virtual HRESULT STDMETHODCALLTYPE RequestNewObjectLayout(void);
+
+// IOleInPlaceSite implementation
+ virtual HRESULT STDMETHODCALLTYPE CanInPlaceActivate(void);
+ virtual HRESULT STDMETHODCALLTYPE OnInPlaceActivate(void);
+ virtual HRESULT STDMETHODCALLTYPE OnUIActivate(void);
+ virtual HRESULT STDMETHODCALLTYPE GetWindowContext(/* [out] */ IOleInPlaceFrame __RPC_FAR *__RPC_FAR *ppFrame, /* [out] */ IOleInPlaceUIWindow __RPC_FAR *__RPC_FAR *ppDoc, /* [out] */ LPRECT lprcPosRect, /* [out] */ LPRECT lprcClipRect, /* [out][in] */ LPOLEINPLACEFRAMEINFO lpFrameInfo);
+ virtual HRESULT STDMETHODCALLTYPE Scroll(/* [in] */ SIZE scrollExtant);
+ virtual HRESULT STDMETHODCALLTYPE OnUIDeactivate(/* [in] */ BOOL fUndoable);
+ virtual HRESULT STDMETHODCALLTYPE OnInPlaceDeactivate(void);
+ virtual HRESULT STDMETHODCALLTYPE DiscardUndoState(void);
+ virtual HRESULT STDMETHODCALLTYPE DeactivateAndUndo(void);
+ virtual HRESULT STDMETHODCALLTYPE OnPosRectChange(/* [in] */ LPCRECT lprcPosRect);
+
+// IOleInPlaceSiteEx implementation
+ virtual HRESULT STDMETHODCALLTYPE OnInPlaceActivateEx(/* [out] */ BOOL __RPC_FAR *pfNoRedraw, /* [in] */ DWORD dwFlags);
+ virtual HRESULT STDMETHODCALLTYPE OnInPlaceDeactivateEx(/* [in] */ BOOL fNoRedraw);
+ virtual HRESULT STDMETHODCALLTYPE RequestUIActivate(void);
+
+// IOleInPlaceSiteWindowless implementation
+ virtual HRESULT STDMETHODCALLTYPE CanWindowlessActivate(void);
+ virtual HRESULT STDMETHODCALLTYPE GetCapture(void);
+ virtual HRESULT STDMETHODCALLTYPE SetCapture(/* [in] */ BOOL fCapture);
+ virtual HRESULT STDMETHODCALLTYPE GetFocus(void);
+ virtual HRESULT STDMETHODCALLTYPE SetFocus(/* [in] */ BOOL fFocus);
+ virtual HRESULT STDMETHODCALLTYPE GetDC(/* [in] */ LPCRECT pRect, /* [in] */ DWORD grfFlags, /* [out] */ HDC __RPC_FAR *phDC);
+ virtual HRESULT STDMETHODCALLTYPE ReleaseDC(/* [in] */ HDC hDC);
+ virtual HRESULT STDMETHODCALLTYPE InvalidateRect(/* [in] */ LPCRECT pRect, /* [in] */ BOOL fErase);
+ virtual HRESULT STDMETHODCALLTYPE InvalidateRgn(/* [in] */ HRGN hRGN, /* [in] */ BOOL fErase);
+ virtual HRESULT STDMETHODCALLTYPE ScrollRect(/* [in] */ INT dx, /* [in] */ INT dy, /* [in] */ LPCRECT pRectScroll, /* [in] */ LPCRECT pRectClip);
+ virtual HRESULT STDMETHODCALLTYPE AdjustRect(/* [out][in] */ LPRECT prc);
+ virtual HRESULT STDMETHODCALLTYPE OnDefWindowMessage(/* [in] */ UINT msg, /* [in] */ WPARAM wParam, /* [in] */ LPARAM lParam, /* [out] */ LRESULT __RPC_FAR *plResult);
+
+// IOleControlSite implementation
+ virtual HRESULT STDMETHODCALLTYPE OnControlInfoChanged(void);
+ virtual HRESULT STDMETHODCALLTYPE LockInPlaceActive(/* [in] */ BOOL fLock);
+ virtual HRESULT STDMETHODCALLTYPE GetExtendedControl(/* [out] */ IDispatch __RPC_FAR *__RPC_FAR *ppDisp);
+ virtual HRESULT STDMETHODCALLTYPE TransformCoords(/* [out][in] */ POINTL __RPC_FAR *pPtlHimetric, /* [out][in] */ POINTF __RPC_FAR *pPtfContainer, /* [in] */ DWORD dwFlags);
+ virtual HRESULT STDMETHODCALLTYPE TranslateAccelerator(/* [in] */ MSG __RPC_FAR *pMsg, /* [in] */ DWORD grfModifiers);
+ virtual HRESULT STDMETHODCALLTYPE OnFocus(/* [in] */ BOOL fGotFocus);
+ virtual HRESULT STDMETHODCALLTYPE ShowPropertyFrame( void);
+
+// IBindStatusCallback
+ virtual HRESULT STDMETHODCALLTYPE OnStartBinding(/* [in] */ DWORD dwReserved, /* [in] */ IBinding __RPC_FAR *pib);
+ virtual HRESULT STDMETHODCALLTYPE GetPriority(/* [out] */ LONG __RPC_FAR *pnPriority);
+ virtual HRESULT STDMETHODCALLTYPE OnLowResource(/* [in] */ DWORD reserved);
+ virtual HRESULT STDMETHODCALLTYPE OnProgress(/* [in] */ ULONG ulProgress, /* [in] */ ULONG ulProgressMax, /* [in] */ ULONG ulStatusCode, /* [in] */ LPCWSTR szStatusText);
+ virtual HRESULT STDMETHODCALLTYPE OnStopBinding(/* [in] */ HRESULT hresult, /* [unique][in] */ LPCWSTR szError);
+ virtual /* [local] */ HRESULT STDMETHODCALLTYPE GetBindInfo( /* [out] */ DWORD __RPC_FAR *grfBINDF, /* [unique][out][in] */ BINDINFO __RPC_FAR *pbindinfo);
+ virtual /* [local] */ HRESULT STDMETHODCALLTYPE OnDataAvailable(/* [in] */ DWORD grfBSCF, /* [in] */ DWORD dwSize, /* [in] */ FORMATETC __RPC_FAR *pformatetc, /* [in] */ STGMEDIUM __RPC_FAR *pstgmed);
+ virtual HRESULT STDMETHODCALLTYPE OnObjectAvailable(/* [in] */ REFIID riid, /* [iid_is][in] */ IUnknown __RPC_FAR *punk);
+
+// IWindowForBindingUI
+ virtual HRESULT STDMETHODCALLTYPE GetWindow(/* [in] */ REFGUID rguidReason, /* [out] */ HWND *phwnd);
+};
+
+typedef CComObject<CControlSite> CControlSiteInstance;
+
+
+
+#endif
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/embedding/browser/activex/src/common/ControlSiteIPFrame.cpp
@@ -0,0 +1,136 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Adam Lock <adamlock@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+#include "stdafx.h"
+
+#include "ControlSiteIPFrame.h"
+
+CControlSiteIPFrame::CControlSiteIPFrame()
+{
+ m_hwndFrame = NULL;
+}
+
+
+CControlSiteIPFrame::~CControlSiteIPFrame()
+{
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// IOleWindow implementation
+
+HRESULT STDMETHODCALLTYPE CControlSiteIPFrame::GetWindow(/* [out] */ HWND __RPC_FAR *phwnd)
+{
+ if (phwnd == NULL)
+ {
+ return E_INVALIDARG;
+ }
+ *phwnd = m_hwndFrame;
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CControlSiteIPFrame::ContextSensitiveHelp(/* [in] */ BOOL fEnterMode)
+{
+ return S_OK;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// IOleInPlaceUIWindow implementation
+
+HRESULT STDMETHODCALLTYPE CControlSiteIPFrame::GetBorder(/* [out] */ LPRECT lprectBorder)
+{
+ return INPLACE_E_NOTOOLSPACE;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSiteIPFrame::RequestBorderSpace(/* [unique][in] */ LPCBORDERWIDTHS pborderwidths)
+{
+ return INPLACE_E_NOTOOLSPACE;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSiteIPFrame::SetBorderSpace(/* [unique][in] */ LPCBORDERWIDTHS pborderwidths)
+{
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSiteIPFrame::SetActiveObject(/* [unique][in] */ IOleInPlaceActiveObject __RPC_FAR *pActiveObject, /* [unique][string][in] */ LPCOLESTR pszObjName)
+{
+ return S_OK;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// IOleInPlaceFrame implementation
+
+HRESULT STDMETHODCALLTYPE CControlSiteIPFrame::InsertMenus(/* [in] */ HMENU hmenuShared, /* [out][in] */ LPOLEMENUGROUPWIDTHS lpMenuWidths)
+{
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSiteIPFrame::SetMenu(/* [in] */ HMENU hmenuShared, /* [in] */ HOLEMENU holemenu, /* [in] */ HWND hwndActiveObject)
+{
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSiteIPFrame::RemoveMenus(/* [in] */ HMENU hmenuShared)
+{
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSiteIPFrame::SetStatusText(/* [in] */ LPCOLESTR pszStatusText)
+{
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSiteIPFrame::EnableModeless(/* [in] */ BOOL fEnable)
+{
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE CControlSiteIPFrame::TranslateAccelerator(/* [in] */ LPMSG lpmsg, /* [in] */ WORD wID)
+{
+ return E_NOTIMPL;
+}
+
new file mode 100644
--- /dev/null
+++ b/embedding/browser/activex/src/common/ControlSiteIPFrame.h
@@ -0,0 +1,77 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Adam Lock <adamlock@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+#ifndef CONTROLSITEIPFRAME_H
+#define CONTROLSITEIPFRAME_H
+
+class CControlSiteIPFrame : public CComObjectRootEx<CComSingleThreadModel>,
+ public IOleInPlaceFrame
+{
+public:
+ CControlSiteIPFrame();
+ virtual ~CControlSiteIPFrame();
+
+ HWND m_hwndFrame;
+
+BEGIN_COM_MAP(CControlSiteIPFrame)
+ COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleInPlaceFrame)
+ COM_INTERFACE_ENTRY_IID(IID_IOleInPlaceUIWindow, IOleInPlaceFrame)
+ COM_INTERFACE_ENTRY(IOleInPlaceFrame)
+END_COM_MAP()
+
+ // IOleWindow
+ virtual /* [input_sync] */ HRESULT STDMETHODCALLTYPE GetWindow(/* [out] */ HWND __RPC_FAR *phwnd);
+ virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(/* [in] */ BOOL fEnterMode);
+
+ // IOleInPlaceUIWindow implementation
+ virtual /* [input_sync] */ HRESULT STDMETHODCALLTYPE GetBorder(/* [out] */ LPRECT lprectBorder);
+ virtual /* [input_sync] */ HRESULT STDMETHODCALLTYPE RequestBorderSpace(/* [unique][in] */ LPCBORDERWIDTHS pborderwidths);
+ virtual /* [input_sync] */ HRESULT STDMETHODCALLTYPE SetBorderSpace(/* [unique][in] */ LPCBORDERWIDTHS pborderwidths);
+ virtual HRESULT STDMETHODCALLTYPE SetActiveObject(/* [unique][in] */ IOleInPlaceActiveObject __RPC_FAR *pActiveObject, /* [unique][string][in] */ LPCOLESTR pszObjName);
+
+ // IOleInPlaceFrame implementation
+ virtual HRESULT STDMETHODCALLTYPE InsertMenus(/* [in] */ HMENU hmenuShared, /* [out][in] */ LPOLEMENUGROUPWIDTHS lpMenuWidths);
+ virtual /* [input_sync] */ HRESULT STDMETHODCALLTYPE SetMenu(/* [in] */ HMENU hmenuShared, /* [in] */ HOLEMENU holemenu, /* [in] */ HWND hwndActiveObject);
+ virtual HRESULT STDMETHODCALLTYPE RemoveMenus(/* [in] */ HMENU hmenuShared);
+ virtual /* [input_sync] */ HRESULT STDMETHODCALLTYPE SetStatusText(/* [in] */ LPCOLESTR pszStatusText);
+ virtual HRESULT STDMETHODCALLTYPE EnableModeless(/* [in] */ BOOL fEnable);
+ virtual HRESULT STDMETHODCALLTYPE TranslateAccelerator(/* [in] */ LPMSG lpmsg, /* [in] */ WORD wID);
+};
+
+typedef CComObject<CControlSiteIPFrame> CControlSiteIPFrameInstance;
+
+#endif
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/embedding/browser/activex/src/common/IEHtmlButtonElement.cpp
@@ -0,0 +1,155 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Alexandre Trémon <atremon@elansoftware.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "stdafx.h"
+#include "IEHTMLButtonElement.h"
+#include "IEHtmlElement.h"
+#include "nsIDOMHTMLButtonElement.h"
+
+HRESULT CIEHtmlButtonElement::FinalConstruct( )
+{
+ return CComCreator<CComAggObject<CIEHtmlElement> >::CreateInstance(GetControllingUnknown(),
+ IID_IUnknown, reinterpret_cast<void**>(&m_pHtmlElementAgg));
+}
+
+HRESULT CIEHtmlButtonElement::GetHtmlElement(CIEHtmlElement **ppHtmlElement)
+{
+ if (ppHtmlElement == NULL)
+ return E_FAIL;
+ *ppHtmlElement = NULL;
+ IHTMLElement* pHtmlElement = NULL;
+ // This causes an AddRef on outer unknown:
+ HRESULT hr = m_pHtmlElementAgg->QueryInterface(IID_IHTMLElement, (void**)&pHtmlElement);
+ *ppHtmlElement = (CIEHtmlElement*)pHtmlElement;
+ return hr;
+}
+
+HRESULT CIEHtmlButtonElement::SetDOMNode(nsIDOMNode *pDomNode)
+{
+ mDOMNode = pDomNode;
+ //Forward to aggregated object:
+ CIEHtmlElement *pHtmlElement;
+ GetHtmlElement(&pHtmlElement);
+ HRESULT hr = pHtmlElement->SetDOMNode(pDomNode);
+ // Release on outer unknown because GetHtmlDomNode does AddRef on it:
+ GetControllingUnknown()->Release();
+ return hr;
+}
+
+HRESULT CIEHtmlButtonElement::SetParent(CNode *pParent)
+{
+ CNode::SetParent(pParent);
+ //Forward to aggregated object:
+ CIEHtmlElement *pHtmlElement;
+ GetHtmlElement(&pHtmlElement);
+ HRESULT hr = pHtmlElement->SetParent(pParent);
+ // Release on outer unknown because GetHtmlDomNode does AddRef on it:
+ GetControllingUnknown()->Release();
+ return hr;
+}
+
+// -----------------------------------------------------------------------
+// IHTMLButtonElement Implementation
+// -----------------------------------------------------------------------
+
+HRESULT STDMETHODCALLTYPE CIEHtmlButtonElement::get_type(BSTR __RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlButtonElement::put_value(BSTR v)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlButtonElement::get_value(BSTR __RPC_FAR *p)
+{
+ if (p == NULL)
+ return E_INVALIDARG;
+
+ *p = NULL;
+ nsCOMPtr<nsIDOMHTMLButtonElement> domHtmlButtonElement = do_QueryInterface(mDOMNode);
+ if (!domHtmlButtonElement)
+ return E_UNEXPECTED;
+ nsAutoString strValue;
+ domHtmlButtonElement->GetValue(strValue);
+ *p = SysAllocString(strValue.get());
+ if (!*p)
+ return E_OUTOFMEMORY;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlButtonElement::put_name(BSTR v)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlButtonElement::get_name(BSTR __RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlButtonElement::put_status(VARIANT v)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlButtonElement::get_status(VARIANT __RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlButtonElement::put_disabled(VARIANT_BOOL v)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlButtonElement::get_disabled(VARIANT_BOOL __RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlButtonElement::get_form(IHTMLFormElement __RPC_FAR *__RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlButtonElement::createTextRange(IHTMLTxtRange __RPC_FAR *__RPC_FAR *range)
+{
+ return E_NOTIMPL;
+}
new file mode 100644
--- /dev/null
+++ b/embedding/browser/activex/src/common/IEHtmlButtonElement.h
@@ -0,0 +1,139 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Alexandre Trémon <atremon@elansoftware.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+//
+// Declaration of IHTMLButtonElement and related classes
+//
+#ifndef IHTMLBUTTONELEMENT_H
+#define IHTMLBUTTONELEMENT_H
+
+#include "IEHtmlNode.h"
+
+class CIEHtmlElement;
+
+// NOTE: Nasty hack in case arcane SDK does not define IHTMLButtonElement
+
+#ifndef __IHTMLButtonElement_INTERFACE_DEFINED__
+ MIDL_INTERFACE("3050f2bb-98b5-11cf-bb82-00aa00bdce0b")
+ IHTMLButtonElement : public IDispatch
+ {
+ public:
+ virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_type(
+ /* [out][retval] */ BSTR *p) = 0;
+
+ virtual /* [bindable][displaybind][id][propput] */ HRESULT STDMETHODCALLTYPE put_value(
+ /* [in] */ BSTR v) = 0;
+
+ virtual /* [bindable][displaybind][id][propget] */ HRESULT STDMETHODCALLTYPE get_value(
+ /* [out][retval] */ BSTR *p) = 0;
+
+ virtual /* [bindable][displaybind][id][propput] */ HRESULT STDMETHODCALLTYPE put_name(
+ /* [in] */ BSTR v) = 0;
+
+ virtual /* [bindable][displaybind][id][propget] */ HRESULT STDMETHODCALLTYPE get_name(
+ /* [out][retval] */ BSTR *p) = 0;
+
+ virtual /* [id][propput] */ HRESULT STDMETHODCALLTYPE put_status(
+ /* [in] */ VARIANT v) = 0;
+
+ virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_status(
+ /* [out][retval] */ VARIANT *p) = 0;
+
+ virtual /* [bindable][displaybind][id][propput] */ HRESULT STDMETHODCALLTYPE put_disabled(
+ /* [in] */ VARIANT_BOOL v) = 0;
+
+ virtual /* [bindable][displaybind][id][propget] */ HRESULT STDMETHODCALLTYPE get_disabled(
+ /* [out][retval] */ VARIANT_BOOL *p) = 0;
+
+ virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_form(
+ /* [out][retval] */ IHTMLFormElement **p) = 0;
+
+ virtual /* [id] */ HRESULT STDMETHODCALLTYPE createTextRange(
+ /* [out][retval] */ IHTMLTxtRange **range) = 0;
+
+ };
+#endif
+
+class CIEHtmlButtonElement :
+ public CNode,
+ public IDispatchImpl<IHTMLButtonElement, &__uuidof(IHTMLButtonElement), &LIBID_MSHTML>
+{
+public:
+ CIEHtmlButtonElement() {
+ };
+
+ HRESULT FinalConstruct( );
+ virtual HRESULT GetHtmlElement(CIEHtmlElement **ppHtmlElement);
+ virtual HRESULT SetDOMNode(nsIDOMNode *pDomNode);
+ virtual HRESULT SetParent(CNode *pParent);
+
+DECLARE_GET_CONTROLLING_UNKNOWN()
+
+protected:
+ virtual ~CIEHtmlButtonElement() {
+ };
+
+public:
+
+BEGIN_COM_MAP(CIEHtmlButtonElement)
+ COM_INTERFACE_ENTRY(IDispatch)
+ COM_INTERFACE_ENTRY(IHTMLButtonElement)
+ COM_INTERFACE_ENTRY_AGGREGATE(IID_IHTMLElement, m_pHtmlElementAgg.p)
+ COM_INTERFACE_ENTRY_AGGREGATE(__uuidof(IHTMLDOMNode), m_pHtmlElementAgg.p)
+END_COM_MAP()
+
+ // IHTMLButtonElement Implementation:
+ virtual HRESULT STDMETHODCALLTYPE get_type(BSTR __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE put_value(BSTR v);
+ virtual HRESULT STDMETHODCALLTYPE get_value(BSTR __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE put_name(BSTR v);
+ virtual HRESULT STDMETHODCALLTYPE get_name(BSTR __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE put_status(VARIANT v);
+ virtual HRESULT STDMETHODCALLTYPE get_status(VARIANT __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE put_disabled(VARIANT_BOOL v);
+ virtual HRESULT STDMETHODCALLTYPE get_disabled(VARIANT_BOOL __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE get_form(IHTMLFormElement __RPC_FAR *__RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE createTextRange(IHTMLTxtRange __RPC_FAR *__RPC_FAR *range);
+
+protected:
+ CComPtr<IUnknown> m_pHtmlElementAgg;
+};
+
+typedef CComObject<CIEHtmlButtonElement> CIEHtmlButtonElementInstance;
+
+#endif //IHTMLBUTTONELEMENT_H
new file mode 100644
--- /dev/null
+++ b/embedding/browser/activex/src/common/IEHtmlElement.cpp
@@ -0,0 +1,979 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Adam Lock <adamlock@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "stdafx.h"
+
+#include "nsCOMPtr.h"
+#include "nsIDOMElement.h"
+
+#include "IEHtmlElement.h"
+#include "IEHtmlElementCollection.h"
+
+#include "nsIDOMHTMLElement.h"
+#include "nsIDOMNSHTMLElement.h"
+#include "nsIDOM3Node.h"
+#include "nsIDOMDocumentRange.h"
+#include "nsIDOMRange.h"
+#include "nsIDOMNSRange.h"
+#include "nsIDOMDocumentFragment.h"
+#include "nsIDocumentEncoder.h"
+#include "nsContentCID.h"
+
+CIEHtmlElement::CIEHtmlElement()
+{
+ m_pNodeAgg = NULL;
+}
+
+HRESULT CIEHtmlElement::FinalConstruct( )
+{
+ return CComCreator<CComAggObject<CIEHtmlDomNode> >::CreateInstance(GetControllingUnknown(),
+ IID_IUnknown, reinterpret_cast<void**>(&m_pNodeAgg));
+}
+
+CIEHtmlElement::~CIEHtmlElement()
+{
+}
+
+void CIEHtmlElement::FinalRelease( )
+{
+ m_pNodeAgg->Release();
+}
+
+HRESULT CIEHtmlElement::GetChildren(CIEHtmlElementCollectionInstance **ppCollection)
+{
+ // Validate parameters
+ if (ppCollection == NULL)
+ {
+ return E_INVALIDARG;
+ }
+
+ *ppCollection = NULL;
+
+ // Create a collection representing the children of this node
+ CIEHtmlElementCollectionInstance *pCollection = NULL;
+ CIEHtmlElementCollection::CreateFromParentNode(this, FALSE, (CIEHtmlElementCollection **) &pCollection);
+ if (pCollection)
+ {
+ pCollection->AddRef();
+ *ppCollection = pCollection;
+ }
+
+ return S_OK;
+}
+
+HRESULT CIEHtmlElement::GetHtmlDomNode(CIEHtmlDomNode **ppHtmlDomNode)
+{
+ if (ppHtmlDomNode == NULL)
+ return E_FAIL;
+ *ppHtmlDomNode = NULL;
+ IHTMLDOMNode* pHtmlNode = NULL;
+ // This causes an AddRef on outer unknown:
+ HRESULT hr = m_pNodeAgg->QueryInterface(__uuidof(IHTMLDOMNode), (void**)&pHtmlNode);
+ *ppHtmlDomNode = (CIEHtmlDomNode*)pHtmlNode;
+ return hr;
+}
+
+HRESULT CIEHtmlElement::SetDOMNode(nsIDOMNode *pDomNode)
+{
+ mDOMNode = pDomNode;
+ // Forward to aggregated object:
+ CIEHtmlDomNode *pHtmlDomNode;
+ GetHtmlDomNode(&pHtmlDomNode);
+ HRESULT hr = pHtmlDomNode->SetDOMNode(pDomNode);
+ // Release on outer unknown because GetHtmlDomNode does AddRef on it:
+ GetControllingUnknown()->Release();
+ return hr;
+}
+
+HRESULT CIEHtmlElement::SetParent(CNode *pParent)
+{
+ CNode::SetParent(pParent);
+ // Forward to aggregated object:
+ CIEHtmlDomNode *pHtmlDomNode;
+ GetHtmlDomNode(&pHtmlDomNode);
+ HRESULT hr = pHtmlDomNode->SetParent(pParent);
+ // Release on outer unknown because GetHtmlDomNode does AddRef on it:
+ GetControllingUnknown()->Release();
+ return hr;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// IHTMLElement implementation
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::setAttribute(BSTR strAttributeName, VARIANT AttributeValue, LONG lFlags)
+{
+ if (strAttributeName == NULL)
+ {
+ return E_INVALIDARG;
+ }
+
+ nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mDOMNode);
+ if (!element)
+ {
+ return E_UNEXPECTED;
+ }
+
+ // Get the name from the BSTR
+ USES_CONVERSION;
+ nsAutoString name(OLE2W(strAttributeName));
+
+ // Get the value from the variant
+ CComVariant vValue;
+ if (FAILED(vValue.ChangeType(VT_BSTR, &AttributeValue)))
+ {
+ return E_INVALIDARG;
+ }
+
+ // Set the attribute
+ nsAutoString value(OLE2W(vValue.bstrVal));
+ element->SetAttribute(name, value);
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::getAttribute(BSTR strAttributeName, LONG lFlags, VARIANT __RPC_FAR *AttributeValue)
+{
+ if (strAttributeName == NULL)
+ {
+ return E_INVALIDARG;
+ }
+ if (AttributeValue == NULL)
+ {
+ return E_INVALIDARG;
+ }
+ VariantInit(AttributeValue);
+
+ // Get the name from the BSTR
+ USES_CONVERSION;
+ nsAutoString name(OLE2W(strAttributeName));
+
+ nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mDOMNode);
+ if (!element)
+ {
+ return E_UNEXPECTED;
+ }
+
+ BOOL bCaseSensitive = (lFlags == VARIANT_TRUE) ? TRUE : FALSE;
+
+
+ // Get the attribute
+ nsAutoString value;
+ nsresult rv = element->GetAttribute(name, value);
+ if (NS_SUCCEEDED(rv))
+ {
+ USES_CONVERSION;
+ AttributeValue->vt = VT_BSTR;
+ AttributeValue->bstrVal = SysAllocString(W2COLE(value.get()));
+ return S_OK;
+ }
+ else
+ {
+ return S_FALSE;
+ }
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::removeAttribute(BSTR strAttributeName, LONG lFlags, VARIANT_BOOL __RPC_FAR *pfSuccess)
+{
+ if (strAttributeName == NULL)
+ {
+ return E_INVALIDARG;
+ }
+
+ nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mDOMNode);
+ if (!element)
+ {
+ return E_UNEXPECTED;
+ }
+
+ BOOL bCaseSensitive = (lFlags == VARIANT_TRUE) ? TRUE : FALSE;
+
+ // Get the name from the BSTR
+ USES_CONVERSION;
+ nsAutoString name(OLE2W(strAttributeName));
+
+ // Remove the attribute
+ nsresult nr = element->RemoveAttribute(name);
+ BOOL bRemoved = (nr == NS_OK) ? TRUE : FALSE;
+
+ if (pfSuccess)
+ {
+ *pfSuccess = (bRemoved) ? VARIANT_TRUE : VARIANT_FALSE;
+ }
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_className(BSTR v)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_className(BSTR __RPC_FAR *p)
+{
+ if (p == NULL)
+ {
+ return E_INVALIDARG;
+ }
+
+ VARIANT vValue;
+ VariantInit(&vValue);
+ BSTR bstrName = SysAllocString(OLESTR("class"));
+ getAttribute(bstrName, FALSE, &vValue);
+ SysFreeString(bstrName);
+
+ *p = vValue.bstrVal;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_id(BSTR v)
+{
+ nsCOMPtr<nsIDOMHTMLElement> domHtmlElmt = do_QueryInterface(mDOMNode);
+ if (!domHtmlElmt)
+ return E_UNEXPECTED;
+ USES_CONVERSION;
+ nsDependentString strID(OLE2CW(v));
+ if (FAILED(domHtmlElmt->SetId(strID)))
+ return E_FAIL;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_id(BSTR __RPC_FAR *p)
+{
+ if (p == NULL)
+ {
+ return E_INVALIDARG;
+ }
+
+ VARIANT vValue;
+ VariantInit(&vValue);
+ BSTR bstrName = SysAllocString(OLESTR("id"));
+ getAttribute(bstrName, FALSE, &vValue);
+ SysFreeString(bstrName);
+
+ *p = vValue.bstrVal;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_tagName(BSTR __RPC_FAR *p)
+{
+ if (p == NULL)
+ {
+ return E_INVALIDARG;
+ }
+
+ nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mDOMNode);
+ if (!element)
+ {
+ return E_UNEXPECTED;
+ }
+
+ nsAutoString tagName;
+ element->GetTagName(tagName);
+
+ USES_CONVERSION;
+ *p = SysAllocString(W2COLE(tagName.get()));
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_parentElement(IHTMLElement __RPC_FAR *__RPC_FAR *p)
+{
+ if (p == NULL)
+ {
+ return E_INVALIDARG;
+ }
+
+ *p = NULL;
+ if (mParent)
+ {
+ CIEHtmlElement *pElt = static_cast<CIEHtmlElement *>(mParent);
+ pElt->QueryInterface(IID_IHTMLElement, (void **) p);
+ }
+ else
+ {
+ nsCOMPtr<nsIDOMNode> parentNode;
+ mDOMNode->GetParentNode(getter_AddRefs(parentNode));
+ nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(parentNode);
+ if (domElement)
+ {
+ CComPtr<IUnknown> pNode;
+ HRESULT hr = CIEHtmlDomNode::FindOrCreateFromDOMNode(parentNode, &pNode);
+ if (FAILED(hr))
+ return hr;
+ if (FAILED(pNode->QueryInterface(IID_IHTMLElement, (void **) p)))
+ return E_UNEXPECTED;
+ }
+ }
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_style(IHTMLStyle __RPC_FAR *__RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_onhelp(VARIANT v)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_onhelp(VARIANT __RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_onclick(VARIANT v)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_onclick(VARIANT __RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_ondblclick(VARIANT v)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_ondblclick(VARIANT __RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_onkeydown(VARIANT v)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_onkeydown(VARIANT __RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_onkeyup(VARIANT v)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_onkeyup(VARIANT __RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_onkeypress(VARIANT v)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_onkeypress(VARIANT __RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_onmouseout(VARIANT v)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_onmouseout(VARIANT __RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_onmouseover(VARIANT v)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_onmouseover(VARIANT __RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_onmousemove(VARIANT v)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_onmousemove(VARIANT __RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_onmousedown(VARIANT v)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_onmousedown(VARIANT __RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_onmouseup(VARIANT v)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_onmouseup(VARIANT __RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_document(IDispatch __RPC_FAR *__RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_title(BSTR v)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_title(BSTR __RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_language(BSTR v)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_language(BSTR __RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_onselectstart(VARIANT v)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_onselectstart(VARIANT __RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::scrollIntoView(VARIANT varargStart)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::contains(IHTMLElement __RPC_FAR *pChild, VARIANT_BOOL __RPC_FAR *pfResult)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_sourceIndex(long __RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_recordNumber(VARIANT __RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_lang(BSTR v)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_lang(BSTR __RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_offsetLeft(long __RPC_FAR *p)
+{
+ nsCOMPtr<nsIDOMNSHTMLElement> nodeAsHTMLElement = do_QueryInterface(mDOMNode);
+ if (!nodeAsHTMLElement)
+ {
+ return E_NOINTERFACE;
+ }
+
+ PRInt32 nData;
+ nodeAsHTMLElement->GetOffsetLeft(&nData);
+ *p = nData;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_offsetTop(long __RPC_FAR *p)
+{
+ nsCOMPtr<nsIDOMNSHTMLElement> nodeAsHTMLElement = do_QueryInterface(mDOMNode);
+ if (!nodeAsHTMLElement)
+ {
+ return E_NOINTERFACE;
+ }
+
+ PRInt32 nData;
+ nodeAsHTMLElement->GetOffsetTop(&nData);
+ *p = nData;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_offsetWidth(long __RPC_FAR *p)
+{
+ nsCOMPtr<nsIDOMNSHTMLElement> nodeAsHTMLElement = do_QueryInterface(mDOMNode);
+ if (!nodeAsHTMLElement)
+ {
+ return E_NOINTERFACE;
+ }
+
+ PRInt32 nData;
+ nodeAsHTMLElement->GetOffsetWidth(&nData);
+ *p = nData;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_offsetHeight(long __RPC_FAR *p)
+{
+ nsCOMPtr<nsIDOMNSHTMLElement> nodeAsHTMLElement = do_QueryInterface(mDOMNode);
+ if (!nodeAsHTMLElement)
+ {
+ return E_NOINTERFACE;
+ }
+
+ PRInt32 nData;
+ nodeAsHTMLElement->GetOffsetHeight(&nData);
+ *p = nData;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_offsetParent(IHTMLElement __RPC_FAR *__RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_innerHTML(BSTR v)
+{
+ nsCOMPtr<nsIDOMNSHTMLElement> elementHTML = do_QueryInterface(mDOMNode);
+ if (!elementHTML)
+ {
+ return E_UNEXPECTED;
+ }
+
+ USES_CONVERSION;
+ nsAutoString innerHTML(OLE2W(v));
+ elementHTML->SetInnerHTML(innerHTML);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_innerHTML(BSTR __RPC_FAR *p)
+{
+ nsCOMPtr<nsIDOMNSHTMLElement> elementHTML = do_QueryInterface(mDOMNode);
+ if (!elementHTML)
+ {
+ return E_UNEXPECTED;
+ }
+
+ nsAutoString innerHTML;
+ elementHTML->GetInnerHTML(innerHTML);
+
+ USES_CONVERSION;
+ *p = SysAllocString(W2COLE(innerHTML.get()));
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_innerText(BSTR v)
+{
+ nsCOMPtr<nsIDOM3Node> node = do_QueryInterface(mDOMNode);
+ if (!node)
+ {
+ return E_UNEXPECTED;
+ }
+
+ USES_CONVERSION;
+ nsAutoString innerText(OLE2W(v));
+ node->SetTextContent(innerText);
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_innerText(BSTR __RPC_FAR *p)
+{
+ nsCOMPtr<nsIDOM3Node> node = do_QueryInterface(mDOMNode);
+ if (!node)
+ {
+ return E_UNEXPECTED;
+ }
+
+ nsAutoString innerText;
+ node->GetTextContent(innerText);
+
+ USES_CONVERSION;
+ *p = SysAllocString(W2COLE(innerText.get()));
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_outerHTML(BSTR v)
+{
+ nsresult rv;
+ nsCOMPtr<nsIDOMDocument> domDoc;
+ nsCOMPtr<nsIDOMRange> domRange;
+ nsCOMPtr<nsIDOMDocumentFragment> domDocFragment;
+
+ mDOMNode->GetOwnerDocument(getter_AddRefs(domDoc));
+ nsCOMPtr<nsIDOMDocumentRange> domDocRange = do_QueryInterface(domDoc);
+ if (!domDocRange)
+ return E_FAIL;
+ domDocRange->CreateRange(getter_AddRefs(domRange));
+ if (!domRange)
+ return E_FAIL;
+ if (domRange->SetStartBefore(mDOMNode))
+ return E_FAIL;
+ if (domRange->DeleteContents())
+ return E_FAIL;
+ nsAutoString outerHTML(OLE2W(v));
+ nsCOMPtr<nsIDOMNSRange> domNSRange = do_QueryInterface(domRange);
+ rv = domNSRange->CreateContextualFragment(outerHTML, getter_AddRefs(domDocFragment));
+ if (!domDocFragment)
+ return E_FAIL;
+ nsCOMPtr<nsIDOMNode> parentNode;
+ mDOMNode->GetParentNode(getter_AddRefs(parentNode));
+ nsCOMPtr<nsIDOMNode> domNode;
+ parentNode->ReplaceChild(domDocFragment, mDOMNode, getter_AddRefs(domNode));
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_outerHTML(BSTR __RPC_FAR *p)
+{
+ if (p == NULL)
+ {
+ return E_INVALIDARG;
+ }
+
+ *p = NULL;
+
+ nsresult rv;
+ nsAutoString outerHTML;
+ nsCOMPtr<nsIDOMDocument> domDoc;
+ nsCOMPtr<nsIDocumentEncoder> docEncoder;
+ nsCOMPtr<nsIDOMRange> domRange;
+
+ mDOMNode->GetOwnerDocument(getter_AddRefs(domDoc));
+ if (!domDoc)
+ return E_FAIL;
+
+ docEncoder = do_CreateInstance(NS_DOC_ENCODER_CONTRACTID_BASE "text/html");
+ NS_ENSURE_TRUE(docEncoder, NS_ERROR_FAILURE);
+ docEncoder->Init(domDoc, NS_LITERAL_STRING("text/html"),
+ nsIDocumentEncoder::OutputEncodeBasicEntities);
+ nsCOMPtr<nsIDOMDocumentRange> domDocRange = do_QueryInterface(domDoc);
+ if (!domDocRange)
+ return E_FAIL;
+ domDocRange->CreateRange(getter_AddRefs(domRange));
+ if (!domRange)
+ return E_FAIL;
+ rv = domRange->SelectNode(mDOMNode);
+ NS_ENSURE_SUCCESS(rv, rv);
+ docEncoder->SetRange(domRange);
+ docEncoder->EncodeToString(outerHTML);
+
+ USES_CONVERSION;
+ *p = SysAllocString(W2COLE(outerHTML.get()));
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_outerText(BSTR v)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_outerText(BSTR __RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::insertAdjacentHTML(BSTR where, BSTR html)
+{
+ nsresult rv;
+ nsCOMPtr<nsIDOMDocument> domDoc;
+ nsCOMPtr<nsIDOMRange> domRange;
+ nsCOMPtr<nsIDOMDocumentFragment> domDocFragment;
+
+ NS_ASSERTION(mDOMNode, "");
+ //Create a range:
+ mDOMNode->GetOwnerDocument(getter_AddRefs(domDoc));
+ nsCOMPtr<nsIDOMDocumentRange> domDocRange = do_QueryInterface(domDoc);
+ if (!domDocRange)
+ return E_FAIL;
+ domDocRange->CreateRange(getter_AddRefs(domRange));
+ if (!domRange)
+ return E_FAIL;
+ // Must position range first before calling CreateContextualFragment:
+ if (domRange->SetStartBefore(mDOMNode))
+ return E_FAIL;
+ USES_CONVERSION;
+ // Create doc fragment:
+ nsDependentString strAdjacentHTML(OLE2CW(html));
+ nsCOMPtr<nsIDOMNSRange> domNSRange = do_QueryInterface(domRange);
+ domNSRange->CreateContextualFragment(strAdjacentHTML, getter_AddRefs(domDocFragment));
+ if (!domDocFragment)
+ return E_FAIL;
+ if (_wcsicmp(OLE2CW(where), L"beforeBegin") == 0)
+ {
+ // Insert fragment immediately before us:
+ nsCOMPtr<nsIDOMNode> parentNode;
+ mDOMNode->GetParentNode(getter_AddRefs(parentNode));
+ nsCOMPtr<nsIDOMNode> dummyNode;
+ rv = parentNode->InsertBefore(domDocFragment, mDOMNode, getter_AddRefs(dummyNode));
+ return SUCCEEDED(rv)? S_OK: E_FAIL;
+ }
+ if (_wcsicmp(OLE2CW(where), L"afterEnd") == 0)
+ {
+ // Insert fragment immediately after us:
+ nsCOMPtr<nsIDOMNode> parentNode;
+ mDOMNode->GetParentNode(getter_AddRefs(parentNode));
+ nsCOMPtr<nsIDOMNode> dummyNode;
+ nsCOMPtr<nsIDOMNode> nextNode;
+ mDOMNode->GetNextSibling(getter_AddRefs(nextNode));
+ if (nextNode)
+ {
+ // Insert immediately before next node:
+ rv = parentNode->InsertBefore(domDocFragment, nextNode, getter_AddRefs(dummyNode));
+ }
+ else
+ {
+ // We are the last child, insert after us:
+ rv = parentNode->AppendChild(domDocFragment, getter_AddRefs(dummyNode));
+ }
+ return SUCCEEDED(rv)? S_OK: E_FAIL;
+ }
+ if (_wcsicmp(OLE2CW(where), L"afterBegin") == 0)
+ {
+ // Insert fragment immediately before first child:
+ nsCOMPtr<nsIDOMNode> firstChildNode;
+ mDOMNode->GetFirstChild(getter_AddRefs(firstChildNode));
+ if (!firstChildNode)
+ return E_FAIL; // IE fails when inserting into a tag that has no childs
+ nsCOMPtr<nsIDOMNode> dummyNode;
+ rv = mDOMNode->InsertBefore(domDocFragment, firstChildNode, getter_AddRefs(dummyNode));
+ return SUCCEEDED(rv)? S_OK: E_FAIL;
+ }
+ if (_wcsicmp(OLE2CW(where), L"beforeEnd") == 0)
+ {
+ // Insert fragment immediately as last child:
+ nsCOMPtr<nsIDOMNode> dummyNode;
+ rv = mDOMNode->AppendChild(domDocFragment, getter_AddRefs(dummyNode));
+ return SUCCEEDED(rv)? S_OK: E_FAIL;
+ }
+ return E_INVALIDARG;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::insertAdjacentText(BSTR where, BSTR text)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_parentTextEdit(IHTMLElement __RPC_FAR *__RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_isTextEdit(VARIANT_BOOL __RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::click(void)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_filters(IHTMLFiltersCollection __RPC_FAR *__RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_ondragstart(VARIANT v)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_ondragstart(VARIANT __RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::toString(BSTR __RPC_FAR *String)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_onbeforeupdate(VARIANT v)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_onbeforeupdate(VARIANT __RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_onafterupdate(VARIANT v)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_onafterupdate(VARIANT __RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_onerrorupdate(VARIANT v)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_onerrorupdate(VARIANT __RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_onrowexit(VARIANT v)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_onrowexit(VARIANT __RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_onrowenter(VARIANT v)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_onrowenter(VARIANT __RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_ondatasetchanged(VARIANT v)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_ondatasetchanged(VARIANT __RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_ondataavailable(VARIANT v)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_ondataavailable(VARIANT __RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_ondatasetcomplete(VARIANT v)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_ondatasetcomplete(VARIANT __RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_onfilterchange(VARIANT v)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_onfilterchange(VARIANT __RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_children(IDispatch __RPC_FAR *__RPC_FAR *p)
+{
+ // Validate parameters
+ if (p == NULL)
+ {
+ return E_INVALIDARG;
+ }
+
+ *p = NULL;
+
+ // Create a collection representing the children of this node
+ CIEHtmlElementCollectionInstance *pCollection = NULL;
+ HRESULT hr = GetChildren(&pCollection);
+ if (SUCCEEDED(hr))
+ {
+ *p = pCollection;
+ }
+
+ return hr;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_all(IDispatch __RPC_FAR *__RPC_FAR *p)
+{
+ // Validate parameters
+ if (p == NULL)
+ {
+ return E_INVALIDARG;
+ }
+
+ *p = NULL;
+
+ // TODO get ALL contained elements, not just the immediate children
+
+ CIEHtmlElementCollectionInstance *pCollection = NULL;
+ CIEHtmlElementCollection::CreateFromParentNode(this, TRUE, (CIEHtmlElementCollection **) &pCollection);
+ if (pCollection)
+ {
+ pCollection->AddRef();
+ *p = pCollection;
+ }
+
+ return S_OK;
+}
+
new file mode 100644
--- /dev/null
+++ b/embedding/browser/activex/src/common/IEHtmlElement.h
@@ -0,0 +1,173 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Adam Lock <adamlock@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+#ifndef IEHTMLELEMENT_H
+#define IEHTMLELEMENT_H
+
+#include "IEHtmlNode.h"
+#include "IEHtmlElementCollection.h"
+
+class CIEHtmlElement :
+ public CNode,
+ public IDispatchImpl<IHTMLElement, &IID_IHTMLElement, &LIBID_MSHTML>
+{
+public:
+ DECLARE_AGGREGATABLE(CIEHtmlElement)
+ CIEHtmlElement();
+ HRESULT FinalConstruct( );
+ void FinalRelease( );
+
+DECLARE_GET_CONTROLLING_UNKNOWN()
+
+protected:
+ virtual ~CIEHtmlElement();
+
+public:
+
+BEGIN_COM_MAP(CIEHtmlElement)
+ COM_INTERFACE_ENTRY2(IDispatch, IHTMLElement)
+ COM_INTERFACE_ENTRY(IHTMLElement)
+ COM_INTERFACE_ENTRY_AGGREGATE(__uuidof(IHTMLDOMNode), m_pNodeAgg)
+END_COM_MAP()
+
+ virtual HRESULT GetChildren(CIEHtmlElementCollectionInstance **ppCollection);
+ virtual HRESULT GetHtmlDomNode(CIEHtmlDomNode **ppHtmlDomNode);
+ virtual HRESULT SetDOMNode(nsIDOMNode *pDomNode);
+ virtual HRESULT SetParent(CNode *pParent);
+
+ // Implementation of IHTMLElement
+ virtual HRESULT STDMETHODCALLTYPE setAttribute(BSTR strAttributeName, VARIANT AttributeValue, LONG lFlags);
+ virtual HRESULT STDMETHODCALLTYPE getAttribute(BSTR strAttributeName, LONG lFlags, VARIANT __RPC_FAR *AttributeValue);
+ virtual HRESULT STDMETHODCALLTYPE removeAttribute(BSTR strAttributeName, LONG lFlags, VARIANT_BOOL __RPC_FAR *pfSuccess);
+ virtual HRESULT STDMETHODCALLTYPE put_className(BSTR v);
+ virtual HRESULT STDMETHODCALLTYPE get_className(BSTR __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE put_id(BSTR v);
+ virtual HRESULT STDMETHODCALLTYPE get_id(BSTR __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE get_tagName(BSTR __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE get_parentElement(IHTMLElement __RPC_FAR *__RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE get_style(IHTMLStyle __RPC_FAR *__RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE put_onhelp(VARIANT v);
+ virtual HRESULT STDMETHODCALLTYPE get_onhelp(VARIANT __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE put_onclick(VARIANT v);
+ virtual HRESULT STDMETHODCALLTYPE get_onclick(VARIANT __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE put_ondblclick(VARIANT v);
+ virtual HRESULT STDMETHODCALLTYPE get_ondblclick(VARIANT __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE put_onkeydown(VARIANT v);
+ virtual HRESULT STDMETHODCALLTYPE get_onkeydown(VARIANT __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE put_onkeyup(VARIANT v);
+ virtual HRESULT STDMETHODCALLTYPE get_onkeyup(VARIANT __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE put_onkeypress(VARIANT v);
+ virtual HRESULT STDMETHODCALLTYPE get_onkeypress(VARIANT __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE put_onmouseout(VARIANT v);
+ virtual HRESULT STDMETHODCALLTYPE get_onmouseout(VARIANT __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE put_onmouseover(VARIANT v);
+ virtual HRESULT STDMETHODCALLTYPE get_onmouseover(VARIANT __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE put_onmousemove(VARIANT v);
+ virtual HRESULT STDMETHODCALLTYPE get_onmousemove(VARIANT __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE put_onmousedown(VARIANT v);
+ virtual HRESULT STDMETHODCALLTYPE get_onmousedown(VARIANT __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE put_onmouseup(VARIANT v);
+ virtual HRESULT STDMETHODCALLTYPE get_onmouseup(VARIANT __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE get_document(IDispatch __RPC_FAR *__RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE put_title(BSTR v);
+ virtual HRESULT STDMETHODCALLTYPE get_title(BSTR __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE put_language(BSTR v);
+ virtual HRESULT STDMETHODCALLTYPE get_language(BSTR __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE put_onselectstart(VARIANT v);
+ virtual HRESULT STDMETHODCALLTYPE get_onselectstart(VARIANT __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE scrollIntoView(VARIANT varargStart);
+ virtual HRESULT STDMETHODCALLTYPE contains(IHTMLElement __RPC_FAR *pChild, VARIANT_BOOL __RPC_FAR *pfResult);
+ virtual HRESULT STDMETHODCALLTYPE get_sourceIndex(long __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE get_recordNumber(VARIANT __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE put_lang(BSTR v);
+ virtual HRESULT STDMETHODCALLTYPE get_lang(BSTR __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE get_offsetLeft(long __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE get_offsetTop(long __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE get_offsetWidth(long __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE get_offsetHeight(long __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE get_offsetParent(IHTMLElement __RPC_FAR *__RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE put_innerHTML(BSTR v);
+ virtual HRESULT STDMETHODCALLTYPE get_innerHTML(BSTR __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE put_innerText(BSTR v);
+ virtual HRESULT STDMETHODCALLTYPE get_innerText(BSTR __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE put_outerHTML(BSTR v);
+ virtual HRESULT STDMETHODCALLTYPE get_outerHTML(BSTR __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE put_outerText(BSTR v);
+ virtual HRESULT STDMETHODCALLTYPE get_outerText(BSTR __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE insertAdjacentHTML(BSTR where, BSTR html);
+ virtual HRESULT STDMETHODCALLTYPE insertAdjacentText(BSTR where, BSTR text);
+ virtual HRESULT STDMETHODCALLTYPE get_parentTextEdit(IHTMLElement __RPC_FAR *__RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE get_isTextEdit(VARIANT_BOOL __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE click(void);
+ virtual HRESULT STDMETHODCALLTYPE get_filters(IHTMLFiltersCollection __RPC_FAR *__RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE put_ondragstart(VARIANT v);
+ virtual HRESULT STDMETHODCALLTYPE get_ondragstart(VARIANT __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE toString(BSTR __RPC_FAR *String);
+ virtual HRESULT STDMETHODCALLTYPE put_onbeforeupdate(VARIANT v);
+ virtual HRESULT STDMETHODCALLTYPE get_onbeforeupdate(VARIANT __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE put_onafterupdate(VARIANT v);
+ virtual HRESULT STDMETHODCALLTYPE get_onafterupdate(VARIANT __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE put_onerrorupdate(VARIANT v);
+ virtual HRESULT STDMETHODCALLTYPE get_onerrorupdate(VARIANT __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE put_onrowexit(VARIANT v);
+ virtual HRESULT STDMETHODCALLTYPE get_onrowexit(VARIANT __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE put_onrowenter(VARIANT v);
+ virtual HRESULT STDMETHODCALLTYPE get_onrowenter(VARIANT __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE put_ondatasetchanged(VARIANT v);
+ virtual HRESULT STDMETHODCALLTYPE get_ondatasetchanged(VARIANT __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE put_ondataavailable(VARIANT v);
+ virtual HRESULT STDMETHODCALLTYPE get_ondataavailable(VARIANT __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE put_ondatasetcomplete(VARIANT v);
+ virtual HRESULT STDMETHODCALLTYPE get_ondatasetcomplete(VARIANT __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE put_onfilterchange(VARIANT v);
+ virtual HRESULT STDMETHODCALLTYPE get_onfilterchange(VARIANT __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE get_children(IDispatch __RPC_FAR *__RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE get_all(IDispatch __RPC_FAR *__RPC_FAR *p);
+
+protected:
+ IUnknown* m_pNodeAgg;
+};
+
+#define CIEHTMLELEMENT_INTERFACES \
+ COM_INTERFACE_ENTRY_IID(IID_IDispatch, IHTMLElement) \
+ COM_INTERFACE_ENTRY_IID(IID_IHTMLElement, IHTMLElement)
+
+typedef CComObject<CIEHtmlElement> CIEHtmlElementInstance;
+
+#endif
+
+
new file mode 100644
--- /dev/null
+++ b/embedding/browser/activex/src/common/IEHtmlElementCollection.cpp
@@ -0,0 +1,723 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Adam Lock <adamlock@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+#include "stdafx.h"
+
+#include "nsIDOMDocumentTraversal.h"
+#include "nsIDOMTreeWalker.h"
+#include "nsIDOMNodeFilter.h"
+#include "nsIDOMDocument.h"
+#include "nsIDOMHtmlElement.h"
+
+#include "IEHtmlElement.h"
+#include "IEHtmlElementCollection.h"
+
+CIEHtmlElementCollection::CIEHtmlElementCollection()
+{
+ mNodeList = NULL;
+ mNodeListCount = 0;
+ mNodeListCapacity = 0;
+}
+
+CIEHtmlElementCollection::~CIEHtmlElementCollection()
+{
+ // Clean the node list
+ if (mNodeList)
+ {
+ for (PRUint32 i = 0; i < mNodeListCount; i++)
+ {
+ IDispatch *pDisp = mNodeList[i];
+ if (pDisp)
+ {
+ pDisp->Release();
+ }
+ }
+ free(mNodeList);
+ mNodeList = NULL;
+ mNodeListCount = 0;
+ mNodeListCapacity = 0;
+ }
+}
+
+HRESULT CIEHtmlElementCollection::FindOrCreateIEElement(nsIDOMNode* domNode, IHTMLElement** pIHtmlElement)
+{
+ CComPtr<IUnknown> pNode;
+ HRESULT hr = CIEHtmlDomNode::FindOrCreateFromDOMNode(domNode, &pNode);
+ if (FAILED(hr))
+ return hr;
+ if (FAILED(pNode->QueryInterface(IID_IHTMLElement, (void**)pIHtmlElement)))
+ return E_UNEXPECTED;
+ return S_OK;
+}
+
+HRESULT CIEHtmlElementCollection::PopulateFromDOMHTMLCollection(nsIDOMHTMLCollection *pNodeList)
+{
+ if (pNodeList == nsnull)
+ {
+ return S_OK;
+ }
+
+ // Recurse through the children of the node (and the children of that)
+ // to populate the collection
+
+ // Iterate through items in list
+ PRUint32 length = 0;
+ pNodeList->GetLength(&length);
+ for (PRUint32 i = 0; i < length; i++)
+ {
+ // Get the next item from the list
+ nsCOMPtr<nsIDOMNode> childNode;
+ pNodeList->Item(i, getter_AddRefs(childNode));
+ if (!childNode)
+ {
+ // Empty node (unexpected, but try and carry on anyway)
+ NS_ERROR("Empty node");
+ continue;
+ }
+
+ // Skip nodes representing, text, attributes etc.
+ PRUint16 nodeType;
+ childNode->GetNodeType(&nodeType);
+ if (nodeType != nsIDOMNode::ELEMENT_NODE)
+ {
+ continue;
+ }
+
+ // Create an equivalent IE element
+ CComQIPtr<IHTMLElement> pHtmlElement;
+ HRESULT hr = FindOrCreateIEElement(childNode, &pHtmlElement);
+ if (FAILED(hr))
+ return hr;
+ AddNode(pHtmlElement);
+ }
+ return S_OK;
+}
+
+HRESULT CIEHtmlElementCollection::PopulateFromDOMNode(nsIDOMNode *aDOMNode, BOOL bRecurseChildren)
+{
+ if (aDOMNode == nsnull)
+ {
+ NS_ERROR("No dom node");
+ return E_INVALIDARG;
+ }
+
+ PRBool hasChildNodes = PR_FALSE;
+ aDOMNode->HasChildNodes(&hasChildNodes);
+ if (hasChildNodes)
+ {
+ if (bRecurseChildren)
+ {
+ nsresult rv;
+
+ // Search through parent nodes, looking for the DOM document
+ nsCOMPtr<nsIDOMNode> docAsNode = aDOMNode;
+ nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(aDOMNode);
+ while (!doc) {
+ nsCOMPtr<nsIDOMNode> parentNode;
+ docAsNode->GetParentNode(getter_AddRefs(parentNode));
+ docAsNode = parentNode;
+ if (!docAsNode)
+ {
+ return E_FAIL;
+ }
+ doc = do_QueryInterface(docAsNode);
+ }
+
+ // Walk the DOM
+ nsCOMPtr<nsIDOMDocumentTraversal> trav = do_QueryInterface(doc, &rv);
+ NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
+ nsCOMPtr<nsIDOMTreeWalker> walker;
+ rv = trav->CreateTreeWalker(aDOMNode,
+ nsIDOMNodeFilter::SHOW_ELEMENT,
+ nsnull, PR_TRUE, getter_AddRefs(walker));
+ NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
+
+ // We're not interested in the document node, so we always start
+ // with the next one, walking through them all to make the collection
+ nsCOMPtr<nsIDOMNode> currentNode;
+ walker->FirstChild(getter_AddRefs(currentNode));
+ while (currentNode)
+ {
+ // Create an equivalent IE element
+ CComQIPtr<IHTMLElement> pHtmlElement;
+ HRESULT hr = FindOrCreateIEElement(currentNode, &pHtmlElement);
+ if (FAILED(hr))
+ return hr;
+ AddNode(pHtmlElement);
+ walker->NextNode(getter_AddRefs(currentNode));
+ }
+ }
+ else
+ {
+ nsCOMPtr<nsIDOMNodeList> nodeList;
+ aDOMNode->GetChildNodes(getter_AddRefs(nodeList));
+ mDOMNodeList = nodeList;
+ }
+ }
+ return S_OK;
+}
+
+
+HRESULT CIEHtmlElementCollection::CreateFromDOMHTMLCollection(CNode *pParentNode, nsIDOMHTMLCollection *pNodeList, CIEHtmlElementCollection **pInstance)
+{
+ if (pInstance == NULL || pParentNode == NULL)
+ {
+ NS_ERROR("No instance or parent node");
+ return E_INVALIDARG;
+ }
+
+ // Get the DOM node from the parent node
+ if (!pParentNode->mDOMNode)
+ {
+ NS_ERROR("Parent has no DOM node");
+ return E_INVALIDARG;
+ }
+
+ *pInstance = NULL;
+
+ // Create a collection object
+ CIEHtmlElementCollectionInstance *pCollection = NULL;
+ CIEHtmlElementCollectionInstance::CreateInstance(&pCollection);
+ if (pCollection == NULL)
+ {
+ NS_ERROR("Could not create collection");
+ return E_OUTOFMEMORY;
+ }
+
+ // Initialise and populate the collection
+ pCollection->SetParent(pParentNode);
+ pCollection->PopulateFromDOMHTMLCollection(pNodeList);
+
+ *pInstance = pCollection;
+
+ return S_OK;
+}
+
+HRESULT CIEHtmlElementCollection::CreateFromParentNode(CNode *pParentNode, BOOL bRecurseChildren, CIEHtmlElementCollection **pInstance)
+{
+ if (pInstance == NULL || pParentNode == NULL)
+ {
+ NS_ERROR("No instance or parent node");
+ return E_INVALIDARG;
+ }
+
+ // Get the DOM node from the parent node
+ if (!pParentNode->mDOMNode)
+ {
+ NS_ERROR("Parent has no DOM node");
+ return E_INVALIDARG;
+ }
+
+ *pInstance = NULL;
+
+ // Create a collection object
+ CIEHtmlElementCollectionInstance *pCollection = NULL;
+ CIEHtmlElementCollectionInstance::CreateInstance(&pCollection);
+ if (pCollection == NULL)
+ {
+ NS_ERROR("Could not create collection");
+ return E_OUTOFMEMORY;
+ }
+
+ // Initialise and populate the collection
+ pCollection->SetParent(pParentNode);
+ pCollection->PopulateFromDOMNode(pParentNode->mDOMNode, bRecurseChildren);
+
+ *pInstance = pCollection;
+
+ return S_OK;
+}
+
+
+HRESULT CIEHtmlElementCollection::AddNode(IDispatch *pNode)
+{
+ if (pNode == NULL)
+ {
+ NS_ERROR("No node");
+ return E_INVALIDARG;
+ }
+
+ const PRUint32 c_NodeListResizeBy = 100;
+
+ if (mNodeList == NULL)
+ {
+ mNodeListCapacity = c_NodeListResizeBy;
+ mNodeList = (IDispatch **) malloc(sizeof(IDispatch *) * mNodeListCapacity);
+ mNodeListCount = 0;
+ }
+ else if (mNodeListCount == mNodeListCapacity)
+ {
+ mNodeListCapacity += c_NodeListResizeBy;
+ mNodeList = (IDispatch **) realloc(mNodeList, sizeof(IDispatch *) * mNodeListCapacity);
+ }
+
+ if (mNodeList == NULL)
+ {
+ NS_ERROR("Could not realloc node list");
+ return E_OUTOFMEMORY;
+ }
+
+ pNode->AddRef();
+ mNodeList[mNodeListCount++] = pNode;
+
+ return S_OK;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// IHTMLElementCollection methods
+
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElementCollection::toString(BSTR __RPC_FAR *String)
+{
+ if (String == NULL)
+ {
+ return E_INVALIDARG;
+ }
+ *String = SysAllocString(OLESTR("ElementCollection"));
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElementCollection::put_length(long v)
+{
+ // What is the point of this method?
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElementCollection::get_length(long __RPC_FAR *p)
+{
+ if (p == NULL)
+ {
+ return E_INVALIDARG;
+ }
+
+ // Return the size of the collection
+ if (mDOMNodeList)
+ {
+ // Count the number of elements in the list
+ PRUint32 elementCount = 0;
+ PRUint32 length = 0;
+ mDOMNodeList->GetLength(&length);
+ for (PRUint32 i = 0; i < length; i++)
+ {
+ // Get the next item from the list
+ nsCOMPtr<nsIDOMNode> childNode;
+ mDOMNodeList->Item(i, getter_AddRefs(childNode));
+ if (!childNode)
+ {
+ // Empty node (unexpected, but try and carry on anyway)
+ NS_ERROR("Empty node");
+ continue;
+ }
+
+ // Only count elements
+ PRUint16 nodeType;
+ childNode->GetNodeType(&nodeType);
+ if (nodeType == nsIDOMNode::ELEMENT_NODE)
+ {
+ elementCount++;
+ }
+ }
+ *p = elementCount;
+ }
+ else
+ {
+ *p = mNodeListCount;
+ }
+ return S_OK;
+}
+
+typedef CComObject<CComEnum<IEnumVARIANT, &IID_IEnumVARIANT, VARIANT, _Copy<VARIANT> > > CComEnumVARIANT;
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElementCollection::get__newEnum(IUnknown __RPC_FAR *__RPC_FAR *p)
+{
+ TRACE_METHOD(CIEHtmlElementCollection::get__newEnum);
+
+ if (p == NULL)
+ {
+ return E_INVALIDARG;
+ }
+
+ *p = NULL;
+
+ // Create a new IEnumVARIANT object
+ CComEnumVARIANT *pEnumVARIANT = NULL;
+ CComEnumVARIANT::CreateInstance(&pEnumVARIANT);
+ if (pEnumVARIANT == NULL)
+ {
+ NS_ERROR("Could not creat Enum");
+ return E_OUTOFMEMORY;
+ }
+
+ int nObject = 0;
+ long nObjects = 0;
+ get_length(&nObjects);
+
+ // Create an array of VARIANTs
+ VARIANT *avObjects = new VARIANT[nObjects];
+ if (avObjects == NULL)
+ {
+ NS_ERROR("Could not create variant array");
+ return E_OUTOFMEMORY;
+ }
+
+ if (mDOMNodeList)
+ {
+ // Fill the variant array with elements from the DOM node list
+ PRUint32 length = 0;
+ mDOMNodeList->GetLength(&length);
+ for (PRUint32 i = 0; i < length; i++)
+ {
+ // Get the next item from the list
+ nsCOMPtr<nsIDOMNode> childNode;
+ mDOMNodeList->Item(i, getter_AddRefs(childNode));
+ if (!childNode)
+ {
+ // Empty node (unexpected, but try and carry on anyway)
+ NS_ERROR("Could not get node");
+ continue;
+ }
+
+ // Skip nodes representing, text, attributes etc.
+ PRUint16 nodeType;
+ childNode->GetNodeType(&nodeType);
+ if (nodeType != nsIDOMNode::ELEMENT_NODE)
+ {
+ continue;
+ }
+
+ // Store the element in the array
+ CComQIPtr<IHTMLElement> pHtmlElement;
+ HRESULT hr = FindOrCreateIEElement(childNode, &pHtmlElement);
+ if (FAILED(hr))
+ return hr;
+ VARIANT *pVariant = &avObjects[nObject++];
+ VariantInit(pVariant);
+ pVariant->vt = VT_DISPATCH;
+ pHtmlElement->QueryInterface(IID_IDispatch, (void **) &pVariant->pdispVal);
+ }
+ }
+ else
+ {
+ // Copy the contents of the collection to the array
+ for (nObject = 0; nObject < nObjects; nObject++)
+ {
+ VARIANT *pVariant = &avObjects[nObject];
+ IDispatch *pDispObject = mNodeList[nObject];
+ VariantInit(pVariant);
+ pVariant->vt = VT_DISPATCH;
+ pVariant->pdispVal = pDispObject;
+ pDispObject->AddRef();
+ }
+ }
+
+ // Copy the variants to the enumeration object
+ pEnumVARIANT->Init(&avObjects[0], &avObjects[nObjects], NULL, AtlFlagCopy);
+
+ // Cleanup the array
+ for (nObject = 0; nObject < nObjects; nObject++)
+ {
+ VARIANT *pVariant = &avObjects[nObject];
+ VariantClear(pVariant);
+ }
+ delete []avObjects;
+
+ return pEnumVARIANT->QueryInterface(IID_IUnknown, (void**) p);
+}
+
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElementCollection::item(VARIANT name, VARIANT index, IDispatch __RPC_FAR *__RPC_FAR *pdisp)
+{
+ TRACE_METHOD(CIEHtmlElementCollection::item);
+
+ if (pdisp == NULL)
+ {
+ return E_INVALIDARG;
+ }
+
+ *pdisp = NULL;
+
+ // Parameter name is either a string or a number
+
+ PRBool searchForName = PR_FALSE;
+ nsAutoString nameToSearch;
+ PRInt32 idxForSearch = 0;
+
+ if (name.vt == VT_BSTR && name.bstrVal && wcslen(name.bstrVal) > 0)
+ {
+ nameToSearch.Assign(name.bstrVal);
+ searchForName = PR_TRUE;
+ }
+ else switch (name.vt)
+ {
+ case VT_UI1:
+ case VT_UI2:
+ case VT_UI4:
+ case VT_I1:
+ case VT_I2:
+ case VT_I1 | VT_BYREF:
+ case VT_I2 | VT_BYREF:
+ // Coerce the variant into a long
+ if (FAILED(VariantChangeType(&name, &name, 0, VT_I4)))
+ {
+ return E_INVALIDARG;
+ }
+ // Fall through
+ case VT_I4:
+ idxForSearch = name.lVal;
+ if (idxForSearch < 0)
+ return E_INVALIDARG;
+ break;
+ default:
+ // Unknown arg.
+ // As per documentation, no attempt to be lenient with crappy clients
+ // for the time being.
+ return E_INVALIDARG;
+ }
+
+ CIEHtmlElementCollectionInstance* pCollection = NULL;
+
+ if (mDOMNodeList)
+ {
+ CComQIPtr<IHTMLElement> pHtmlElement;
+ // Search for the Nth element in the list
+ PRUint32 elementCount = 0;
+ PRUint32 length = 0;
+ mDOMNodeList->GetLength(&length);
+ for (PRUint32 i = 0; i < length; i++)
+ {
+ // Get the next item from the list
+ nsCOMPtr<nsIDOMNode> childNode;
+ mDOMNodeList->Item(i, getter_AddRefs(childNode));
+ if (!childNode)
+ {
+ // Empty node (unexpected, but try and carry on anyway)
+ NS_ERROR("Could not get node");
+ continue;
+ }
+
+ // Skip nodes representing, text, attributes etc.
+ nsCOMPtr<nsIDOMElement> nodeAsElement = do_QueryInterface(childNode);
+ if (!nodeAsElement)
+ {
+ continue;
+ }
+
+ // Have we found the element we need?
+ PRBool grabThisNode = PR_FALSE;
+ if (searchForName)
+ {
+ nsCOMPtr<nsIDOMHTMLElement> nodeAsHtmlElement = do_QueryInterface(childNode);
+ if (nodeAsHtmlElement)
+ {
+ NS_NAMED_LITERAL_STRING(nameAttr, "name");
+ nsAutoString nodeName;
+ nsAutoString nodeId;
+ nodeAsHtmlElement->GetAttribute(nameAttr, nodeName);
+ nodeAsHtmlElement->GetId(nodeId);
+ if (nodeName.Equals(nameToSearch) || nodeId.Equals(nameToSearch))
+ {
+ grabThisNode = PR_TRUE;
+ }
+ }
+ }
+ else if (elementCount == idxForSearch)
+ {
+ grabThisNode = PR_TRUE;
+ }
+
+ if (grabThisNode)
+ {
+ if (pHtmlElement)
+ {
+ if (pCollection == NULL)
+ CIEHtmlElementCollectionInstance::CreateInstance(&pCollection);
+ // Add existing to collection
+ pCollection->AddNode(pHtmlElement);
+ }
+ // Create new element:
+ HRESULT hr = FindOrCreateIEElement(childNode, &pHtmlElement);
+ if (FAILED(hr))
+ return hr;
+ ((CIEHtmlElement*)pHtmlElement.p)->SetParent(mParent);
+ }
+ elementCount++;
+ }
+ // Return the element or collection :
+ if (pCollection != NULL)
+ {
+ // Add last created element to collection
+ pCollection->AddNode(pHtmlElement);
+ pCollection->QueryInterface(IID_IDispatch, (void **) pdisp);
+ }
+ else if (pHtmlElement != NULL)
+ pHtmlElement->QueryInterface(IID_IDispatch, (void **) pdisp);
+ }
+ else
+ {
+ if (searchForName)
+ {
+ CComPtr<IHTMLElement> element = NULL;
+ for (PRUint32 i = 0; i < mNodeListCount; i++)
+ {
+ CComQIPtr<IHTMLElement> currElement = mNodeList[i];
+ if (currElement.p)
+ {
+ CComVariant elementName;
+ CComBSTR elementId;
+ currElement->get_id(&elementId);
+ currElement->getAttribute(L"name", 0, &elementName);
+ if ((elementId && wcscmp(elementId, name.bstrVal) == 0) ||
+ (elementName.vt == VT_BSTR && elementName.bstrVal &&
+ wcscmp(elementName.bstrVal, name.bstrVal) == 0))
+ {
+ if (element != NULL)
+ {
+ if (!pCollection)
+ CIEHtmlElementCollectionInstance::CreateInstance(&pCollection);
+ pCollection->AddNode(element);
+ }
+ element = currElement;
+ }
+ }
+ }
+ // Return the element or collection :
+ if (pCollection != NULL)
+ {
+ pCollection->AddNode(element);
+ pCollection->QueryInterface(IID_IDispatch, (void **) pdisp);
+ }
+ else if (element != NULL)
+ element->QueryInterface(IID_IDispatch, (void **) pdisp);
+ }
+ else
+ {
+ // Test for stupid values
+ if (idxForSearch >= mNodeListCount)
+ {
+ return E_INVALIDARG;
+ }
+
+ *pdisp = NULL;
+ IDispatch *pNode = mNodeList[idxForSearch];
+ if (pNode == NULL)
+ {
+ NS_ERROR("No node");
+ return E_UNEXPECTED;
+ }
+ pNode->QueryInterface(IID_IDispatch, (void **) pdisp);
+ }
+ }
+
+ // Note: As per docs S_OK is fine even if no node is returned
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlElementCollection::tags(VARIANT tagName, IDispatch __RPC_FAR *__RPC_FAR *pdisp)
+{
+ if (pdisp == NULL || tagName.vt != VT_BSTR)
+ {
+ return E_INVALIDARG;
+ }
+
+ *pdisp = NULL;
+
+ CIEHtmlElementCollectionInstance* pCollection = NULL;
+ CIEHtmlElementCollectionInstance::CreateInstance(&pCollection);
+ if (mNodeList)
+ {
+ for (PRUint32 i = 0; i < mNodeListCount; i++)
+ {
+ CComQIPtr<IHTMLElement> element = mNodeList[i];
+ if (element.p)
+ {
+ CComBSTR elementTagName;
+ element->get_tagName(&elementTagName);
+ if (elementTagName && _wcsicmp(elementTagName, tagName.bstrVal) == 0)
+ pCollection->AddNode(element);
+ }
+ }
+ pCollection->QueryInterface(IID_IDispatch, (void**)pdisp);
+ return S_OK;
+ }
+ else if (mDOMNodeList)
+ {
+ PRUint32 length = 0;
+ mDOMNodeList->GetLength(&length);
+ for (PRUint32 i = 0; i < length; i++)
+ {
+ // Get the next item from the list
+ nsCOMPtr<nsIDOMNode> childNode;
+ mDOMNodeList->Item(i, getter_AddRefs(childNode));
+ if (!childNode)
+ {
+ // Empty node (unexpected, but try and carry on anyway)
+ NS_ERROR("Could not get node");
+ continue;
+ }
+
+ // Skip nodes representing, text, attributes etc.
+ nsCOMPtr<nsIDOMElement> nodeAsElement = do_QueryInterface(childNode);
+ if (!nodeAsElement)
+ {
+ continue;
+ }
+
+ nsCOMPtr<nsIDOMHTMLElement> nodeAsHtmlElement = do_QueryInterface(childNode);
+ if (nodeAsHtmlElement)
+ {
+ nsAutoString elementTagName;
+ nodeAsHtmlElement->GetTagName(elementTagName);
+ if (_wcsicmp(elementTagName.get(), OLE2CW(tagName.bstrVal)) == 0)
+ {
+ CComQIPtr<IHTMLElement> pHtmlElement;
+ HRESULT hr = FindOrCreateIEElement(childNode, &pHtmlElement);
+ if (FAILED(hr))
+ return hr;
+ //Add to collection :
+ pCollection->AddNode(pHtmlElement);
+ }
+ }
+ }
+ pCollection->QueryInterface(IID_IDispatch, (void**)pdisp);
+ return S_OK;
+ }
+ return E_UNEXPECTED;
+}
+
new file mode 100644
--- /dev/null
+++ b/embedding/browser/activex/src/common/IEHtmlElementCollection.h
@@ -0,0 +1,99 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Adam Lock <adamlock@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+#ifndef IEHTMLNODECOLLECTION_H
+#define IEHTMLNODECOLLECTION_H
+
+#include "nsIDOMHTMLCollection.h"
+#include "nsIDOMNodeList.h"
+
+#include "IEHtmlNode.h"
+
+class CIEHtmlElement;
+
+class CIEHtmlElementCollection :
+ public CNode,
+ public IDispatchImpl<IHTMLElementCollection, &IID_IHTMLElementCollection, &LIBID_MSHTML>
+{
+private:
+ // Hold a DOM node list
+ nsCOMPtr<nsIDOMNodeList> mDOMNodeList;
+ // Or hold a static collection
+ IDispatch **mNodeList;
+ PRUint32 mNodeListCount;
+ PRUint32 mNodeListCapacity;
+
+public:
+ CIEHtmlElementCollection();
+
+protected:
+ virtual ~CIEHtmlElementCollection();
+ virtual HRESULT FindOrCreateIEElement(nsIDOMNode* domNode, IHTMLElement** pIHtmlElement);
+
+public:
+ // Adds a node to the collection
+ virtual HRESULT AddNode(IDispatch *pNode);
+
+ virtual HRESULT PopulateFromDOMHTMLCollection(nsIDOMHTMLCollection *pNodeList);
+
+ // Populates the collection with items from the DOM node
+ virtual HRESULT PopulateFromDOMNode(nsIDOMNode *pIDOMNode, BOOL bRecurseChildren);
+
+ // Helper method creates a collection from a parent node
+ static HRESULT CreateFromParentNode(CNode *pParentNode, BOOL bRecurseChildren, CIEHtmlElementCollection **pInstance);
+
+ // Helper method creates a collection from the specified HTML collection
+ static HRESULT CreateFromDOMHTMLCollection(CNode *pParentNode, nsIDOMHTMLCollection *pNodeList, CIEHtmlElementCollection **pInstance);
+
+
+BEGIN_COM_MAP(CIEHtmlElementCollection)
+ COM_INTERFACE_ENTRY(IDispatch)
+ COM_INTERFACE_ENTRY(IHTMLElementCollection)
+END_COM_MAP()
+
+ // IHTMLElementCollection methods
+ virtual HRESULT STDMETHODCALLTYPE toString(BSTR __RPC_FAR *String);
+ virtual HRESULT STDMETHODCALLTYPE put_length(long v);
+ virtual HRESULT STDMETHODCALLTYPE get_length(long __RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE get__newEnum(IUnknown __RPC_FAR *__RPC_FAR *p);
+ virtual HRESULT STDMETHODCALLTYPE item(VARIANT name, VARIANT index, IDispatch __RPC_FAR *__RPC_FAR *pdisp);
+ virtual HRESULT STDMETHODCALLTYPE tags(VARIANT tagName, IDispatch __RPC_FAR *__RPC_FAR *pdisp);
+};
+
+typedef CComObject<CIEHtmlElementCollection> CIEHtmlElementCollectionInstance;
+
+#endif
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/embedding/browser/activex/src/common/IEHtmlNode.cpp
@@ -0,0 +1,381 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Adam Lock <adamlock@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "stdafx.h"
+#include "IEHtmlNode.h"
+
+#include "plhash.h"
+
+static PLHashTable *g_NodeLookupTable;
+
+static PLHashNumber HashFunction(const void *key)
+{
+ return (PRUint32) key;
+}
+
+PRIntn HashComparator(const void *v1, const void *v2)
+{
+ if (v1 == v2)
+ {
+ return 1;
+ }
+ return 0;
+}
+
+
+CNode::CNode() :
+ mParent(NULL),mDOMNode(NULL)
+{
+}
+
+CNode::~CNode()
+{
+}
+
+
+HRESULT CNode::SetParent(CNode *pParent)
+{
+ mParent = pParent;
+ return S_OK;
+}
+
+
+HRESULT CNode::FindFromDOMNode(nsIDOMNode *pIDOMNode, CNode **pNode)
+{
+ if (pIDOMNode == nsnull)
+ {
+ return E_FAIL;
+ }
+
+ if (g_NodeLookupTable == NULL)
+ {
+ return E_FAIL;
+ }
+
+ nsCOMPtr<nsISupports> nodeAsSupports = do_QueryInterface(pIDOMNode);
+ *pNode = (CNode *) PL_HashTableLookup(g_NodeLookupTable, nodeAsSupports);
+
+ return S_OK;
+}
+
+HRESULT CNode::SetDOMNode(nsIDOMNode *pIDOMNode)
+{
+ if (pIDOMNode)
+ {
+ if (g_NodeLookupTable == NULL)
+ {
+ g_NodeLookupTable = PL_NewHashTable(123, HashFunction, HashComparator, HashComparator, NULL, NULL);
+ }
+
+ mDOMNode = pIDOMNode;
+ nsCOMPtr<nsISupports> nodeAsSupports= do_QueryInterface(mDOMNode);
+ PL_HashTableAdd(g_NodeLookupTable, nodeAsSupports, this);
+ }
+ else if (mDOMNode)
+ {
+ // Remove the entry from the hashtable
+ nsCOMPtr<nsISupports> nodeAsSupports = do_QueryInterface(mDOMNode);
+ PL_HashTableRemove(g_NodeLookupTable, nodeAsSupports);
+ mDOMNode = nsnull;
+
+ if (g_NodeLookupTable->nentries == 0)
+ {
+ PL_HashTableDestroy(g_NodeLookupTable);
+ g_NodeLookupTable = NULL;
+ }
+ }
+ return S_OK;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// CIEHtmlDomNode methods
+
+#include "nsIDOMHTMLButtonElement.h"
+#include "nsIDOMHTMLElement.h"
+
+#include "IEHtmlButtonElement.h"
+#include "IEHtmlElement.h"
+
+CIEHtmlDomNode::CIEHtmlDomNode()
+{
+}
+
+CIEHtmlDomNode::~CIEHtmlDomNode()
+{
+ SetDOMNode(nsnull);
+}
+
+#define CREATE_FROM_DOMNODE(nsInterface, WrapperType, errorMsg) \
+ nsCOMPtr<nsInterface> domNode_##nsInterface = do_QueryInterface(pIDOMNode); \
+ if (domNode_##nsInterface) \
+ { \
+ WrapperType *pWrapper = NULL; \
+ WrapperType::CreateInstance(&pWrapper); \
+ if (!pWrapper) \
+ { \
+ NS_ERROR(errorMsg); \
+ return E_OUTOFMEMORY; \
+ } \
+ if (FAILED(pWrapper->QueryInterface(IID_IUnknown, (void**)pNode))) \
+ return E_UNEXPECTED; \
+ pWrapper->SetDOMNode(pIDOMNode); \
+ return S_OK; \
+ }
+
+
+HRESULT CIEHtmlDomNode::CreateFromDOMNode(nsIDOMNode *pIDOMNode, IUnknown **pNode)
+{
+ CREATE_FROM_DOMNODE(nsIDOMHTMLButtonElement, CIEHtmlButtonElementInstance, "")
+ CREATE_FROM_DOMNODE(nsIDOMHTMLElement, CIEHtmlElementInstance, "Could not create element")
+ CREATE_FROM_DOMNODE(nsIDOMNode, CIEHtmlDomNodeInstance, "Could not create node")
+ return E_FAIL;
+}
+
+HRESULT CIEHtmlDomNode::FindFromDOMNode(nsIDOMNode *pIDOMNode, IUnknown **pNode)
+{
+ if (pIDOMNode == nsnull)
+ {
+ return E_FAIL;
+ }
+
+ if (g_NodeLookupTable == NULL)
+ {
+ return E_FAIL;
+ }
+
+ nsCOMPtr<nsISupports> nodeAsSupports = do_QueryInterface(pIDOMNode);
+ *pNode = (IUnknown *) PL_HashTableLookup(g_NodeLookupTable, nodeAsSupports);
+
+ return S_OK;
+}
+
+HRESULT CIEHtmlDomNode::FindOrCreateFromDOMNode(nsIDOMNode *pIDOMNode, IUnknown **pNode)
+{
+ FindFromDOMNode(pIDOMNode,pNode);
+
+ if (*pNode)
+ {
+ (*pNode)->AddRef();
+ return S_OK;
+ }
+
+ HRESULT hr = CreateFromDOMNode(pIDOMNode, pNode);
+ if SUCCEEDED(hr)
+ return S_OK;
+ return hr;
+}
+
+HRESULT CIEHtmlDomNode::SetDOMNode(nsIDOMNode *pIDOMNode)
+{
+ if (pIDOMNode)
+ {
+ if (g_NodeLookupTable == NULL)
+ {
+ g_NodeLookupTable = PL_NewHashTable(123, HashFunction, HashComparator, HashComparator, NULL, NULL);
+ }
+
+ mDOMNode = pIDOMNode;
+ nsCOMPtr<nsISupports> nodeAsSupports= do_QueryInterface(mDOMNode);
+ PL_HashTableAdd(g_NodeLookupTable, nodeAsSupports, (IUnknown *)this );
+ }
+ else if (mDOMNode)
+ {
+ // Remove the entry from the hashtable
+ nsCOMPtr<nsISupports> nodeAsSupports = do_QueryInterface(mDOMNode);
+ PL_HashTableRemove(g_NodeLookupTable, nodeAsSupports);
+ mDOMNode = nsnull;
+
+ if (g_NodeLookupTable->nentries == 0)
+ {
+ PL_HashTableDestroy(g_NodeLookupTable);
+ g_NodeLookupTable = NULL;
+ }
+ }
+ return S_OK;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// IHTMLDOMNode methods
+
+#define SIB_NODE_GET_NUMERIC(function,numtype) \
+{ \
+ if (!p) return E_INVALIDARG; \
+ if (!mDOMNode) return E_UNEXPECTED; \
+ numtype nData; \
+ HRESULT rc = mDOMNode->function(&nData); \
+ *p=nData; \
+ return rc; \
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::get_nodeType(long __RPC_FAR *p)
+ SIB_NODE_GET_NUMERIC(GetNodeType,PRUint16)
+
+#define SIB_NODE_GET_ELEMENT(function,fn_elt_type) \
+{ \
+ return E_NOTIMPL; \
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::get_parentNode(IHTMLDOMNode __RPC_FAR *__RPC_FAR *p)
+ SIB_NODE_GET_ELEMENT(GetParentNode,nsIDOMNode)
+
+HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::hasChildNodes(VARIANT_BOOL __RPC_FAR *p)
+ SIB_NODE_GET_NUMERIC(HasChildNodes,PRBool)
+
+#define SIB_STD_NOTIMPL \
+{ \
+ return E_NOTIMPL; \
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::get_childNodes(IDispatch __RPC_FAR *__RPC_FAR *p)
+ SIB_STD_NOTIMPL
+
+HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::get_attributes(IDispatch __RPC_FAR *__RPC_FAR *p)
+ SIB_STD_NOTIMPL
+
+HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::insertBefore(IHTMLDOMNode __RPC_FAR *newChild,
+ VARIANT refChild,
+ IHTMLDOMNode __RPC_FAR *__RPC_FAR *node)
+ SIB_STD_NOTIMPL
+
+HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::removeChild(
+ IHTMLDOMNode __RPC_FAR *oldChild,
+ IHTMLDOMNode __RPC_FAR *__RPC_FAR *node)
+ SIB_STD_NOTIMPL
+
+HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::replaceChild(
+ IHTMLDOMNode __RPC_FAR *newChild,
+ IHTMLDOMNode __RPC_FAR *oldChild,
+ IHTMLDOMNode __RPC_FAR *__RPC_FAR *node)
+ SIB_STD_NOTIMPL
+
+HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::cloneNode(
+ VARIANT_BOOL fDeep,
+ IHTMLDOMNode __RPC_FAR *__RPC_FAR *clonedNode)
+ SIB_STD_NOTIMPL
+
+HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::removeNode(
+ VARIANT_BOOL fDeep,
+ IHTMLDOMNode __RPC_FAR *__RPC_FAR *removed)
+ SIB_STD_NOTIMPL
+
+HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::swapNode(
+ IHTMLDOMNode __RPC_FAR *otherNode,
+ IHTMLDOMNode __RPC_FAR *__RPC_FAR *swappedNode)
+ SIB_STD_NOTIMPL
+
+HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::replaceNode(
+ IHTMLDOMNode __RPC_FAR *replacement,
+ IHTMLDOMNode __RPC_FAR *__RPC_FAR *replaced)
+ SIB_STD_NOTIMPL
+
+HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::appendChild(IHTMLDOMNode *newChild, IHTMLDOMNode **node)
+{
+ if (!newChild || !node)
+ return E_INVALIDARG;
+ *node = NULL;
+ if (!mDOMNode)
+ return E_UNEXPECTED;
+ nsCOMPtr<nsIDOMNode> domNode;
+ nsresult rv = mDOMNode->AppendChild(((CIEHtmlDomNode*)newChild)->mDOMNode, getter_AddRefs(domNode));
+ if (NS_FAILED(rv))
+ return E_FAIL;
+ // Create com object:
+ CComPtr<IUnknown> pNode = NULL;
+ HRESULT hr = CIEHtmlDomNode::FindOrCreateFromDOMNode(domNode, &pNode);
+ if (FAILED(hr))
+ return hr;
+ if (FAILED(pNode->QueryInterface(__uuidof(IHTMLDOMNode), (void**)node)))
+ return E_UNEXPECTED;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::get_nodeName(BSTR __RPC_FAR *p)
+{
+ if (!mDOMNode) return E_UNEXPECTED;
+ nsString szTagName;
+ HRESULT rc = mDOMNode->GetNodeName(szTagName);
+ USES_CONVERSION;
+ *p = SysAllocString(W2COLE(ToNewUnicode(szTagName)));
+ return rc;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::put_nodeValue(VARIANT p)
+{
+ if (!mDOMNode) return E_UNEXPECTED;
+ CComVariant vValue;
+ if (FAILED(vValue.ChangeType(VT_BSTR, &p))) {
+ return E_INVALIDARG;
+ }
+ nsString szValue(OLE2W(vValue.bstrVal));
+ if (!mDOMNode->SetNodeValue(szValue))
+ return E_FAIL;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::get_nodeValue(VARIANT __RPC_FAR *p)
+{
+ if (p == NULL) {
+ return E_INVALIDARG;
+ }
+ if (!mDOMNode) return E_UNEXPECTED;
+ nsString szValue;
+ nsresult nr = mDOMNode->GetNodeValue(szValue);
+ if (nr == NS_OK) {
+ USES_CONVERSION;
+ p->vt = VT_BSTR;
+ p->bstrVal = SysAllocString(W2COLE(ToNewUnicode(szValue)));
+ return S_OK;
+ }
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::get_firstChild(IHTMLDOMNode __RPC_FAR *__RPC_FAR *p)
+ SIB_NODE_GET_ELEMENT(GetFirstChild,nsIDOMNode)
+
+HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::get_lastChild(IHTMLDOMNode __RPC_FAR *__RPC_FAR *p)
+ SIB_NODE_GET_ELEMENT(GetLastChild,nsIDOMNode)
+
+HRESULT STDMETHODCALLTYPE CIEHtmlDomNode::get_previousSibling(IHTMLDOMNode __RPC_FAR *__RPC_FAR *p)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CIEHtmlDomN