Excel Q&Aサロンに「列挙型の一覧データを取得したい」との質問がありました。
この手の処理は「組み込み定数を列挙するVBAマクロ」でも使用していますが、TypeLib Information(tlbinf32.dll)を利用するのが簡単です。
ただし、tlbinf32.dllは「Windows Vista および Windows Server 2008 に対する Visual Basic 6.0 のサポートに関する声明」にあるように、Windows Vista以降、すでにサポートされていませんので、今回は別の方法を考えてみることにしました。
参考にしたのはこちら↓のページ。
・タイプライブラリ
http://eternalwindows.jp/com/auto/auto02.html
LoadTypeLibでTypeLibraryを取得して、GetTypeInfoやらGetVarDescやらを使っていけば、処理できそうな感じです。
ただ、これをVBAでやるとシンドそうだったので、今回はC#を使うことにします。
using System; using System.Runtime.InteropServices; using ComTypes = System.Runtime.InteropServices.ComTypes; namespace ListTypeLibInfo { class Program { [DllImport("oleaut32.dll", PreserveSig=false)] public static extern ComTypes.ITypeLib LoadTypeLib([In, MarshalAs(UnmanagedType.LPWStr)] string typelib); public static void Main(string[] args) { ComTypes.ITypeLib lib; try { lib = LoadTypeLib(@args[0]); } catch (Exception ex) { Console.WriteLine("Error:" + ex.Message); //Console.ReadKey(true); return; } for (int i = 0; i < lib.GetTypeInfoCount(); i++) { IntPtr ppta; ComTypes.ITypeInfo info; int con; string sname, doc, hlp; lib.GetTypeInfo(i, out info); info.GetDocumentation(-1, out sname, out doc, out con, out hlp); info.GetTypeAttr(out ppta); try { ComTypes.TYPEATTR ta = (ComTypes.TYPEATTR)Marshal.PtrToStructure(ppta, typeof(ComTypes.TYPEATTR)); if (ta.typekind == ComTypes.TYPEKIND.TKIND_ENUM) { for (int j = 0; j < ta.cVars; j++) { IntPtr ppvd; int pcnames; string[] names = {string.Empty}; info.GetVarDesc(j, out ppvd); try { ComTypes.VARDESC vd = (ComTypes.VARDESC)Marshal.PtrToStructure(ppvd, typeof(ComTypes.VARDESC)); info.GetNames(vd.memid, names, 1, out pcnames); Console.WriteLine("{0}\t{1}\t{2}", sname, names[0], Marshal.GetObjectForNativeVariant(vd.desc.lpvarValue)); } finally { info.ReleaseVarDesc(ppvd); } } } } finally { info.ReleaseTypeAttr(ppta); } } //Console.Write("Press any key to continue . . . "); //Console.ReadKey(true); } } }
こんな感じでしょうか?
構造体の解放処理あたりが特に自信ありませんが、実行すると一応指定したライブラリの列挙型の情報を抜き出してくれます。
しかしながら、実際にやってみて思ったことは、やはり「TypeLib Information(tlbinf32.dll)を使った方が楽!」だということです。
tlbinf32.dllはoleaut32.dllのラッパーだと思いますが、TypeLibraryの情報を抜き出したいときはホント便利だと思います。
この記事へのコメントはありません。