none
デスクトップアイコンの情報取得 [ちょっと急いでます] RRS feed

  • 質問

  • こんにちは。
    すこし急いでいるので早速本題に入らせていただきますね。
    デスクトップアイコンの情報取得について教えていただきたいことがあります。
    listBox1と2があるとして、
    アイコンの座標は、
    using System;
    using System.Drawing;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
     
    namespace Sample
    {
        public partial class Form1 : Form
        {
            public const uint PROCESS_VM_OPERATION = 0x8;
            public const uint PROCESS_VM_READ = 0x10;
            public const uint PROCESS_VM_WRITE = 0x20;
            public const uint MEM_RESERVE = 0x2000;
            public const uint MEM_COMMIT = 0x1000;
            public const uint PAGE_READWRITE = 0x4;
            public const int LVM_GETITEMPOSITION = 0x1010;
            public const int LVM_GETITEMCOUNT = 0x1004;
            public const uint MEM_RELEASE = 0x8000;
     
            [DllImport("user32.dll")]
            public static extern IntPtr FindWindow(string strclassName, string strWindowName);
     
            [DllImport("user32", EntryPoint = "FindWindowEx")]
            public static extern IntPtr FindWindowEx(IntPtr hWnd1, IntPtr hWnd2, string lpsz1, string lpsz2);
     
            [DllImport("user32.dll")]
            public static extern int SendMessage(IntPtr hWnd, int wMsg, int wParam, IntPtr lParam);
     
            [DllImport("user32.dll")]
            public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
     
            [DllImport("kernel32.dll")]
            public static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, uint dwProcessId);
     
            [DllImport("kernel32.dll")]
            public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
     
            [DllImport("kernel32.dll")]
            public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, int nSize, ref uint vNumberOfBytesRead);
     
            [DllImport("kernel32.dll")]
            public static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint dwFreeType);
     
            [DllImport("kernel32.dll")]
            public static extern bool CloseHandle(IntPtr hObject);
     
            public Form1()
            {
                InitializeComponent();
            }
     
            private void Form1_Load(object sender, EventArgs e)
            {
                GetIconPosition();
            }
     
            public static bool ListView_GetItemPosition(IntPtr hwnd, int i, IntPtr ppt)
            {
                return SendMessage(hwnd, LVM_GETITEMPOSITION, i, ppt) != 0;
            }
            public static int ListView_GetItemCount(IntPtr AHandle)
            {
                return SendMessage(AHandle, LVM_GETITEMCOUNT, 0, IntPtr.Zero);
            }
     
            private void GetIconPosition()
            {
                IntPtr hWnd;
                IntPtr hProcess;
                IntPtr pnt;
                Point[] iconPoint = new Point[1];
                int iconCount;
                uint dwProcessId;
                uint vNumberOfBytesRead = 0;
     
                hWnd = FindWindow("Progman", "Program Manager");
                hWnd = FindWindowEx(hWnd, IntPtr.Zero, "SHELLDLL_DefView", null);
                hWnd = FindWindowEx(hWnd, IntPtr.Zero, "SysListView32", null);
     
                //アイコンの数を取得
                iconCount = ListView_GetItemCount(hWnd);
     
                GetWindowThreadProcessId(hWnd, out dwProcessId);
                hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, false, dwProcessId);
                pnt = VirtualAllocEx(hProcess, IntPtr.Zero, 4096, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
     
                for (int i = 0; i < iconCount; i++)
                {
                    //アイコンの位置を取得
                    ListView_GetItemPosition(hWnd, i, pnt);
                    ReadProcessMemory(hProcess, pnt, Marshal.UnsafeAddrOfPinnedArrayElement(iconPoint, 0), Marshal.SizeOf(typeof(Point)), ref vNumberOfBytesRead);
     
                    listBox1.Items.Add(string.Format("x:{0}, y:{1}", iconPoint[0].X, iconPoint[0].Y));
                }
     
                VirtualFreeEx(hProcess, pnt, 0, MEM_RELEASE);
                CloseHandle(hProcess);
            }
        }
    }
    
    (コピペですけどねf(^_^;;))
    で取得、
    デスクトップアイコンのパス一覧は、
    string userName = Environment.UserName.ToString();
    
    foreach (string stFilePath in System.IO.Directory.GetFiles(@"C:¥Users¥Public¥Desktop¥"))
    {
       listBox2.Items.Add(string.Format(stFilePath));
    }
    foreach (string stFilePath in System.IO.Directory.GetFiles(@"C:¥Users¥"+userName+@"¥Desktop¥"))
    {
        listBox2.Items.Add(string.Format(stFilePath));
    }
    
    foreach (string stFilePath in System.IO.Directory.GetDirectories(@"C:¥Users¥"+userName+@"¥Desktop¥"))
    {
        listBox2.Items.Add(string.Format(stFilePath));
    }
    foreach (string stFilePath in System.IO.Directory.GetDirectories(@"C:¥Users¥Public¥Desktop¥"))
    {
        listBox2.Items.Add(string.Format(stFilePath));
    }
    
    (desktop.iniが含まれますが。また、もしかするとWin7だけかもしれませんが)
    で取得できますよね。
    しかし、これではどのパスのアイコンがどの座標にあるのかが分かりません。
    いろいろ考えた結果、2番目の方法は使わず、1番目の方法を応用して取得するのではないかという結論に至りました。
    しかしその方法が全く分かりません。
    ググっても見たのですが、これというものがヒットしませんでした。
    どなたかこの方法をご存知の方、いらっしゃいませんでしょうか?
    よろしくお願いします。

    • 編集済み mountT 2011年5月30日 15:36
    2011年5月21日 13:38

