* ext/win32ole/win32ole.c (find_default_source): try to

find COCLASS when WIN32OLE object is not COCLASS. 

* test/win32ole/test_win32ole_event.rb: ditto


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@17956 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
suke 2008-07-08 11:13:09 +00:00
Родитель f1d967c6ee
Коммит 6c32d10c01
3 изменённых файлов: 99 добавлений и 3 удалений

Просмотреть файл

@ -1,3 +1,10 @@
Tue Jul 8 19:55:40 2008 Masaki Suketa <masaki.suketa@nifty.ne.jp>
* ext/win32ole/win32ole.c (find_default_source): try to
find COCLASS when WIN32OLE object is not COCLASS.
* test/win32ole/test_win32ole_event.rb: ditto
Tue Jul 8 13:44:01 2008 Koichi Sasada <ko1@atdot.net>
* lib/debug.rb, lib/profile.rb: fix to use RubyVM.

Просмотреть файл

@ -118,7 +118,7 @@
#define WC2VSTR(x) ole_wc2vstr((x), TRUE)
#define WIN32OLE_VERSION "1.2.1"
#define WIN32OLE_VERSION "1.2.2"
typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX)
(REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*);
@ -7606,10 +7606,18 @@ find_default_source(VALUE ole, IID *piid, ITypeInfo **ppTypeInfo)
IDispatch *pDispatch;
ITypeInfo *pTypeInfo;
ITypeInfo *pTypeInfo2;
ITypeInfo *pRefTypeInfo;
ITypeLib *pTypeLib;
TYPEATTR *pTypeAttr;
int i;
TYPEATTR *pTypeAttr2;
TYPEATTR *pRefTypeAttr;
int i, j;
int iFlags;
HREFTYPE hRefType;
int flags;
HREFTYPE hRefType, href;
int count;
BOOL found = FALSE;
struct oledata *pole;
@ -7649,6 +7657,73 @@ find_default_source(VALUE ole, IID *piid, ITypeInfo **ppTypeInfo)
OLE_RELEASE(pTypeInfo);
return hr;
}
/*
* if the ole is not COCLASS, then try to find COCLASS which
* has ole as [default] interface.
*/
if (pTypeAttr->typekind != TKIND_COCLASS) {
/*
* search coclass
*/
hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, NULL);
if (FAILED(hr)) {
OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
OLE_RELEASE(pTypeInfo);
return hr;
}
count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
for (i = 0; i < count && !found; i++) {
hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo2);
if (FAILED(hr))
continue;
hr = OLE_GET_TYPEATTR(pTypeInfo2, &pTypeAttr2);
if (FAILED(hr)) {
OLE_RELEASE(pTypeInfo2);
continue;
}
if (pTypeAttr2->typekind != TKIND_COCLASS) {
OLE_RELEASE_TYPEATTR(pTypeInfo2, pTypeAttr2);
OLE_RELEASE(pTypeInfo2);
continue;
}
for (j = 0; j < pTypeAttr2->cImplTypes && !found; j++) {
hr = pTypeInfo2->lpVtbl->GetImplTypeFlags(pTypeInfo2, j, &flags);
if (FAILED(hr))
continue;
if (!(flags & IMPLTYPEFLAG_FDEFAULT))
continue;
hr = pTypeInfo2->lpVtbl->GetRefTypeOfImplType(pTypeInfo2, j, &href);
if (FAILED(hr))
continue;
hr = pTypeInfo2->lpVtbl->GetRefTypeInfo(pTypeInfo2, href, &pRefTypeInfo);
if (FAILED(hr))
continue;
hr = OLE_GET_TYPEATTR(pRefTypeInfo, &pRefTypeAttr);
if (FAILED(hr)) {
OLE_RELEASE(pRefTypeInfo);
continue;
}
if (IsEqualGUID(&(pTypeAttr->guid), &(pRefTypeAttr->guid))) {
found = TRUE;
}
OLE_RELEASE_TYPEATTR(pRefTypeInfo, pRefTypeAttr);
OLE_RELEASE(pRefTypeInfo);
}
if (!found) {
OLE_RELEASE_TYPEATTR(pTypeInfo2, pTypeAttr2);
OLE_RELEASE(pTypeInfo2);
}
}
if (found) {
OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
OLE_RELEASE(pTypeInfo);
pTypeInfo = pTypeInfo2;
pTypeAttr = pTypeAttr2;
}
}
/* Enumerate all implemented types of the COCLASS */
for (i = 0; i < pTypeAttr->cImplTypes; i++) {
hr = pTypeInfo->lpVtbl->GetImplTypeFlags(pTypeInfo, i, &iFlags);

Просмотреть файл

@ -30,6 +30,20 @@ if defined?(WIN32OLE_EVENT)
@event += event
end
def test_s_new_without_itf
ev = WIN32OLE_EVENT.new(@ie)
ev.on_event {|*args| default_handler(*args)}
@ie.navigate("file:///#{@f}")
while @ie.busy
WIN32OLE_EVENT.new(@ie)
GC.start
WIN32OLE_EVENT.message_loop
sleep 0.1
end
assert_match(/BeforeNavigate/, @event)
assert_match(/NavigateComplete/, @event)
end
def test_on_event
ev = WIN32OLE_EVENT.new(@ie, 'DWebBrowserEvents')
ev.on_event {|*args| default_handler(*args)}