OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "chrome_frame/com_message_event.h" |
| 6 |
| 7 #include "base/logging.h" |
| 8 #include "base/string_util.h" |
| 9 |
| 10 ComMessageEvent::ComMessageEvent() { |
| 11 } |
| 12 |
| 13 ComMessageEvent::~ComMessageEvent() { |
| 14 } |
| 15 |
| 16 bool ComMessageEvent::Initialize(IOleContainer* container, |
| 17 const std::string& message, |
| 18 const std::string& origin, |
| 19 const std::string& event_type) { |
| 20 DCHECK(container); |
| 21 message_ = message; |
| 22 origin_ = origin; |
| 23 type_ = event_type; |
| 24 |
| 25 // May remain NULL if container not IE |
| 26 ScopedComPtr<IHTMLEventObj> basic_event; |
| 27 ScopedComPtr<IHTMLDocument2> doc; |
| 28 |
| 29 // Fetching doc may fail in non-IE containers. |
| 30 container->QueryInterface(doc.Receive()); |
| 31 if (doc) { |
| 32 ScopedComPtr<IHTMLDocument4> doc4; |
| 33 doc4.QueryFrom(doc); |
| 34 DCHECK(doc4); // supported by IE5.5 and higher |
| 35 if (doc4) { |
| 36 // IHTMLEventObj5 is only supported in IE8 and later, so we provide our |
| 37 // own (minimalistic) implementation of it. |
| 38 doc4->createEventObject(NULL, basic_event.Receive()); |
| 39 DCHECK(basic_event); |
| 40 } |
| 41 } |
| 42 |
| 43 basic_event_ = basic_event; |
| 44 return true; |
| 45 } |
| 46 |
| 47 STDMETHODIMP ComMessageEvent::GetTypeInfoCount(UINT* info) { |
| 48 // Don't DCHECK as python scripts might still call this function |
| 49 // inadvertently. |
| 50 DLOG(WARNING) << "Not implemented: " << __FUNCTION__; |
| 51 return E_NOTIMPL; |
| 52 } |
| 53 |
| 54 STDMETHODIMP ComMessageEvent::GetTypeInfo(UINT which_info, LCID lcid, |
| 55 ITypeInfo** type_info) { |
| 56 NOTREACHED(); |
| 57 return E_NOTIMPL; |
| 58 } |
| 59 |
| 60 STDMETHODIMP ComMessageEvent::GetIDsOfNames(REFIID iid, LPOLESTR* names, |
| 61 UINT count_names, LCID lcid, |
| 62 DISPID* dispids) { |
| 63 HRESULT hr = S_OK; |
| 64 |
| 65 // Note that since we're using LowerCaseEqualsASCII for string comparison, |
| 66 // the second argument _must_ be all lower case. I.e. we cannot compare |
| 67 // against L"messagePort" since it has a capital 'P'. |
| 68 for (UINT i = 0; SUCCEEDED(hr) && i < count_names; ++i) { |
| 69 const wchar_t* name_begin = names[i]; |
| 70 const wchar_t* name_end = name_begin + wcslen(name_begin); |
| 71 if (LowerCaseEqualsASCII(name_begin, name_end, "data")) { |
| 72 dispids[i] = DISPID_MESSAGE_EVENT_DATA; |
| 73 } else if (LowerCaseEqualsASCII(name_begin, name_end, "origin")) { |
| 74 dispids[i] = DISPID_MESSAGE_EVENT_ORIGIN; |
| 75 } else if (LowerCaseEqualsASCII(name_begin, name_end, "lasteventid")) { |
| 76 dispids[i] = DISPID_MESSAGE_EVENT_LAST_EVENT_ID; |
| 77 } else if (LowerCaseEqualsASCII(name_begin, name_end, "source")) { |
| 78 dispids[i] = DISPID_MESSAGE_EVENT_SOURCE; |
| 79 } else if (LowerCaseEqualsASCII(name_begin, name_end, "messageport")) { |
| 80 dispids[i] = DISPID_MESSAGE_EVENT_MESSAGE_PORT; |
| 81 } else if (LowerCaseEqualsASCII(name_begin, name_end, "type")) { |
| 82 dispids[i] = DISPID_MESSAGE_EVENT_TYPE; |
| 83 } else { |
| 84 if (basic_event_) { |
| 85 hr = basic_event_->GetIDsOfNames(IID_IDispatch, &names[i], 1, lcid, |
| 86 &dispids[i]); |
| 87 } else { |
| 88 hr = DISP_E_MEMBERNOTFOUND; |
| 89 } |
| 90 |
| 91 if (FAILED(hr)) { |
| 92 DLOG(WARNING) << "member not found: " << names[i] |
| 93 << StringPrintf(L"0x%08X", hr); |
| 94 } |
| 95 } |
| 96 } |
| 97 return hr; |
| 98 } |
| 99 |
| 100 STDMETHODIMP ComMessageEvent::Invoke(DISPID dispid, REFIID iid, LCID lcid, |
| 101 WORD flags, DISPPARAMS* params, |
| 102 VARIANT* result, EXCEPINFO* excepinfo, |
| 103 UINT* arg_err) { |
| 104 HRESULT hr = DISP_E_MEMBERNOTFOUND; |
| 105 switch (dispid) { |
| 106 case DISPID_MESSAGE_EVENT_DATA: |
| 107 hr = GetStringProperty(flags, UTF8ToWide(message_).c_str(), result); |
| 108 break; |
| 109 |
| 110 case DISPID_MESSAGE_EVENT_ORIGIN: |
| 111 hr = GetStringProperty(flags, UTF8ToWide(origin_).c_str(), result); |
| 112 break; |
| 113 |
| 114 case DISPID_MESSAGE_EVENT_TYPE: |
| 115 hr = GetStringProperty(flags, UTF8ToWide(type_).c_str(), result); |
| 116 break; |
| 117 |
| 118 case DISPID_MESSAGE_EVENT_LAST_EVENT_ID: |
| 119 hr = GetStringProperty(flags, L"", result); |
| 120 break; |
| 121 |
| 122 case DISPID_MESSAGE_EVENT_SOURCE: |
| 123 case DISPID_MESSAGE_EVENT_MESSAGE_PORT: |
| 124 if (flags & DISPATCH_PROPERTYGET) { |
| 125 result->vt = VT_NULL; |
| 126 hr = S_OK; |
| 127 } else { |
| 128 hr = DISP_E_TYPEMISMATCH; |
| 129 } |
| 130 break; |
| 131 |
| 132 default: |
| 133 if (basic_event_) { |
| 134 hr = basic_event_->Invoke(dispid, iid, lcid, flags, params, result, |
| 135 excepinfo, arg_err); |
| 136 } |
| 137 break; |
| 138 } |
| 139 |
| 140 return hr; |
| 141 } |
| 142 |
| 143 HRESULT ComMessageEvent::GetStringProperty(WORD flags, const wchar_t* value, |
| 144 VARIANT* result) { |
| 145 if (!result) |
| 146 return E_INVALIDARG; |
| 147 |
| 148 HRESULT hr; |
| 149 if (flags & DISPATCH_PROPERTYGET) { |
| 150 result->vt = VT_BSTR; |
| 151 result->bstrVal = ::SysAllocString(value); |
| 152 hr = S_OK; |
| 153 } else { |
| 154 hr = DISP_E_TYPEMISMATCH; |
| 155 } |
| 156 return hr; |
| 157 } |
OLD | NEW |