すべての返信

  • ちょっと急いで答えますと…ひじょーに難しい問題です。1番目の方法=アイコンの座標取得、2番目の方法=ファイル名の取得、ですか? そこが書かれてないと質問本文が読み取れないことにはお気づきでしょうか。

    ともあれ目的の実現までのアプローチをどう考えているのかがわからないことには。1番目の方法を使うとして、アイコンが置かれている座標がわかったら、次は1ピクセルずつ色を読み込んで行くことをお考えでしょうか? 半透明アイコンがあれば背景色と合成されてしまうのは些細な問題だとは思います。

    1番目の方法も欲している座標データが正しく取得できているのか疑問です。自プロセスでAPI呼び出しを行って、相手プロセスのメモリ空間から結果を読み込んでいるようにも見えますが…。

    • 回答としてマーク mountT 2011年6月2日 14:58
    • 回答としてマークされていない mountT 2011年6月3日 11:30
    2011年5月22日 1:58
  • 返信ありがとうございます!

     

     

    >1番目の方法=アイコンの座標取得、2番目の方法=ファイル名の取得、ですか? 

    そうです。すみません。分かりづらかったですね。

    しかし方法というよりは、1番目のプログラム, 2番目のプログラム、といった感じだったでしょうか。

     

     

     

    >1番目の方法を使うとして、アイコンが置かれている座標がわかったら、次は1ピクセルずつ色を読み込んで行くことをお考えでしょうか? 半透明アイコンがあれば背景色と合成されてしまうのは些細な問題だとは思います。

    いえ。そういうつもりではないです。

    なんとかWindowsからそのまま座標とパスをセットでを取得できないものかと考えております。

     

     

    >1番目の方法も欲している座標データが正しく取得できているのか疑問です。自プロセスでAPI呼び出しを行って、相手プロセスのメモリ空間から結果を読み込んでいるようにも見えますが…。

    すみません。ちょっと分からないのですが、多分そうではないかと思います。

    programan.exeから読み込んでいると思われます。

    このままついでにPrograman.exeからパスも取得する、なんてことは出来ませんか?

    できないならどうすれば良いでしょうか?

     

    また、これが間違った取得の仕方で、正しい方法があるのでしたら教えていただけないでしょうか?

     

     

    質問ばかりですみません。

     

     

     

    2011年5月22日 3:27
  • 「デスクトップアイコンの情報取得」というのはアイコン画像が欲しいのではなく、どのファイルがどの座標に置かれているのか? がほしいのでしょうか。

    ListView_GetItemPosition(hWnd, i, pnt);
    ReadProcessMemory(hProcess, pnt, Marshal.UnsafeAddrOfPinnedArrayElement(iconPoint, 0), Marshal.SizeOf(typeof(Point)), ref vNumberOfBytesRead);

    というのは、クズリさんの作ったプログラム・プロセス内でListView_GetItemPosition()関数を呼び出しておいて、それが終了したらPrograman.exeのプロセス内のメモリの値を読み込んでいるんですよね?

    • 回答としてマーク mountT 2011年6月2日 14:58
    • 回答としてマークされていない mountT 2011年6月3日 11:30
    2011年5月22日 7:57
  • アイコン画像が欲しいのではなく、どのファイルがどの座標に置かれているのか? がほしいのでしょうか。

    はい!そうなんです!

     

    クズリさんの作ったプログラム・プロセス内でListView_GetItemPosition()関数を呼び出しておいて、それが終了したらPrograman.exeのプロセス内のメモリの値を読み込んでいるんですよね?

    そうだと思います。

     

     


    2011年5月22日 8:20
  • 正しいかどうかは知りませんが、Windows XP 以降なら IFolderView を使う方法はあるようですね(IFolderView2 / Windows Vista が必要にあるかも?)。バリバリの COM なので C# からの使用は面倒ですが。idl ファイルとか tlb ファイルとか見あたらないし。

    とりあえず手順としては、

    1. SHGetSpecialFolderLocation 関数などでデスクトップの IDL を取得する。
    2. IShellWindows オブジェクトを生成し、IShellWindows::FindWindowSW メソッドでデスクトップを識別するオブジェクトを取得する。このオブジェクトは IServiceProvider を公開しているので、IServiceProvider にキャスト(※ .NET のライブラリにある System.IServiceProvider とは別物)。
    3. IServiceProvider::QueryService で、IFolderView を取得する。サービス ID は SID_SFolderView で、IFolderView の GUID と同じ。
    4. IFolderView の各メソッドを使用してアイテムの位置を取得する。名前またはパスは、IFolderView::Item メソッドで取得した IDL をもとに SHGetNameFromIDList 関数で。

    となります。COM インターフェイスの定義方法については、とりあえず pinvoke.net に IServiceProvider が載ってるのでそれを参考にしてください。

    IFolderView::GetItemPosition が返すのがアイコンの座標のようなので、アイテムの座標としては IFolderView::GetSpacing とか使って調整する必要がありそうです。

    // DPI 設定が 96dpi じゃないと面倒そう。

    • 回答としてマーク mountT 2011年6月2日 14:58
    • 回答としてマークされていない mountT 2011年6月3日 11:30
    2011年5月22日 9:04
  • 返信ありがとうございます!

     

    し、しかし難しいですね...

    1~4まで一通り調べたのですが、まったくわかりませんでした......

     

    でも頑張って最後までやります!

    まずは1ですね。

    SHGetSpecialFolderLocation 関数などでデスクトップの IDL を取得する。

    聞いただけではさっぱりわからないので、もうちょっと詳しく調べてみますね!

    (こんなに難しそうなのが自然に言える方ってすごいなぁと思います。将来はこんな風になりたいなぁ...)



    2011年5月22日 12:38
  • 1ができました!
    と言いましても合っているのかどうかは分かりませんが...
    using System;  
    using System.Collections.Generic;  
    using System.ComponentModel;  
    using System.Data;  
    using System.Drawing;  
    using System.Text;  
    using System.Windows.Forms;  
    using System.Runtime.InteropServices;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            [DllImport("Shell32.DLL")]
            public static extern int SHGetSpecialFolderLocation(IntPtr hwndOwner, int nFolder, out IntPtr ppidl);
           
            public Form1()  
            {  
                InitializeComponent();  
            } 
    
            private void Form1_Load(object sender, EventArgs e)
            {
                IntPtr pidlRoot = IntPtr.Zero;  
      
                SHGetSpecialFolderLocation(this.Handle, 0x0000, out pidlRoot); 
            }
    
        }  
    
    }  
    どうでしょうか?
    2011年5月23日 14:01
  • >idl ファイルとか tlb ファイルとか見あたらないし。

    shdocvw.dll とか、その辺の .dll にリソースとして入ってるかもしれません。

     

    • 回答としてマーク mountT 2011年6月2日 14:58
    • 回答としてマークされていない mountT 2011年6月3日 11:30
    2011年5月23日 23:09
    モデレータ
  • 返信ありがとうございます!

     

    参照にShdocvw.dllを追加して、

    using SHDocVw;

    と記述すると、IShellWindowsが使えるようになりました。(VC#の候補に出てくるようになったということです。)

     

    しかしそれをどう使っていいのかは分からないままです。

    Hongliangさんの説明の2番ですね。


    2011年5月25日 9:59
  • えと、、、
    >Hongliangさん
    とりあえず pinvoke.net に IServiceProvider が載ってるので
    とはこれのことですよね?↓
            [ComImport]
            [Guid("6d5140c1-7436-11ce-8034-00aa006009fa")]
            [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
            interface IServiceProvider
            {
                void QueryService(ref Guid guidService, ref Guid riid,
                    [MarshalAs(UnmanagedType.Interface)] out object ppvObject);
            }
    
    では、IShellWindowsのほうもこれと同じようにしていいのでしょうか?
     
    もしそうであれば、Guidの値や、FindWindowSWの引数はどうすればいいでしょうか?
    Hongliangさんか、どなたか分かる方、ご教授いただけますでしょうか?

    • 編集済み mountT 2011年5月30日 15:35
    2011年5月25日 14:36
  • SHDocVw.dll に IShellWindows が入っているならそれを使えばいいのでは。あるいは ildasm で SHDocVw.dll を調べるとか。

    インターフェイスのネイティブ定義は、インターフェイス名で検索すれば大体見つかりますが(主に非日本語サイトで)、基本は Microsoft SDK を入れてヘッダを調べます。

    • 回答としてマーク mountT 2011年6月2日 14:58
    • 回答としてマークされていない mountT 2011年6月3日 11:30
    2011年5月26日 20:50
  • ありがとうございます。

     

    SHDocVw.dll に IShellWindows が入っているならそれを使えばいいのでは。

    分かりました。そうします。

     

    しかし、やはり他は分かりません...。

     

     

    using System; 
    using System.Collections.Generic; 
    using System.ComponentModel; 
    using System.Data; 
    using System.Drawing; 
    using System.Text; 
    using System.Windows.Forms; 
    using System.Runtime.InteropServices;
    
    namespace WindowsFormsApplication1
    {
     public partial class Form1 : Form
     {
     [DllImport("Shell32.DLL")]
     public static extern int SHGetSpecialFolderLocation(IntPtr hwndOwner, int nFolder, out IntPtr ppidl);
     
     public Form1() 
     { 
      InitializeComponent(); 
     } 
    
     private void Form1_Load(object sender, EventArgs e)
     {
      
      IntPtr pidl = IntPtr.Zero; 
    
      SHGetSpecialFolderLocation(this.Handle, 0x0000, out pidl);
    
    
      IShellWindows sw = new ShellWindows();
    
      IntPtr pvarLocRoot = IntPtr.Zero;
    
      int pHwnd;
    
      sw.FindWindowSW(pidl, pvarLocRoot, 0x00000008, out pHwnd, 0x00000004);
    
      }  
    }

     

    いろいろなサイトを巡りに巡った結果がこれです。

    ここまで書いてみたものの、合っているのか間違っているのかもさっぱり分からないという状態です。

    2011年6月1日 12:03
  • SHDocVw.dllは利用せず、自分でP/Invokeの記述をしたほうが良いでしょう。
    C++で記述していますので、後はC#向けに手直しすればよいです。
    Shell InterfaceはOS(UI)と密着していますので、OSにより動作が変わる可能性があります。

    最初に記述された1番目の方法でも良いかもしれません。

    HRESULT result;
    
    IShellWindows *shellWindows;
    IWebBrowserApp *webBrowserApp;
    IDispatch *dispatch;
    IServiceProvider *serviceProvider;
    IShellBrowser *shellBrowser;
    IShellView *shellView;
    IFolderView *folderView;
    IEnumIDList *enumIDList;
    
    VARIANT var;
    ITEMIDLIST *childpidl;
    long hwnd;
    POINT pos;
    
    result = CoCreateInstance(CLSID_ShellWindows, nullptr, CLSCTX_ALL, IID_IShellWindows, (void**)&shellWindows);
    
    VariantInit(&var);
    result = shellWindows->FindWindowSW(&var,&var,SWC_DESKTOP,&hwnd,SWFO_NEEDDISPATCH,&dispatch);
    
    result = dispatch->QueryInterface(IID_IWebBrowserApp,(void**)&webBrowserApp);
    result = webBrowserApp->QueryInterface(IID_IServiceProvider,(void**)&serviceProvider);
    result = serviceProvider->QueryService(SID_STopLevelBrowser,IID_IShellBrowser, (void**)&shellBrowser);
    result = shellBrowser->QueryActiveShellView(&shellView);
    result = shellView->QueryInterface(IID_IFolderView,(void**)&folderView);
    
    result = folderView->Items(SVGIO_FLAG_VIEWORDER,IID_IEnumIDList,(void**)&enumIDList);
    
    while(enumIDList->Next(1,&childpidl,nullptr) == S_OK)
    {
      result = folderView->GetItemPosition(childpidl,&pos);
      ILFree(childpidl);
    }
    
    //you should check if you need to clean up variables
    //this code will work on vista or later
    

     

    • 回答としてマーク mountT 2011年6月2日 13:45
    • 回答としてマークされていない mountT 2011年6月2日 13:45
    • 回答としてマーク mountT 2011年6月2日 14:58
    • 回答としてマークされていない mountT 2011年6月3日 11:30
    2011年6月2日 11:28
  • 返信ありがとうございます!

     

    >SHDocVw.dllは利用せず、自分でP/Invokeの記述をしたほうが良いでしょう。

    そうでしたか!分かりました。

     

    C++で記述していますので、後はC#向けに手直しすればよいです。

    えっと...

    お恥ずかしながら実はC++使ったことがないんです。

     手直し、ものすごく難しそうです。f(^_^;;)

     

    しかしその前にP/Invokeの記述ですね。

    頑張ります。

     

     


     


    2011年6月2日 14:58
  • P/Invokeとは

    [DllImport("*****.dll")]

    のような書き方をするやつのことですよね?

    それなら何というdllを使うのでしょう?

    2011年6月3日 14:04
  • P/InvokeとCOM Interopでしたね。

    確認です。
    COMそのものの仕組みはご存知でしょうか?
    COMと.NET Frameworkの関係や仕組みはご存知でしょうか?
    Shellの仕組みはご存知でしょうか?
    どこまで何をご存知でしょうか?

    もしそれらを知らないならば、難易度は高く先に進むのは困難でしょう。
    一朝一夕には説明できませんし、同じく理解できるものではないです。

    [COM Interop Part 1: C# Client Tutorial]
      http://msdn.microsoft.com/en-us/library/aa645736(VS.71).aspx

    [Interoperability Overview (C# Programming Guide)]
      http://msdn.microsoft.com/en-us/library/ms173185.aspx

    [Advanced COM Interoperability]
      http://msdn.microsoft.com/en-us/library/bd9cdfyx.aspx

    [COM 相互運用機能の概要]
      http://msdn.microsoft.com/ja-jp/magazine/cc163494.aspx

    [マネージ コードとアンマネージ コード間でマーシャリングする]
      http://msdn.microsoft.com/ja-jp/magazine/cc164193.aspx

    C++をご存じなら案として、C++/CLIの案内も出来たのですが、それも難しそうですね。

    補足です。
    >SHDocVw.dllは利用せず、自分でP/Invokeの記述をしたほうが良いでしょう。
    SHDocVw.dllはTypeLibを持っているためReferenceに追加することができるのですが、FindWindowSW Methodがありません。
    (自分でIDLを編集する手が使えるかもしれませんが、少し面倒です)

    >//this code will work on vista or later
    SWC_DESKTOP flagはVista以降でSupportされます。

    Codeは位置の取得までしか記述していません。
    どのFileなのか特定するには追加Codeが必要です。
    MSDNでIFolderViewを調べてみてください。

    >それなら何というdllを使うのでしょう?
    COMはGUIDで区別します。
    そのGUIDの先にDLL(in-process server)やEXE(out-process server)が紐付けされていると考えてください。
    従ってCOMの場合、DLL云々は気にしなくて良いです。EXEの場合もありますしね。

    ILFreeなどのAPIはMSDNで調べてみましょう。
    [ILFree Function]
      http://msdn.microsoft.com/en-us/library/bb776441(VS.85).aspx
    下の方にDLL Shell32.dll (version 5.0 or later) と書かれていますね。

    2011年6月3日 15:58
  • お忙しいところありがとうございます。お世話になります。

     

     

    COMそのものの仕組みはご存知でしょうか?

    COMと.NET Frameworkの関係や仕組みはご存知でしょうか?
    Shellの仕組みはご存知でしょうか?
    どこまで何をご存知でしょうか?

    COMの仕組みはなんとなくですが分かります。

    ですがその後は分かりません...

     

    もしそれらを知らないならば、難易度は高く先に進むのは困難でしょう。
    一朝一夕には説明できませんし、同じく理解できるものではないです。

    やはりそうですか...

    ではどうしましょう。どうしても完成させたい作品なので、諦めるのは絶対に嫌なんです。

    急ぐのをやめて一生懸命勉強した方がいいでしょうか...

     

    補足です。

    いろいろな情報、本当にありがとうございます!

    感謝です!

     

    COMはGUIDで区別します。

    IServiceProviderやIFolderViewはExplorerBrowserIIDGuidで取得できますが、IShellWindowsはどうすればいいのでしょうか?

     

    下の方にDLL Shell32.dll (version 5.0 or later) と書かれていますね。

    ほんとですね!ではこれをDllImportすればよさそうですね。

     

    あと、リンク貼ってくださってありがとうございます!

    勉強になります。

     


    • 回答の候補に設定 kozz 2011年6月8日 11:25
    • 回答の候補の設定解除 kozz 2011年6月8日 11:25
    2011年6月4日 9:42
  • >急ぐのをやめて一生懸命勉強した方がいいでしょうか
    諦める必要はありませんが、個人的にはある程度知識を習得してから実装された方が良いかと思います。

    >IShellWindowsはどうすればいいのでしょうか?
    Windows SDKにExDisp.hがあります。その中のIShellWindowsの定義を参照してください。
    すでにInstallされていると思いますので、検索してみてください。


    2011年6月8日 11:28
  • 返信ありがとうございます!

     

    諦める必要はありませんが、個人的にはある程度知識を習得してから実装された方が良いかと思います。

    そうですか。できれば実装しながら習得していきたいと思っていたのですが、学習を優先しようかと思います。

     


    Windows SDKにExDisp.hがあります。その中のIShellWindowsの定義を参照してください。

    ありました!ありがとうございます。

     

     

     

    いろいろやってみた結果、定義の部分で分からずに残っているのはIDispatch *dispatch;とITEMIDLIST* childpidl;だけになりました。

     

     



    2011年6月12日 12:43
  • >IDispatch
    同じようにWindows SDKのHeaderから検索してください。

    定義が必要とのことですが、上記Link内の以下についてはご理解されていますか?
    その上で定義が必要とのことでしたら、気にしないでください。
      COM interfaces declared in C# must include declarations for all members of their base interfaces with the exception of members of IUnknown and IDispatch — the .NET Framework automatically adds these. COM interfaces which derive from IDispatch must be marked with the InterfaceType attribute.

    >ITEMIDLIST
    構造体の中身は可変サイズであり、直接中身を除く必要もないでしょうからC#ではIntPtrでよいでしょう。

    • 編集済み kozz 2011年6月13日 9:36 補足
    2011年6月13日 9:28
  • ありがとうございます!

     

    >IDispatch
    同じようにWindows SDKのHeaderから検索してください。

    Dispatch.hを見ると、

    your code should #include oleauto.h instead of dispatch.h

    と書いてあったので、oleauto.hを見たのですが載っていませんでした...

     

    定義が必要とのことですが、上記Link内の以下についてはご理解されていますか?
    その上で定義が必要とのことでしたら、気にしないでください。
      COM interfaces declared in C# must include declarations for all members of their base interfaces with the exception of members of IUnknown and IDispatch — the .NET Framework automatically adds these. COM interfaces which derive from IDispatch must be marked with the InterfaceType attribute.

    すみません。いまいち理解できずにいます。

    なので何故定義しなくてもいいことがあるのかわかりません...

    .NET Frameworkが自動的に定義してくれるということでしょうか?

     

     

    >ITEMIDLIST
    構造体の中身は可変サイズであり、直接中身を除く必要もないでしょうからC#ではIntPtrでよいでしょう。

    分かりました。ありがとうございます!

    2011年6月14日 14:03