зеркало из https://github.com/github/ruby.git
* ext/win32ole/win32ole.c: separate src of WIN32OLE_TYPELIB from
win32ole.c * ext/win32ole/win32ole.h: ditto. * ext/win32ole/win32ole_typelib.c: ditto. * ext/win32ole/win32ole_typelib.h: ditto. * ext/win32ole/depend: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47088 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
9b94249f39
Коммит
0e2410f47e
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
Wed Aug 6 20:56:02 2014 Masaki Suketa <masaki.suketa@nifty.ne.jp>
|
||||
|
||||
* ext/win32ole/win32ole.c: separate src of WIN32OLE_TYPELIB from
|
||||
win32ole.c
|
||||
|
||||
* ext/win32ole/win32ole.h: ditto.
|
||||
* ext/win32ole/win32ole_typelib.c: ditto.
|
||||
* ext/win32ole/win32ole_typelib.h: ditto.
|
||||
* ext/win32ole/depend: ditto.
|
||||
|
||||
Wed Aug 6 20:44:07 2014 Akinori MUSHA <knu@iDaemons.org>
|
||||
|
||||
* enum.c (enum_one): [DOC] Move enum.one? documentation before the
|
||||
|
|
|
@ -2,3 +2,4 @@ WIN32OLE_HEADERS = $(HDRS) $(ruby_headers)
|
|||
win32ole.o : win32ole.c $(WIN32OLE_HEADERS)
|
||||
win32ole_variant_m.o : win32ole_variant_m.c $(WIN32OLE_HEADERS)
|
||||
win32ole_error.o : win32ole_error.c $(WIN32OLE_HEADERS)
|
||||
win32ole_typelib.o : win32ole_typelib.c $(WIN32OLE_HEADERS)
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -82,12 +82,38 @@
|
|||
#define V_UINTREF(X) V_UNION(X, puintVal)
|
||||
#endif
|
||||
|
||||
#define OLE_RELEASE(X) (X) ? ((X)->lpVtbl->Release(X)) : 0
|
||||
#define OLE_FREE(x) {\
|
||||
if(ole_initialized() == TRUE) {\
|
||||
if(x) {\
|
||||
OLE_RELEASE(x);\
|
||||
(x) = 0;\
|
||||
}\
|
||||
}\
|
||||
}
|
||||
|
||||
VALUE cWIN32OLE;
|
||||
|
||||
VALUE cWIN32OLE_TYPE;
|
||||
LCID cWIN32OLE_lcid;
|
||||
|
||||
LPWSTR ole_vstr2wc(VALUE vstr);
|
||||
LONG reg_open_key(HKEY hkey, const char *name, HKEY *phkey);
|
||||
LONG reg_open_vkey(HKEY hkey, VALUE key, HKEY *phkey);
|
||||
VALUE reg_enum_key(HKEY hkey, DWORD i);
|
||||
VALUE reg_get_val(HKEY hkey, const char *subkey);
|
||||
VALUE reg_get_val2(HKEY hkey, const char *subkey);
|
||||
void ole_initialize(void);
|
||||
VALUE default_inspect(VALUE self, const char *class_name);
|
||||
VALUE ole_wc2vstr(LPWSTR pw, BOOL isfree);
|
||||
|
||||
|
||||
#define WC2VSTR(x) ole_wc2vstr((x), TRUE)
|
||||
|
||||
BOOL ole_initialized();
|
||||
VALUE create_win32ole_type(ITypeInfo *pTypeInfo, VALUE name);
|
||||
|
||||
#include "win32ole_variant_m.h"
|
||||
#include "win32ole_typelib.h"
|
||||
#include "win32ole_error.h"
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,818 @@
|
|||
#include "win32ole.h"
|
||||
|
||||
struct oletypelibdata {
|
||||
ITypeLib *pTypeLib;
|
||||
};
|
||||
|
||||
static VALUE reg_get_typelib_file_path(HKEY hkey);
|
||||
static VALUE oletypelib_path(VALUE guid, VALUE version);
|
||||
static HRESULT oletypelib_from_guid(VALUE guid, VALUE version, ITypeLib **ppTypeLib);
|
||||
static VALUE foletypelib_s_typelibs(VALUE self);
|
||||
static VALUE oletypelib_set_member(VALUE self, ITypeLib *pTypeLib);
|
||||
static void oletypelib_free(struct oletypelibdata *poletypelib);
|
||||
static VALUE foletypelib_s_allocate(VALUE klass);
|
||||
static VALUE oletypelib_search_registry(VALUE self, VALUE typelib);
|
||||
static void oletypelib_get_libattr(ITypeLib *pTypeLib, TLIBATTR **ppTLibAttr);
|
||||
static VALUE oletypelib_search_registry2(VALUE self, VALUE args);
|
||||
static VALUE foletypelib_initialize(VALUE self, VALUE args);
|
||||
static VALUE foletypelib_guid(VALUE self);
|
||||
static VALUE foletypelib_name(VALUE self);
|
||||
static VALUE make_version_str(VALUE major, VALUE minor);
|
||||
static VALUE foletypelib_version(VALUE self);
|
||||
static VALUE foletypelib_major_version(VALUE self);
|
||||
static VALUE foletypelib_minor_version(VALUE self);
|
||||
static VALUE foletypelib_path(VALUE self);
|
||||
static VALUE foletypelib_visible(VALUE self);
|
||||
static VALUE foletypelib_library_name(VALUE self);
|
||||
static VALUE ole_types_from_typelib(ITypeLib *pTypeLib, VALUE classes);
|
||||
static VALUE typelib_file_from_typelib(VALUE ole);
|
||||
static VALUE typelib_file_from_clsid(VALUE ole);
|
||||
static VALUE foletypelib_ole_types(VALUE self);
|
||||
static VALUE foletypelib_inspect(VALUE self);
|
||||
|
||||
static VALUE
|
||||
reg_get_typelib_file_path(HKEY hkey)
|
||||
{
|
||||
VALUE path = Qnil;
|
||||
path = reg_get_val2(hkey, "win64");
|
||||
if (path != Qnil) {
|
||||
return path;
|
||||
}
|
||||
path = reg_get_val2(hkey, "win32");
|
||||
if (path != Qnil) {
|
||||
return path;
|
||||
}
|
||||
path = reg_get_val2(hkey, "win16");
|
||||
return path;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
oletypelib_path(VALUE guid, VALUE version)
|
||||
{
|
||||
int k;
|
||||
LONG err;
|
||||
HKEY hkey;
|
||||
HKEY hlang;
|
||||
VALUE lang;
|
||||
VALUE path = Qnil;
|
||||
|
||||
VALUE key = rb_str_new2("TypeLib\\");
|
||||
rb_str_concat(key, guid);
|
||||
rb_str_cat2(key, "\\");
|
||||
rb_str_concat(key, version);
|
||||
|
||||
err = reg_open_vkey(HKEY_CLASSES_ROOT, key, &hkey);
|
||||
if (err != ERROR_SUCCESS) {
|
||||
return Qnil;
|
||||
}
|
||||
for(k = 0; path == Qnil; k++) {
|
||||
lang = reg_enum_key(hkey, k);
|
||||
if (lang == Qnil)
|
||||
break;
|
||||
err = reg_open_vkey(hkey, lang, &hlang);
|
||||
if (err == ERROR_SUCCESS) {
|
||||
path = reg_get_typelib_file_path(hlang);
|
||||
RegCloseKey(hlang);
|
||||
}
|
||||
}
|
||||
RegCloseKey(hkey);
|
||||
return path;
|
||||
}
|
||||
|
||||
static HRESULT
|
||||
oletypelib_from_guid(VALUE guid, VALUE version, ITypeLib **ppTypeLib)
|
||||
{
|
||||
VALUE path;
|
||||
OLECHAR *pBuf;
|
||||
HRESULT hr;
|
||||
path = oletypelib_path(guid, version);
|
||||
if (path == Qnil) {
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
pBuf = ole_vstr2wc(path);
|
||||
hr = LoadTypeLibEx(pBuf, REGKIND_NONE, ppTypeLib);
|
||||
SysFreeString(pBuf);
|
||||
return hr;
|
||||
}
|
||||
|
||||
ITypeLib *
|
||||
itypelib(VALUE self)
|
||||
{
|
||||
struct oletypelibdata *ptlib;
|
||||
Data_Get_Struct(self, struct oletypelibdata, ptlib);
|
||||
return ptlib->pTypeLib;
|
||||
}
|
||||
|
||||
/*
|
||||
* Document-class: WIN32OLE_TYPELIB
|
||||
*
|
||||
* <code>WIN32OLE_TYPELIB</code> objects represent OLE tyblib information.
|
||||
*/
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
*
|
||||
* WIN32OLE_TYPELIB.typelibs
|
||||
*
|
||||
* Returns the array of WIN32OLE_TYPELIB object.
|
||||
*
|
||||
* tlibs = WIN32OLE_TYPELIB.typelibs
|
||||
*
|
||||
*/
|
||||
static VALUE
|
||||
foletypelib_s_typelibs(VALUE self)
|
||||
{
|
||||
HKEY htypelib, hguid;
|
||||
DWORD i, j;
|
||||
LONG err;
|
||||
VALUE guid;
|
||||
VALUE version;
|
||||
VALUE name = Qnil;
|
||||
VALUE typelibs = rb_ary_new();
|
||||
VALUE typelib = Qnil;
|
||||
HRESULT hr;
|
||||
ITypeLib *pTypeLib;
|
||||
|
||||
err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib);
|
||||
if(err != ERROR_SUCCESS) {
|
||||
return typelibs;
|
||||
}
|
||||
for(i = 0; ; i++) {
|
||||
guid = reg_enum_key(htypelib, i);
|
||||
if (guid == Qnil)
|
||||
break;
|
||||
err = reg_open_vkey(htypelib, guid, &hguid);
|
||||
if (err != ERROR_SUCCESS)
|
||||
continue;
|
||||
for(j = 0; ; j++) {
|
||||
version = reg_enum_key(hguid, j);
|
||||
if (version == Qnil)
|
||||
break;
|
||||
if ( (name = reg_get_val2(hguid, StringValuePtr(version))) != Qnil ) {
|
||||
hr = oletypelib_from_guid(guid, version, &pTypeLib);
|
||||
if (SUCCEEDED(hr)) {
|
||||
typelib = create_win32ole_typelib(pTypeLib);
|
||||
rb_ary_push(typelibs, typelib);
|
||||
}
|
||||
}
|
||||
}
|
||||
RegCloseKey(hguid);
|
||||
}
|
||||
RegCloseKey(htypelib);
|
||||
return typelibs;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
oletypelib_set_member(VALUE self, ITypeLib *pTypeLib)
|
||||
{
|
||||
struct oletypelibdata *ptlib;
|
||||
Data_Get_Struct(self, struct oletypelibdata, ptlib);
|
||||
ptlib->pTypeLib = pTypeLib;
|
||||
return self;
|
||||
}
|
||||
|
||||
static void
|
||||
oletypelib_free(struct oletypelibdata *poletypelib)
|
||||
{
|
||||
OLE_FREE(poletypelib->pTypeLib);
|
||||
free(poletypelib);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
foletypelib_s_allocate(VALUE klass)
|
||||
{
|
||||
struct oletypelibdata *poletypelib;
|
||||
VALUE obj;
|
||||
ole_initialize();
|
||||
obj = Data_Make_Struct(klass, struct oletypelibdata, 0, oletypelib_free, poletypelib);
|
||||
poletypelib->pTypeLib = NULL;
|
||||
return obj;
|
||||
}
|
||||
|
||||
VALUE
|
||||
create_win32ole_typelib(ITypeLib *pTypeLib)
|
||||
{
|
||||
VALUE obj = foletypelib_s_allocate(cWIN32OLE_TYPELIB);
|
||||
oletypelib_set_member(obj, pTypeLib);
|
||||
return obj;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
oletypelib_search_registry(VALUE self, VALUE typelib)
|
||||
{
|
||||
HKEY htypelib, hguid, hversion;
|
||||
DWORD i, j;
|
||||
LONG err;
|
||||
VALUE found = Qfalse;
|
||||
VALUE tlib;
|
||||
VALUE guid;
|
||||
VALUE ver;
|
||||
HRESULT hr;
|
||||
ITypeLib *pTypeLib;
|
||||
|
||||
err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib);
|
||||
if(err != ERROR_SUCCESS) {
|
||||
return Qfalse;
|
||||
}
|
||||
for(i = 0; !found; i++) {
|
||||
guid = reg_enum_key(htypelib, i);
|
||||
if (guid == Qnil)
|
||||
break;
|
||||
err = reg_open_vkey(htypelib, guid, &hguid);
|
||||
if (err != ERROR_SUCCESS)
|
||||
continue;
|
||||
for(j = 0; found == Qfalse; j++) {
|
||||
ver = reg_enum_key(hguid, j);
|
||||
if (ver == Qnil)
|
||||
break;
|
||||
err = reg_open_vkey(hguid, ver, &hversion);
|
||||
if (err != ERROR_SUCCESS)
|
||||
continue;
|
||||
tlib = reg_get_val(hversion, NULL);
|
||||
if (tlib == Qnil) {
|
||||
RegCloseKey(hversion);
|
||||
continue;
|
||||
}
|
||||
if (rb_str_cmp(typelib, tlib) == 0) {
|
||||
hr = oletypelib_from_guid(guid, ver, &pTypeLib);
|
||||
if (SUCCEEDED(hr)) {
|
||||
oletypelib_set_member(self, pTypeLib);
|
||||
found = Qtrue;
|
||||
}
|
||||
}
|
||||
RegCloseKey(hversion);
|
||||
}
|
||||
RegCloseKey(hguid);
|
||||
}
|
||||
RegCloseKey(htypelib);
|
||||
return found;
|
||||
}
|
||||
|
||||
static void
|
||||
oletypelib_get_libattr(ITypeLib *pTypeLib, TLIBATTR **ppTLibAttr)
|
||||
{
|
||||
HRESULT hr;
|
||||
hr = pTypeLib->lpVtbl->GetLibAttr(pTypeLib, ppTLibAttr);
|
||||
if (FAILED(hr)) {
|
||||
ole_raise(hr, eWIN32OLERuntimeError,
|
||||
"failed to get library attribute(TLIBATTR) from ITypeLib");
|
||||
}
|
||||
}
|
||||
|
||||
static VALUE
|
||||
oletypelib_search_registry2(VALUE self, VALUE args)
|
||||
{
|
||||
HKEY htypelib, hguid, hversion;
|
||||
double fver;
|
||||
DWORD j;
|
||||
LONG err;
|
||||
VALUE found = Qfalse;
|
||||
VALUE tlib;
|
||||
VALUE ver;
|
||||
VALUE version_str;
|
||||
VALUE version = Qnil;
|
||||
VALUE typelib = Qnil;
|
||||
HRESULT hr;
|
||||
ITypeLib *pTypeLib;
|
||||
|
||||
VALUE guid = rb_ary_entry(args, 0);
|
||||
version_str = make_version_str(rb_ary_entry(args, 1), rb_ary_entry(args, 2));
|
||||
|
||||
err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib);
|
||||
if(err != ERROR_SUCCESS) {
|
||||
return Qfalse;
|
||||
}
|
||||
err = reg_open_vkey(htypelib, guid, &hguid);
|
||||
if (err != ERROR_SUCCESS) {
|
||||
RegCloseKey(htypelib);
|
||||
return Qfalse;
|
||||
}
|
||||
if (version_str != Qnil) {
|
||||
err = reg_open_vkey(hguid, version_str, &hversion);
|
||||
if (err == ERROR_SUCCESS) {
|
||||
tlib = reg_get_val(hversion, NULL);
|
||||
if (tlib != Qnil) {
|
||||
typelib = tlib;
|
||||
version = version_str;
|
||||
}
|
||||
}
|
||||
RegCloseKey(hversion);
|
||||
} else {
|
||||
fver = 0.0;
|
||||
for(j = 0; ;j++) {
|
||||
ver = reg_enum_key(hguid, j);
|
||||
if (ver == Qnil)
|
||||
break;
|
||||
err = reg_open_vkey(hguid, ver, &hversion);
|
||||
if (err != ERROR_SUCCESS)
|
||||
continue;
|
||||
tlib = reg_get_val(hversion, NULL);
|
||||
if (tlib == Qnil) {
|
||||
RegCloseKey(hversion);
|
||||
continue;
|
||||
}
|
||||
if (fver < atof(StringValuePtr(ver))) {
|
||||
fver = atof(StringValuePtr(ver));
|
||||
version = ver;
|
||||
typelib = tlib;
|
||||
}
|
||||
RegCloseKey(hversion);
|
||||
}
|
||||
}
|
||||
RegCloseKey(hguid);
|
||||
RegCloseKey(htypelib);
|
||||
if (typelib != Qnil) {
|
||||
hr = oletypelib_from_guid(guid, version, &pTypeLib);
|
||||
if (SUCCEEDED(hr)) {
|
||||
found = Qtrue;
|
||||
oletypelib_set_member(self, pTypeLib);
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* WIN32OLE_TYPELIB.new(typelib [, version1, version2]) -> WIN32OLE_TYPELIB object
|
||||
*
|
||||
* Returns a new WIN32OLE_TYPELIB object.
|
||||
*
|
||||
* The first argument <i>typelib</i> specifies OLE type library name or GUID or
|
||||
* OLE library file.
|
||||
* The second argument is major version or version of the type library.
|
||||
* The third argument is minor version.
|
||||
* The second argument and third argument are optional.
|
||||
* If the first argument is type library name, then the second and third argument
|
||||
* are ignored.
|
||||
*
|
||||
* tlib1 = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
|
||||
* tlib2 = WIN32OLE_TYPELIB.new('{00020813-0000-0000-C000-000000000046}')
|
||||
* tlib3 = WIN32OLE_TYPELIB.new('{00020813-0000-0000-C000-000000000046}', 1.3)
|
||||
* tlib4 = WIN32OLE_TYPELIB.new('{00020813-0000-0000-C000-000000000046}', 1, 3)
|
||||
* tlib5 = WIN32OLE_TYPELIB.new("C:\\WINNT\\SYSTEM32\\SHELL32.DLL")
|
||||
* puts tlib1.name # -> 'Microsoft Excel 9.0 Object Library'
|
||||
* puts tlib2.name # -> 'Microsoft Excel 9.0 Object Library'
|
||||
* puts tlib3.name # -> 'Microsoft Excel 9.0 Object Library'
|
||||
* puts tlib4.name # -> 'Microsoft Excel 9.0 Object Library'
|
||||
* puts tlib5.name # -> 'Microsoft Shell Controls And Automation'
|
||||
*
|
||||
*/
|
||||
static VALUE
|
||||
foletypelib_initialize(VALUE self, VALUE args)
|
||||
{
|
||||
VALUE found = Qfalse;
|
||||
VALUE typelib = Qnil;
|
||||
int len = 0;
|
||||
OLECHAR * pbuf;
|
||||
ITypeLib *pTypeLib;
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
len = RARRAY_LEN(args);
|
||||
if (len < 1 || len > 3) {
|
||||
rb_raise(rb_eArgError, "wrong number of arguments (%d for 1..3)", len);
|
||||
}
|
||||
|
||||
typelib = rb_ary_entry(args, 0);
|
||||
|
||||
SafeStringValue(typelib);
|
||||
|
||||
found = oletypelib_search_registry(self, typelib);
|
||||
if (found == Qfalse) {
|
||||
found = oletypelib_search_registry2(self, args);
|
||||
}
|
||||
if (found == Qfalse) {
|
||||
pbuf = ole_vstr2wc(typelib);
|
||||
hr = LoadTypeLibEx(pbuf, REGKIND_NONE, &pTypeLib);
|
||||
SysFreeString(pbuf);
|
||||
if (SUCCEEDED(hr)) {
|
||||
found = Qtrue;
|
||||
oletypelib_set_member(self, pTypeLib);
|
||||
}
|
||||
}
|
||||
|
||||
if (found == Qfalse) {
|
||||
rb_raise(eWIN32OLERuntimeError, "not found type library `%s`",
|
||||
StringValuePtr(typelib));
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* WIN32OLE_TYPELIB#guid -> The guid string.
|
||||
*
|
||||
* Returns guid string which specifies type library.
|
||||
*
|
||||
* tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
|
||||
* guid = tlib.guid # -> '{00020813-0000-0000-C000-000000000046}'
|
||||
*/
|
||||
static VALUE
|
||||
foletypelib_guid(VALUE self)
|
||||
{
|
||||
ITypeLib *pTypeLib;
|
||||
OLECHAR bstr[80];
|
||||
VALUE guid = Qnil;
|
||||
int len;
|
||||
TLIBATTR *pTLibAttr;
|
||||
|
||||
pTypeLib = itypelib(self);
|
||||
oletypelib_get_libattr(pTypeLib, &pTLibAttr);
|
||||
len = StringFromGUID2(&pTLibAttr->guid, bstr, sizeof(bstr)/sizeof(OLECHAR));
|
||||
if (len > 3) {
|
||||
guid = ole_wc2vstr(bstr, FALSE);
|
||||
}
|
||||
pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
|
||||
return guid;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* WIN32OLE_TYPELIB#name -> The type library name
|
||||
*
|
||||
* Returns the type library name.
|
||||
*
|
||||
* tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
|
||||
* name = tlib.name # -> 'Microsoft Excel 9.0 Object Library'
|
||||
*/
|
||||
static VALUE
|
||||
foletypelib_name(VALUE self)
|
||||
{
|
||||
ITypeLib *pTypeLib;
|
||||
HRESULT hr;
|
||||
BSTR bstr;
|
||||
VALUE name;
|
||||
pTypeLib = itypelib(self);
|
||||
hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, -1,
|
||||
NULL, &bstr, NULL, NULL);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
ole_raise(hr, eWIN32OLERuntimeError, "failed to get name from ITypeLib");
|
||||
}
|
||||
name = WC2VSTR(bstr);
|
||||
return name;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
make_version_str(VALUE major, VALUE minor)
|
||||
{
|
||||
VALUE version_str = Qnil;
|
||||
VALUE minor_str = Qnil;
|
||||
if (major == Qnil) {
|
||||
return Qnil;
|
||||
}
|
||||
version_str = rb_String(major);
|
||||
if (minor != Qnil) {
|
||||
minor_str = rb_String(minor);
|
||||
rb_str_cat2(version_str, ".");
|
||||
rb_str_append(version_str, minor_str);
|
||||
}
|
||||
return version_str;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* WIN32OLE_TYPELIB#version -> The type library version.
|
||||
*
|
||||
* Returns the type library version.
|
||||
*
|
||||
* tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
|
||||
* puts tlib.version #-> 1.3
|
||||
*/
|
||||
static VALUE
|
||||
foletypelib_version(VALUE self)
|
||||
{
|
||||
TLIBATTR *pTLibAttr;
|
||||
VALUE major;
|
||||
VALUE minor;
|
||||
ITypeLib *pTypeLib;
|
||||
|
||||
pTypeLib = itypelib(self);
|
||||
oletypelib_get_libattr(pTypeLib, &pTLibAttr);
|
||||
major = INT2NUM(pTLibAttr->wMajorVerNum);
|
||||
minor = INT2NUM(pTLibAttr->wMinorVerNum);
|
||||
pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
|
||||
return rb_Float(make_version_str(major, minor));
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* WIN32OLE_TYPELIB#major_version -> The type library major version.
|
||||
*
|
||||
* Returns the type library major version.
|
||||
*
|
||||
* tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
|
||||
* puts tlib.major_version # -> 1
|
||||
*/
|
||||
static VALUE
|
||||
foletypelib_major_version(VALUE self)
|
||||
{
|
||||
TLIBATTR *pTLibAttr;
|
||||
VALUE major;
|
||||
ITypeLib *pTypeLib;
|
||||
pTypeLib = itypelib(self);
|
||||
oletypelib_get_libattr(pTypeLib, &pTLibAttr);
|
||||
|
||||
major = INT2NUM(pTLibAttr->wMajorVerNum);
|
||||
pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
|
||||
return major;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* WIN32OLE_TYPELIB#minor_version -> The type library minor version.
|
||||
*
|
||||
* Returns the type library minor version.
|
||||
*
|
||||
* tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
|
||||
* puts tlib.minor_version # -> 3
|
||||
*/
|
||||
static VALUE
|
||||
foletypelib_minor_version(VALUE self)
|
||||
{
|
||||
TLIBATTR *pTLibAttr;
|
||||
VALUE minor;
|
||||
ITypeLib *pTypeLib;
|
||||
pTypeLib = itypelib(self);
|
||||
oletypelib_get_libattr(pTypeLib, &pTLibAttr);
|
||||
minor = INT2NUM(pTLibAttr->wMinorVerNum);
|
||||
pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
|
||||
return minor;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* WIN32OLE_TYPELIB#path -> The type library file path.
|
||||
*
|
||||
* Returns the type library file path.
|
||||
*
|
||||
* tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
|
||||
* puts tlib.path #-> 'C:\...\EXCEL9.OLB'
|
||||
*/
|
||||
static VALUE
|
||||
foletypelib_path(VALUE self)
|
||||
{
|
||||
TLIBATTR *pTLibAttr;
|
||||
HRESULT hr = S_OK;
|
||||
BSTR bstr;
|
||||
LCID lcid = cWIN32OLE_lcid;
|
||||
VALUE path;
|
||||
ITypeLib *pTypeLib;
|
||||
|
||||
pTypeLib = itypelib(self);
|
||||
oletypelib_get_libattr(pTypeLib, &pTLibAttr);
|
||||
hr = QueryPathOfRegTypeLib(&pTLibAttr->guid,
|
||||
pTLibAttr->wMajorVerNum,
|
||||
pTLibAttr->wMinorVerNum,
|
||||
lcid,
|
||||
&bstr);
|
||||
if (FAILED(hr)) {
|
||||
pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
|
||||
ole_raise(hr, eWIN32OLERuntimeError, "failed to QueryPathOfRegTypeTypeLib");
|
||||
}
|
||||
|
||||
pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
|
||||
path = WC2VSTR(bstr);
|
||||
return path;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* WIN32OLE_TYPELIB#visible?
|
||||
*
|
||||
* Returns true if the type library information is not hidden.
|
||||
* If wLibFlags of TLIBATTR is 0 or LIBFLAG_FRESTRICTED or LIBFLAG_FHIDDEN,
|
||||
* the method returns false, otherwise, returns true.
|
||||
* If the method fails to access the TLIBATTR information, then
|
||||
* WIN32OLERuntimeError is raised.
|
||||
*
|
||||
* tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
|
||||
* tlib.visible? # => true
|
||||
*/
|
||||
static VALUE
|
||||
foletypelib_visible(VALUE self)
|
||||
{
|
||||
ITypeLib *pTypeLib = NULL;
|
||||
VALUE visible = Qtrue;
|
||||
TLIBATTR *pTLibAttr;
|
||||
|
||||
pTypeLib = itypelib(self);
|
||||
oletypelib_get_libattr(pTypeLib, &pTLibAttr);
|
||||
|
||||
if ((pTLibAttr->wLibFlags == 0) ||
|
||||
(pTLibAttr->wLibFlags & LIBFLAG_FRESTRICTED) ||
|
||||
(pTLibAttr->wLibFlags & LIBFLAG_FHIDDEN)) {
|
||||
visible = Qfalse;
|
||||
}
|
||||
pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
|
||||
return visible;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* WIN32OLE_TYPELIB#library_name
|
||||
*
|
||||
* Returns library name.
|
||||
* If the method fails to access library name, WIN32OLERuntimeError is raised.
|
||||
*
|
||||
* tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
|
||||
* tlib.library_name # => Excel
|
||||
*/
|
||||
static VALUE
|
||||
foletypelib_library_name(VALUE self)
|
||||
{
|
||||
HRESULT hr;
|
||||
ITypeLib *pTypeLib = NULL;
|
||||
VALUE libname = Qnil;
|
||||
BSTR bstr;
|
||||
|
||||
pTypeLib = itypelib(self);
|
||||
hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, -1,
|
||||
&bstr, NULL, NULL, NULL);
|
||||
if (FAILED(hr)) {
|
||||
ole_raise(hr, eWIN32OLERuntimeError, "failed to get library name");
|
||||
}
|
||||
libname = WC2VSTR(bstr);
|
||||
return libname;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
ole_types_from_typelib(ITypeLib *pTypeLib, VALUE classes)
|
||||
{
|
||||
long count;
|
||||
int i;
|
||||
HRESULT hr;
|
||||
BSTR bstr;
|
||||
ITypeInfo *pTypeInfo;
|
||||
VALUE type;
|
||||
|
||||
count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
|
||||
for (i = 0; i < count; i++) {
|
||||
hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i,
|
||||
&bstr, NULL, NULL, NULL);
|
||||
if (FAILED(hr))
|
||||
continue;
|
||||
|
||||
hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo);
|
||||
if (FAILED(hr))
|
||||
continue;
|
||||
|
||||
type = create_win32ole_type(pTypeInfo, WC2VSTR(bstr));
|
||||
|
||||
rb_ary_push(classes, type);
|
||||
OLE_RELEASE(pTypeInfo);
|
||||
}
|
||||
return classes;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
typelib_file_from_typelib(VALUE ole)
|
||||
{
|
||||
HKEY htypelib, hclsid, hversion, hlang;
|
||||
double fver;
|
||||
DWORD i, j, k;
|
||||
LONG err;
|
||||
BOOL found = FALSE;
|
||||
VALUE typelib;
|
||||
VALUE file = Qnil;
|
||||
VALUE clsid;
|
||||
VALUE ver;
|
||||
VALUE lang;
|
||||
|
||||
err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib);
|
||||
if(err != ERROR_SUCCESS) {
|
||||
return Qnil;
|
||||
}
|
||||
for(i = 0; !found; i++) {
|
||||
clsid = reg_enum_key(htypelib, i);
|
||||
if (clsid == Qnil)
|
||||
break;
|
||||
err = reg_open_vkey(htypelib, clsid, &hclsid);
|
||||
if (err != ERROR_SUCCESS)
|
||||
continue;
|
||||
fver = 0;
|
||||
for(j = 0; !found; j++) {
|
||||
ver = reg_enum_key(hclsid, j);
|
||||
if (ver == Qnil)
|
||||
break;
|
||||
err = reg_open_vkey(hclsid, ver, &hversion);
|
||||
if (err != ERROR_SUCCESS || fver > atof(StringValuePtr(ver)))
|
||||
continue;
|
||||
fver = atof(StringValuePtr(ver));
|
||||
typelib = reg_get_val(hversion, NULL);
|
||||
if (typelib == Qnil)
|
||||
continue;
|
||||
if (rb_str_cmp(typelib, ole) == 0) {
|
||||
for(k = 0; !found; k++) {
|
||||
lang = reg_enum_key(hversion, k);
|
||||
if (lang == Qnil)
|
||||
break;
|
||||
err = reg_open_vkey(hversion, lang, &hlang);
|
||||
if (err == ERROR_SUCCESS) {
|
||||
if ((file = reg_get_typelib_file_path(hlang)) != Qnil)
|
||||
found = TRUE;
|
||||
RegCloseKey(hlang);
|
||||
}
|
||||
}
|
||||
}
|
||||
RegCloseKey(hversion);
|
||||
}
|
||||
RegCloseKey(hclsid);
|
||||
}
|
||||
RegCloseKey(htypelib);
|
||||
return file;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
typelib_file_from_clsid(VALUE ole)
|
||||
{
|
||||
HKEY hroot, hclsid;
|
||||
LONG err;
|
||||
VALUE typelib;
|
||||
char path[MAX_PATH + 1];
|
||||
|
||||
err = reg_open_key(HKEY_CLASSES_ROOT, "CLSID", &hroot);
|
||||
if (err != ERROR_SUCCESS) {
|
||||
return Qnil;
|
||||
}
|
||||
err = reg_open_key(hroot, StringValuePtr(ole), &hclsid);
|
||||
if (err != ERROR_SUCCESS) {
|
||||
RegCloseKey(hroot);
|
||||
return Qnil;
|
||||
}
|
||||
typelib = reg_get_val2(hclsid, "InprocServer32");
|
||||
RegCloseKey(hroot);
|
||||
RegCloseKey(hclsid);
|
||||
if (typelib != Qnil) {
|
||||
ExpandEnvironmentStrings(StringValuePtr(typelib), path, sizeof(path));
|
||||
path[MAX_PATH] = '\0';
|
||||
typelib = rb_str_new2(path);
|
||||
}
|
||||
return typelib;
|
||||
}
|
||||
|
||||
VALUE
|
||||
typelib_file(VALUE ole)
|
||||
{
|
||||
VALUE file = typelib_file_from_clsid(ole);
|
||||
if (file != Qnil) {
|
||||
return file;
|
||||
}
|
||||
return typelib_file_from_typelib(ole);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* WIN32OLE_TYPELIB#ole_types -> The array of WIN32OLE_TYPE object included the type library.
|
||||
*
|
||||
* Returns the type library file path.
|
||||
*
|
||||
* tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
|
||||
* classes = tlib.ole_types.collect{|k| k.name} # -> ['AddIn', 'AddIns' ...]
|
||||
*/
|
||||
static VALUE
|
||||
foletypelib_ole_types(VALUE self)
|
||||
{
|
||||
ITypeLib *pTypeLib = NULL;
|
||||
VALUE classes = rb_ary_new();
|
||||
pTypeLib = itypelib(self);
|
||||
ole_types_from_typelib(pTypeLib, classes);
|
||||
return classes;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* WIN32OLE_TYPELIB#inspect -> String
|
||||
*
|
||||
* Returns the type library name with class name.
|
||||
*
|
||||
* tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
|
||||
* tlib.inspect # => "<#WIN32OLE_TYPELIB:Microsoft Excel 9.0 Object Library>"
|
||||
*/
|
||||
static VALUE
|
||||
foletypelib_inspect(VALUE self)
|
||||
{
|
||||
return default_inspect(self, "WIN32OLE_TYPELIB");
|
||||
}
|
||||
|
||||
void
|
||||
Init_win32ole_typelib()
|
||||
{
|
||||
cWIN32OLE_TYPELIB = rb_define_class("WIN32OLE_TYPELIB", rb_cObject);
|
||||
rb_define_singleton_method(cWIN32OLE_TYPELIB, "typelibs", foletypelib_s_typelibs, 0);
|
||||
rb_define_alloc_func(cWIN32OLE_TYPELIB, foletypelib_s_allocate);
|
||||
rb_define_method(cWIN32OLE_TYPELIB, "initialize", foletypelib_initialize, -2);
|
||||
rb_define_method(cWIN32OLE_TYPELIB, "guid", foletypelib_guid, 0);
|
||||
rb_define_method(cWIN32OLE_TYPELIB, "name", foletypelib_name, 0);
|
||||
rb_define_method(cWIN32OLE_TYPELIB, "version", foletypelib_version, 0);
|
||||
rb_define_method(cWIN32OLE_TYPELIB, "major_version", foletypelib_major_version, 0);
|
||||
rb_define_method(cWIN32OLE_TYPELIB, "minor_version", foletypelib_minor_version, 0);
|
||||
rb_define_method(cWIN32OLE_TYPELIB, "path", foletypelib_path, 0);
|
||||
rb_define_method(cWIN32OLE_TYPELIB, "ole_types", foletypelib_ole_types, 0);
|
||||
rb_define_alias(cWIN32OLE_TYPELIB, "ole_classes", "ole_types");
|
||||
rb_define_method(cWIN32OLE_TYPELIB, "visible?", foletypelib_visible, 0);
|
||||
rb_define_method(cWIN32OLE_TYPELIB, "library_name", foletypelib_library_name, 0);
|
||||
rb_define_alias(cWIN32OLE_TYPELIB, "to_s", "name");
|
||||
rb_define_method(cWIN32OLE_TYPELIB, "inspect", foletypelib_inspect, 0);
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef WIN32OLE_TYPELIB_H
|
||||
#define WIN32OLE_TYPELIB_H 1
|
||||
|
||||
VALUE cWIN32OLE_TYPELIB;
|
||||
|
||||
void Init_win32ole_typelib();
|
||||
ITypeLib * itypelib(VALUE self);
|
||||
VALUE typelib_file(VALUE ole);
|
||||
VALUE create_win32ole_typelib(ITypeLib *pTypeLib);
|
||||
#endif
|
Загрузка…
Ссылка в новой задаче