diff options
author | slightlyoff@chromium.org <slightlyoff@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-24 05:11:58 +0000 |
---|---|---|
committer | slightlyoff@chromium.org <slightlyoff@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-24 05:11:58 +0000 |
commit | f781782dd67077478e117c61dca4ea5eefce3544 (patch) | |
tree | 4801f724123cfdcbb69c4e7fe40a565b331723ae /chrome_frame/com_message_event.cc | |
parent | 63cf4759efa2373e33436fb5df6849f930081226 (diff) | |
download | chromium_src-f781782dd67077478e117c61dca4ea5eefce3544.zip chromium_src-f781782dd67077478e117c61dca4ea5eefce3544.tar.gz chromium_src-f781782dd67077478e117c61dca4ea5eefce3544.tar.bz2 |
Initial import of the Chrome Frame codebase. Integration in chrome.gyp coming in a separate CL.
BUG=None
TEST=None
Review URL: http://codereview.chromium.org/218019
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@27042 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame/com_message_event.cc')
-rw-r--r-- | chrome_frame/com_message_event.cc | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/chrome_frame/com_message_event.cc b/chrome_frame/com_message_event.cc new file mode 100644 index 0000000..1e25b87 --- /dev/null +++ b/chrome_frame/com_message_event.cc @@ -0,0 +1,157 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome_frame/com_message_event.h" + +#include "base/logging.h" +#include "base/string_util.h" + +ComMessageEvent::ComMessageEvent() { +} + +ComMessageEvent::~ComMessageEvent() { +} + +bool ComMessageEvent::Initialize(IOleContainer* container, + const std::string& message, + const std::string& origin, + const std::string& event_type) { + DCHECK(container); + message_ = message; + origin_ = origin; + type_ = event_type; + + // May remain NULL if container not IE + ScopedComPtr<IHTMLEventObj> basic_event; + ScopedComPtr<IHTMLDocument2> doc; + + // Fetching doc may fail in non-IE containers. + container->QueryInterface(doc.Receive()); + if (doc) { + ScopedComPtr<IHTMLDocument4> doc4; + doc4.QueryFrom(doc); + DCHECK(doc4); // supported by IE5.5 and higher + if (doc4) { + // IHTMLEventObj5 is only supported in IE8 and later, so we provide our + // own (minimalistic) implementation of it. + doc4->createEventObject(NULL, basic_event.Receive()); + DCHECK(basic_event); + } + } + + basic_event_ = basic_event; + return true; +} + +STDMETHODIMP ComMessageEvent::GetTypeInfoCount(UINT* info) { + // Don't DCHECK as python scripts might still call this function + // inadvertently. + DLOG(WARNING) << "Not implemented: " << __FUNCTION__; + return E_NOTIMPL; +} + +STDMETHODIMP ComMessageEvent::GetTypeInfo(UINT which_info, LCID lcid, + ITypeInfo** type_info) { + NOTREACHED(); + return E_NOTIMPL; +} + +STDMETHODIMP ComMessageEvent::GetIDsOfNames(REFIID iid, LPOLESTR* names, + UINT count_names, LCID lcid, + DISPID* dispids) { + HRESULT hr = S_OK; + + // Note that since we're using LowerCaseEqualsASCII for string comparison, + // the second argument _must_ be all lower case. I.e. we cannot compare + // against L"messagePort" since it has a capital 'P'. + for (UINT i = 0; SUCCEEDED(hr) && i < count_names; ++i) { + const wchar_t* name_begin = names[i]; + const wchar_t* name_end = name_begin + wcslen(name_begin); + if (LowerCaseEqualsASCII(name_begin, name_end, "data")) { + dispids[i] = DISPID_MESSAGE_EVENT_DATA; + } else if (LowerCaseEqualsASCII(name_begin, name_end, "origin")) { + dispids[i] = DISPID_MESSAGE_EVENT_ORIGIN; + } else if (LowerCaseEqualsASCII(name_begin, name_end, "lasteventid")) { + dispids[i] = DISPID_MESSAGE_EVENT_LAST_EVENT_ID; + } else if (LowerCaseEqualsASCII(name_begin, name_end, "source")) { + dispids[i] = DISPID_MESSAGE_EVENT_SOURCE; + } else if (LowerCaseEqualsASCII(name_begin, name_end, "messageport")) { + dispids[i] = DISPID_MESSAGE_EVENT_MESSAGE_PORT; + } else if (LowerCaseEqualsASCII(name_begin, name_end, "type")) { + dispids[i] = DISPID_MESSAGE_EVENT_TYPE; + } else { + if (basic_event_) { + hr = basic_event_->GetIDsOfNames(IID_IDispatch, &names[i], 1, lcid, + &dispids[i]); + } else { + hr = DISP_E_MEMBERNOTFOUND; + } + + if (FAILED(hr)) { + DLOG(WARNING) << "member not found: " << names[i] + << StringPrintf(L"0x%08X", hr); + } + } + } + return hr; +} + +STDMETHODIMP ComMessageEvent::Invoke(DISPID dispid, REFIID iid, LCID lcid, + WORD flags, DISPPARAMS* params, + VARIANT* result, EXCEPINFO* excepinfo, + UINT* arg_err) { + HRESULT hr = DISP_E_MEMBERNOTFOUND; + switch (dispid) { + case DISPID_MESSAGE_EVENT_DATA: + hr = GetStringProperty(flags, UTF8ToWide(message_).c_str(), result); + break; + + case DISPID_MESSAGE_EVENT_ORIGIN: + hr = GetStringProperty(flags, UTF8ToWide(origin_).c_str(), result); + break; + + case DISPID_MESSAGE_EVENT_TYPE: + hr = GetStringProperty(flags, UTF8ToWide(type_).c_str(), result); + break; + + case DISPID_MESSAGE_EVENT_LAST_EVENT_ID: + hr = GetStringProperty(flags, L"", result); + break; + + case DISPID_MESSAGE_EVENT_SOURCE: + case DISPID_MESSAGE_EVENT_MESSAGE_PORT: + if (flags & DISPATCH_PROPERTYGET) { + result->vt = VT_NULL; + hr = S_OK; + } else { + hr = DISP_E_TYPEMISMATCH; + } + break; + + default: + if (basic_event_) { + hr = basic_event_->Invoke(dispid, iid, lcid, flags, params, result, + excepinfo, arg_err); + } + break; + } + + return hr; +} + +HRESULT ComMessageEvent::GetStringProperty(WORD flags, const wchar_t* value, + VARIANT* result) { + if (!result) + return E_INVALIDARG; + + HRESULT hr; + if (flags & DISPATCH_PROPERTYGET) { + result->vt = VT_BSTR; + result->bstrVal = ::SysAllocString(value); + hr = S_OK; + } else { + hr = DISP_E_TYPEMISMATCH; + } + return hr; +} |