1 // Copyright (c) 2011 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.
5 #include "chrome_frame/com_message_event.h"
7 #include "base/logging.h"
8 #include "base/string_util.h"
9 #include "base/stringprintf.h"
10 #include "base/utf_string_conversions.h"
12 ComMessageEvent::ComMessageEvent() {
15 ComMessageEvent::~ComMessageEvent() {
18 bool ComMessageEvent::Initialize(IOleContainer
* container
,
19 const std::string
& message
,
20 const std::string
& origin
,
21 const std::string
& event_type
) {
22 DLOG_IF(WARNING
, !container
) << __FUNCTION__
<< " no container";
27 // May remain NULL if container not IE
28 base::win::ScopedComPtr
<IHTMLEventObj
> basic_event
;
29 base::win::ScopedComPtr
<IHTMLDocument2
> doc
;
31 // Fetching doc may fail in non-IE containers
32 // and container might be NULL in some applications.
34 container
->QueryInterface(doc
.Receive());
36 base::win::ScopedComPtr
<IHTMLDocument4
> doc4
;
38 DCHECK(doc4
); // supported by IE5.5 and higher
40 // IHTMLEventObj5 is only supported in IE8 and later, so we provide our
41 // own (minimalistic) implementation of it.
42 doc4
->createEventObject(NULL
, basic_event
.Receive());
47 basic_event_
= basic_event
;
51 STDMETHODIMP
ComMessageEvent::GetTypeInfoCount(UINT
* info
) {
52 // Don't DCHECK as python scripts might still call this function
54 DLOG(WARNING
) << "Not implemented: " << __FUNCTION__
;
58 STDMETHODIMP
ComMessageEvent::GetTypeInfo(UINT which_info
, LCID lcid
,
59 ITypeInfo
** type_info
) {
60 DLOG(WARNING
) << "Not implemented: " << __FUNCTION__
;
64 STDMETHODIMP
ComMessageEvent::GetIDsOfNames(REFIID iid
, LPOLESTR
* names
,
65 UINT count_names
, LCID lcid
,
69 // Note that since we're using LowerCaseEqualsASCII for string comparison,
70 // the second argument _must_ be all lower case. I.e. we cannot compare
71 // against L"messagePort" since it has a capital 'P'.
72 for (UINT i
= 0; SUCCEEDED(hr
) && i
< count_names
; ++i
) {
73 const wchar_t* name_begin
= names
[i
];
74 const wchar_t* name_end
= name_begin
+ wcslen(name_begin
);
75 if (LowerCaseEqualsASCII(name_begin
, name_end
, "data")) {
76 dispids
[i
] = DISPID_MESSAGE_EVENT_DATA
;
77 } else if (LowerCaseEqualsASCII(name_begin
, name_end
, "origin")) {
78 dispids
[i
] = DISPID_MESSAGE_EVENT_ORIGIN
;
79 } else if (LowerCaseEqualsASCII(name_begin
, name_end
, "lasteventid")) {
80 dispids
[i
] = DISPID_MESSAGE_EVENT_LAST_EVENT_ID
;
81 } else if (LowerCaseEqualsASCII(name_begin
, name_end
, "source")) {
82 dispids
[i
] = DISPID_MESSAGE_EVENT_SOURCE
;
83 } else if (LowerCaseEqualsASCII(name_begin
, name_end
, "messageport")) {
84 dispids
[i
] = DISPID_MESSAGE_EVENT_MESSAGE_PORT
;
85 } else if (LowerCaseEqualsASCII(name_begin
, name_end
, "type")) {
86 dispids
[i
] = DISPID_MESSAGE_EVENT_TYPE
;
89 hr
= basic_event_
->GetIDsOfNames(IID_IDispatch
, &names
[i
], 1, lcid
,
92 hr
= DISP_E_MEMBERNOTFOUND
;
96 DLOG(WARNING
) << "member not found: " << names
[i
]
97 << base::StringPrintf(L
"0x%08X", hr
);
104 STDMETHODIMP
ComMessageEvent::Invoke(DISPID dispid
, REFIID iid
, LCID lcid
,
105 WORD flags
, DISPPARAMS
* params
,
106 VARIANT
* result
, EXCEPINFO
* excepinfo
,
108 HRESULT hr
= DISP_E_MEMBERNOTFOUND
;
110 case DISPID_MESSAGE_EVENT_DATA
:
111 hr
= GetStringProperty(flags
, UTF8ToWide(message_
).c_str(), result
);
114 case DISPID_MESSAGE_EVENT_ORIGIN
:
115 hr
= GetStringProperty(flags
, UTF8ToWide(origin_
).c_str(), result
);
118 case DISPID_MESSAGE_EVENT_TYPE
:
119 hr
= GetStringProperty(flags
, UTF8ToWide(type_
).c_str(), result
);
122 case DISPID_MESSAGE_EVENT_LAST_EVENT_ID
:
123 hr
= GetStringProperty(flags
, L
"", result
);
126 case DISPID_MESSAGE_EVENT_SOURCE
:
127 case DISPID_MESSAGE_EVENT_MESSAGE_PORT
:
128 if (flags
& DISPATCH_PROPERTYGET
) {
129 result
->vt
= VT_NULL
;
132 hr
= DISP_E_TYPEMISMATCH
;
138 hr
= basic_event_
->Invoke(dispid
, iid
, lcid
, flags
, params
, result
,
147 HRESULT
ComMessageEvent::GetStringProperty(WORD flags
, const wchar_t* value
,
153 if (flags
& DISPATCH_PROPERTYGET
) {
154 result
->vt
= VT_BSTR
;
155 result
->bstrVal
= ::SysAllocString(value
);
158 hr
= DISP_E_TYPEMISMATCH
;