diff options
author | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-27 00:20:51 +0000 |
---|---|---|
committer | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-27 00:20:51 +0000 |
commit | f5b16fed647e941aa66933178da85db2860d639b (patch) | |
tree | f00e9856c04aad3b558a140955e7674add33f051 /webkit/activex_shim/web_activex_site.cc | |
parent | 920c091ac3ee15079194c82ae8a7a18215f3f23c (diff) | |
download | chromium_src-f5b16fed647e941aa66933178da85db2860d639b.zip chromium_src-f5b16fed647e941aa66933178da85db2860d639b.tar.gz chromium_src-f5b16fed647e941aa66933178da85db2860d639b.tar.bz2 |
Add webkit to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/activex_shim/web_activex_site.cc')
-rw-r--r-- | webkit/activex_shim/web_activex_site.cc | 692 |
1 files changed, 692 insertions, 0 deletions
diff --git a/webkit/activex_shim/web_activex_site.cc b/webkit/activex_shim/web_activex_site.cc new file mode 100644 index 0000000..85bf675 --- /dev/null +++ b/webkit/activex_shim/web_activex_site.cc @@ -0,0 +1,692 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "webkit/activex_shim/web_activex_site.h" + +#include <exdisp.h> +#include <oaidl.h> +#include <shlguid.h> + +#include "base/string_util.h" +#include "webkit/activex_shim/activex_plugin.h" +#include "webkit/activex_shim/npp_impl.h" +#include "webkit/activex_shim/web_activex_container.h" + +namespace activex_shim { + +// WebActiveXSite +WebActiveXSite::WebActiveXSite() + : container_(NULL), + control_(NULL), + inplace_activated_(false), + has_capture_(false) { + rect_.left = 0; + rect_.top = 0; + rect_.right = 0; + rect_.bottom = 0; +} + +WebActiveXSite::~WebActiveXSite() { + // Don't do anything here. Do everything in FinalRelease. +} + +void WebActiveXSite::Init(WebActiveXContainer* container, IUnknown* control) { + container_ = container; + control_.Attach(control); + dispatch_ = control; + ole_object_ = control; + inplace_object_ = control; + view_object_ = control; + inplace_object_windowless_ = control; +} + +void WebActiveXSite::FinalRelease() { + // We must release everything here instead of leaving it to the destructor. + // Otherwise crash is possible. + if (control_ != NULL) { + dispatch_.Release(); + view_object_.Release(); + inplace_object_windowless_.Release(); + if (inplace_object_ != NULL) { + if (inplace_activated_) { + // If we just deactivate without checking whether the control has been + // inplace activated, the control may behave irratically. Flash will + // decrease its reference count during deactivation. Thus causing + // crash when we try to release it later. + inplace_object_->InPlaceDeactivate(); + inplace_activated_ = false; + } + inplace_object_.Release(); + } + if (ole_object_ != NULL) { + ole_object_->SetClientSite(NULL); + ole_object_->Close(OLECLOSE_NOSAVE); + ole_object_.Release(); + } + long ref = control_.Detach()->Release(); + // It should be 0 otherwise we have incorrect ref counting. + // Shockwave is known to have ref counting problems. All other controls + // behave well. + DCHECK(ref == 0 || container_->plugin()->activex_type() + == ACTIVEX_SHOCKWAVE); + } +} + +HRESULT WebActiveXSite::ActivateControl( + int x, int y, int width, int height, + const std::vector<ControlParam>& params) { + // Set the rect size of site first before SetClientSite. Otherwise the + // control may query the site for such information during SetClientSite. + rect_.left = x; + rect_.top = y; + rect_.right = rect_.left + width; + rect_.bottom = rect_.top + height; + + HRESULT hr; + if (ole_object_ != NULL) { + hr = ole_object_->SetClientSite(static_cast<IOleClientSite*>(this)); + if (FAILED(hr)) + return hr; + } + SetExtent(width, height); + + // Set initial properties. + CComQIPtr<IPersistPropertyBag> persist_property_bag = control_; + CComQIPtr<IPersistPropertyBag2> persist_property_bag2 = control_; + if (persist_property_bag2 != NULL || persist_property_bag != NULL) { + // Use property bag for initialization. This is the preferred way. + initial_params_ = params; + // Use bag2 first. + if (persist_property_bag2 != NULL) { + persist_property_bag2->InitNew(); + hr = persist_property_bag2->Load(this, NULL); + DCHECK(SUCCEEDED(hr)); + } else { + persist_property_bag->InitNew(); + hr = persist_property_bag->Load(this, NULL); + DCHECK(SUCCEEDED(hr)); + } + // We don't need this anymore. + initial_params_.clear(); + } else if (dispatch_ != NULL) { + // Use the dispatch interface to set the initial properties. This is + // less efficient for most controls. + for (unsigned int i = 0; i < params.size(); ++i) { + const ControlParam& param = params[i]; + VARIANT vtvalue; + // TODO(ruijiang): Think about type conversion. + vtvalue.vt = VT_BSTR; + vtvalue.bstrVal = SysAllocString(param.value.c_str()); + DispSetProperty(dispatch_, param.name.c_str(), vtvalue); + VariantClear(&vtvalue); + } + } + + // In place activate it if it is able to. + if (inplace_object_ != NULL) { + hr = DoVerb(OLEIVERB_INPLACEACTIVATE); + if (FAILED(hr)) + return hr; + } + + return S_OK; +} + +HRESULT WebActiveXSite::DoVerb(long verb) { + if (ole_object_ != NULL) { + HRESULT hr = ole_object_->DoVerb(verb, NULL, + static_cast<IOleClientSite*>(this), 0, + container_->container_wnd(), &rect_); + if (verb == OLEIVERB_INPLACEACTIVATE && SUCCEEDED(hr)) + inplace_activated_ = true; + return hr; + } else { + return E_UNEXPECTED; + } +} + +HRESULT WebActiveXSite::SetExtent(int width, int height) { + if (ole_object_ != NULL) { + SIZEL size; + if (width < 0) + width = 0; + if (height < 0) + height = 0; + ScreenToHimetric(width, height, &size); + return ole_object_->SetExtent(DVASPECT_CONTENT, &size); + } else { + return E_UNEXPECTED; + } +} + +void WebActiveXSite::SetRect(const RECT* rect) { + if (EqualRect(&rect_, rect)) + return; + SetExtent(rect->right - rect->left, rect->bottom - rect->top); + if (inplace_object_ != NULL) { + inplace_object_->SetObjectRects(rect, rect); + rect_ = *rect; + } +} + +// IUnknown +HRESULT STDMETHODCALLTYPE WebActiveXSite::QueryInterface(REFIID iid, + void** object) { + *object = NULL; + if (iid == IID_IUnknown) { + // Avoid ambiguous resolution of IUnknown. + *object = static_cast<IUnknown*>(static_cast<MinimumIDispatchImpl*>(this)); + } else if (iid == IID_IDispatch) { + *object = static_cast<MinimumIDispatchImpl*>(this); + } else if (iid == IID_IOleClientSite) { + *object = static_cast<IOleClientSite*>(this); + } else if (iid == IID_IOleControlSite) { + *object = static_cast<IOleControlSite*>(this); + } else if (iid == IID_IOleInPlaceSite) { + *object = static_cast<IOleInPlaceSite*>(this); + } else if (iid == IID_IOleInPlaceSiteEx) { + *object = static_cast<IOleInPlaceSiteEx*>(this); + } else if (iid == IID_IOleInPlaceSiteWindowless) { + if (container_->plugin()->windowless()) + *object = static_cast<IOleInPlaceSiteWindowless*>(this); + } else if (iid == IID_IServiceProvider) { + *object = static_cast<IServiceProvider*>(this); + } else if (iid == IID_IPropertyBag) { + *object = static_cast<IPropertyBag*>(this); + } else if (iid == IID_IPropertyBag2) { + *object = static_cast<IPropertyBag2*>(this); + } + TRACK_QUERY_INTERFACE(iid, *object != NULL); + return (*object != NULL) ? S_OK : E_NOINTERFACE; +} + +// IOleClientSite +HRESULT STDMETHODCALLTYPE WebActiveXSite::SaveObject() { + // Do not support saving object to persistant storage. + return E_NOTIMPL; +} + +// Even though Flash will call this method to get the url, it will not use +// the url to resolve its movie path. +// However, according to http://support.microsoft.com/kb/181678, this is +// a valid way of getting url from ActiveX control. +HRESULT STDMETHODCALLTYPE WebActiveXSite::GetMoniker( + DWORD assign, + DWORD which_moniker, + IMoniker** moniker) { + TRACK_METHOD(); + if (which_moniker == OLEWHICHMK_CONTAINER) { + std::wstring url = container_->plugin()->GetCurrentURL(); + HRESULT hr = CreateURLMoniker(NULL, url.c_str(), moniker); + return hr; + } else { + return E_FAIL; + } +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::GetContainer( + IOleContainer** container) { + *container = container_; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::ShowObject() { + TRACK_METHOD(); + // The control asks us to show the object which we already did. + return S_OK; +}; + +HRESULT STDMETHODCALLTYPE WebActiveXSite::OnShowWindow(BOOL show) { + TRACK_METHOD(); + // Doesn't apply to us. + return S_OK; +}; + +HRESULT STDMETHODCALLTYPE WebActiveXSite::RequestNewObjectLayout() { + TRACK_METHOD(); + // As MSDN says: "Currently, there is no standard mechanism by which + // a container can negotiate how much room an object would like. When + // such a negotiation is defined, responding to this method will be + // optional for containers." + return E_NOTIMPL; +} + +// IOleControlSite +HRESULT STDMETHODCALLTYPE WebActiveXSite::OnControlInfoChanged() { + TRACK_METHOD(); + // As we do not support mnemonics, we do not need to retrieve control info. + // This may change in the future though. + return S_OK; +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::LockInPlaceActive(BOOL lock) { + TRACK_METHOD(); + // We don't support this. + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::GetExtendedControl(IDispatch** disp) { + TRACK_METHOD(); + // We do not support extended control. + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::TransformCoords(POINTL* ptl_himetric, + POINTF* ptf_container, + DWORD flags) { + TRACK_METHOD(); + // TODO(ruijiang): so far haven't found anyone use this yet. Be aware and + // add support if needed. + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::TranslateAccelerator( + MSG* msg, + DWORD modifiers) { + TRACK_METHOD(); + // It would be nice if controls call this and let me process accelerator + // first. But unfortunately all of them I tested don't. So let's ignore + // and just keep an eye on it. + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::OnFocus(BOOL got_focus) { + TRACK_METHOD(); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::ShowPropertyFrame() { + TRACK_METHOD(); + // No we don't want to show property sheet. + return E_NOTIMPL; +} + +// IOleWindow + +HRESULT STDMETHODCALLTYPE WebActiveXSite::GetWindow(HWND* wnd) { + *wnd = container_->container_wnd(); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::ContextSensitiveHelp( + BOOL enter_mode) { + // Do not support this. + return E_NOTIMPL; +} + +// IOleInPlaceSite + +HRESULT STDMETHODCALLTYPE WebActiveXSite::CanInPlaceActivate() { + TRACK_METHOD(); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::OnInPlaceActivate() { + TRACK_METHOD(); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::OnInPlaceDeactivate() { + TRACK_METHOD(); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::OnUIActivate() { + TRACK_METHOD(); + // If we have multiple sites in a container we may deactivate the previous + // active control. This is not a requirement though. + return S_OK; +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::OnUIDeactivate(BOOL undoable) { + TRACK_METHOD(); + // Some controls will call this when they lose focus. Right now we don't need + // to do anything about it. + return S_OK; +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::GetWindowContext( + IOleInPlaceFrame** frame, + IOleInPlaceUIWindow** doc, + LPRECT pos, + LPRECT clip, + LPOLEINPLACEFRAMEINFO frame_info) { + TRACK_METHOD(); + if (frame) { + *frame = container_; + } + if (doc) + *doc = NULL; + if (pos) + *pos = rect_; + if (clip) + *clip = rect_; + if (frame_info) { + frame_info->fMDIApp = FALSE; + frame_info->hwndFrame = container_->container_wnd(); + frame_info->haccel = NULL; + frame_info->cAccelEntries = 0; + } + return S_OK; +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::Scroll(SIZE scroll_extant) { + TRACK_METHOD(); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::DiscardUndoState() { + TRACK_METHOD(); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::DeactivateAndUndo() { + TRACK_METHOD(); + // Just let the object know that it's deactivated. + if (inplace_object_ != NULL) + inplace_object_->UIDeactivate(); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::OnPosRectChange(LPCRECT pos) { + TRACK_METHOD(); + // We do not let the control move/resize itself. It should be controled + // by the container/browser. + return E_UNEXPECTED; +} + +// IOleInPlaceSiteEx + +HRESULT STDMETHODCALLTYPE WebActiveXSite::OnInPlaceActivateEx( + BOOL* no_redraw, + DWORD flags) { + TRACK_METHOD(); + // Redraw doesn't hurt. + if (no_redraw) + *no_redraw = FALSE; + if (flags & ACTIVATE_WINDOWLESS) { + // TODO(ruijiang): At this point we know for sure the object is activated + // as windowless. Revisit when we implement windowless controls. + } + return S_OK; +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::OnInPlaceDeactivateEx( + BOOL no_redraw) { + TRACK_METHOD(); + // See also: OnInPlaceDeactivate + return S_OK; +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::RequestUIActivate() { + TRACK_METHOD(); + return S_OK; +} + +// IOleInPlaceSiteWindowless + +HRESULT STDMETHODCALLTYPE WebActiveXSite::CanWindowlessActivate() { + TRACK_METHOD(); + // Yes, we prefer windowless activation. + return S_OK; +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::GetCapture() { + TRACK_METHOD(); + return has_capture_ ? S_OK : S_FALSE; +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::SetCapture(BOOL capture) { + TRACK_METHOD(); + // TODO(ruijiang): for now, let's cheat the control that it can always get + // what it wants (capture). + if (capture) { + has_capture_ = true; + return S_OK; + } else { + has_capture_ = false; + return S_OK; + } +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::GetFocus() { + TRACK_METHOD(); + // TODO(ruijiang): handle it. + return S_FALSE; +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::SetFocus(BOOL focus) { + TRACK_METHOD(); + // TODO(ruijiang): handle it. + if (focus) { + return S_FALSE; + } else { + return S_OK; + } +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::GetDC( + LPCRECT rect, + DWORD flags, + HDC* dc) { + // It's probably not wise to get the dc of Chrome window and return it, + // because we always draw onto a memory dc. Thus we may have to disappoint + // the caller. + // TODO(ruijiang): We may enable this for other browsers like FireFox. + return E_FAIL; +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::ReleaseDC(HDC dc) { + // TODO(ruijiang): We may enable this for other browsers like FireFox. + return E_FAIL; +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::InvalidateRect( + LPCRECT rect, + BOOL erase) { + // This would be the rect (in client coord of the control) that we will + // invalidate. + RECT rc; + // Control's client area, start from top-left corner as 0. + RECT client = rect_; + OffsetRect(&client, -rect_.left, -rect_.top); + if (rect) { + RECT rc_in_client = *rect; + OffsetRect(&rc_in_client, -rect_.left, -rect_.top); + if (!IntersectRect(&rc, &rc_in_client, &client)) + return S_OK; + } else { + rc = client; + } + // Convert it to NPRect. Now rc is relative to the upper-left corner of + // control. This is the requirement of NPN_InvalidateRect. + NPRect npr; + npr.left = static_cast<uint16>(rc.left); + npr.top = static_cast<uint16>(rc.top); + npr.right = static_cast<uint16>(rc.right); + npr.bottom = static_cast<uint16>(rc.bottom); + g_browser->invalidaterect(container_->plugin()->npp(), &npr); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::InvalidateRgn( + HRGN rgn, + BOOL erase) { + TRACK_METHOD(); + if (rgn == NULL) { + return InvalidateRect(NULL, erase); + } else { + // TODO(ruijiang): So far no one is using this function yet. So let's just + // invalidate the whole area. Optimize this when we need to. + return InvalidateRect(NULL, erase); + } +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::ScrollRect( + INT dx, + INT dy, + LPCRECT scroll, + LPCRECT clip) { + TRACK_METHOD(); + // TODO(ruijiang): revisit. + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::AdjustRect(LPRECT rc) { + TRACK_METHOD(); + // TODO(ruijiang): revisit. + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::OnDefWindowMessage( + UINT msg, + WPARAM wparam, + LPARAM lparam, + LRESULT* result) { + TRACK_METHOD(); + // TODO(ruijiang): handle it later. + return E_NOTIMPL; +} + +// IServiceProvider +HRESULT STDMETHODCALLTYPE WebActiveXSite::QueryService( + REFGUID guid, + REFIID riid, + void** object) { + HRESULT hr = E_FAIL; + // TODO(ruijiang): We may need to support SID_SWebBrowserApp and + // IID_IHTMLWindow2 in the future. + if (guid == IID_IBindHost || guid == IID_IWebBrowserApp) + hr = container_->QueryInterface(riid, object); + TRACK_QUERY_INTERFACE(riid, *object != NULL); + return hr; +} + +// IPropertyBag +HRESULT STDMETHODCALLTYPE WebActiveXSite::Read(LPCOLESTR prop_name, + VARIANT* var, + IErrorLog* err_log) { + unsigned int i; + for (i = 0; i < initial_params_.size(); ++i) { + if (_wcsicmp(prop_name, initial_params_[i].name.c_str()) == 0) + break; + } + if (i >= initial_params_.size()) + return E_INVALIDARG; + if (var->vt == VT_EMPTY || var->vt == VT_BSTR) { + // We don't need to do any conversion in this case. + var->vt = VT_BSTR; + var->bstrVal = ::SysAllocString(initial_params_[i].value.c_str()); + return S_OK; + } else { + // We need to try type conversion. + ScopedVariant org; + org.vt = VT_BSTR; + org.bstrVal = ::SysAllocString(initial_params_[i].value.c_str()); + HRESULT hr = VariantChangeType(var, &org, 0, var->vt); + return FAILED(hr) ? E_FAIL : S_OK; + } +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::Write(LPCOLESTR prop_name, + VARIANT* var) { + TRACK_METHOD(); + return E_NOTIMPL; +} + +// IPropertyBag2 +HRESULT STDMETHODCALLTYPE WebActiveXSite::Read(ULONG c_properties, + PROPBAG2* prop_bag, + IErrorLog* err_log, + VARIANT* value, + HRESULT* error) { + if (!prop_bag) + return E_INVALIDARG; + for (unsigned int i = 0; i < c_properties; ++i) { + PROPBAG2* p = prop_bag + i; + value->vt = p->vt; + HRESULT hr = Read(p->pstrName, value + i, err_log); + if (error) + error[i] = hr; + } + return S_OK; +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::Write(ULONG c_properties, + PROPBAG2* prop_bag, + VARIANT* value) { + TRACK_METHOD(); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::CountProperties( + ULONG* pc_properties) { + if (!pc_properties) + return E_INVALIDARG; + *pc_properties = static_cast<ULONG>(initial_params_.size()); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::GetPropertyInfo( + ULONG iproperty, + ULONG c_properties, + PROPBAG2* prop_bag, + ULONG* properties_returned) { + if (!prop_bag) + return E_INVALIDARG; + if (iproperty >= initial_params_.size()) + return E_INVALIDARG; + unsigned int i; + for (i = iproperty; + i < iproperty + c_properties && i < initial_params_.size(); + ++i) { + PROPBAG2* p = prop_bag + (i - iproperty); + memset(p, 0, sizeof(PROPBAG2)); + p->dwType = PROPBAG2_TYPE_DATA; + p->vt = VT_BSTR; + p->cfType = CF_TEXT; + p->dwHint = iproperty; + // According to the document of IPropertyBag2::GetPropertyInfo, here + // requires a string allocated by CoTaskMemAlloc. + p->pstrName = CoTaskMemAllocString(initial_params_[i].name); + } + if (properties_returned) + *properties_returned = i - iproperty; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE WebActiveXSite::LoadObject(LPCOLESTR name, + DWORD hint, + IUnknown* unk_object, + IErrorLog* err_log) { + TRACK_METHOD(); + return E_NOTIMPL; +} + +} // namespace activex_shim |