summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsuke <suke@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-07-08 11:13:09 +0000
committersuke <suke@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-07-08 11:13:09 +0000
commit6c32d10c0186a1aebe212f0f61c940204d7f1e73 (patch)
tree76cf0e22a68c00c7bdcb6d637318aad533a67109
parentf1d967c6ee0560eee1d728a70903534992adb6cd (diff)
* 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
-rw-r--r--ChangeLog7
-rw-r--r--ext/win32ole/win32ole.c81
-rw-r--r--test/win32ole/test_win32ole_event.rb14
3 files changed, 99 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index ccc431ee3d..3b276c7679 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/ext/win32ole/win32ole.c b/ext/win32ole/win32ole.c
index dd7d7b13a9..2de548a4cb 100644
--- a/ext/win32ole/win32ole.c
+++ b/ext/win32ole/win32ole.c
@@ -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);
diff --git a/test/win32ole/test_win32ole_event.rb b/test/win32ole/test_win32ole_event.rb
index 744021dfd2..79e5b06080 100644
--- a/test/win32ole/test_win32ole_event.rb
+++ b/test/win32ole/test_win32ole_event.rb
@@ -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)}