author | Ehsan Akhgari <ehsan@mozilla.com> |
Tue, 14 Jun 2011 00:17:10 -0400 | |
changeset 71035 | 436671b3bee7d586449330a470664b029042bd01 |
parent 71034 | 6eb2bcc24f7621ec8bad4636dcdd1976b6e197b8 |
child 71036 | 09428adfd4a838f2bbc29813b9cca2082ae7b0ea |
push id | 58 |
push user | mlamouri@mozilla.com |
push date | Tue, 14 Jun 2011 14:14:36 +0000 |
treeherder | mozilla-inbound@3a4b05b2df87 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
milestone | 7.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- 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: