DOBON.NETプログラミング道掲示板
(現在 過去ログ1 を表示中)

[ 最新記事及び返信フォームをトピックトップへ ]

■33138 / inTopicNo.1)  スモールアイコンが正しくロードできない
  
□投稿者/ がおおおお 一般人(5回)-(2015/10/09(Fri) 15:31:02)
  • アイコン環境/言語:[Windows 10 Pro 32bit / Visual Studio Community 2015 / C# / .NET Framework 4.5.2] 
    分類:[.NET] 

    2015/10/09(Fri) 15:35:47 編集(投稿者)
    
    SHGetFileInfo関数を使用しファイルに関連付けられたスモールアイコンを取得したいのですが
    async await の中で実行するとおかしなアイコンがロードされてしまいます。
    
    テスト方法としてはFormにButton2個とPictureBox1個を配置し、文末のようなコードを作成します。
    
    F5で実行しbutton1を押すと青い山のようなアイコンが表示されます。
    この状態でbottun2を押しても青い山のようなアイコンが表示されます。
    
    フォームをいったん閉じます。
    
    F5で実行しbutton2を押すと白紙のアイコンが表示されます。
    この状態でbottun1を押しても白紙のアイコンが表示されます。
    
    async await の中でも必ず青い山のようなアイコンを表示させるにはどのようにすれば良いかわかりますでしょうか?
    
    
    ※テストコードではbmpファイルを指定していますが、
    例えばpdfを指定するとどちらのボタンを先に押しても同じアイコンが表示されます。
    
    
    ////////////////////////////////////////////////////////////////
    // ここからコード
    
    using System;
    using System.Drawing;
    using System.Runtime.InteropServices;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace Test
    {
        public partial class Form1 : Form
        {
            internal struct SHFILEINFO
            {
                public IntPtr hIcon;
                public IntPtr iIcon;
                public uint dwAttributes;
                [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
                public string szDisplayName;
                [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
                public string szTypeName;
            };
    
            const uint SHGFI_ICON = 0x000000100;
            const uint SHGFI_SMALLICON = 0x000000001;
    
            [DllImport("shell32.dll")]
            static extern int SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                LoadImage();
            }
    
            async private void button2_Click(object sender, EventArgs e)
            {
                await Task.Run(() =>
                {
                    LoadImage();
                });
            }
    
            void LoadImage()
            {
                SHFILEINFO shFileInfo = new SHFILEINFO();
                int result = SHGetFileInfo(@"C:\test.bmp", 0, ref shFileInfo, (uint)Marshal.SizeOf(shFileInfo), SHGFI_ICON | SHGFI_SMALLICON);
                if (result != 0)
                {
                    this.pictureBox1.Image = Icon.FromHandle(shFileInfo.hIcon).ToBitmap();
                }
            }
        }
    }
    

引用返信 削除キー/
■33139 / inTopicNo.2)  Re[1]: スモールアイコンが正しくロードできない
□投稿者/ Hongliang 大御所(506回)-(2015/10/09(Fri) 15:47:21)
  • アイコンSHGetFileInfo関数は、MTAなスレッドでは正しく動作しないようですね。
    // MSDNの当該ページにはCoInitializeを使えってぐらいしか記述がないな…。

    TaskやBackgroundWorkerが使うデスクトップ標準のThreadPoolでは必ずMTAとしてスレッドが起こされるので、非同期で使うにもこれらは使えないことになります。
    Threadクラスを直接扱うしかないでしょう。Startする前にSetApartmentStateでSTAにします。
    // 探せばSTAなスレッドを使うTaskSchedulerも転がってるかもしれない。
引用返信 削除キー/
■33140 / inTopicNo.3)  Re[2]: スモールアイコンが正しくロードできない
□投稿者/ がおおおお 一般人(6回)-(2015/10/11(Sun) 00:00:14)
  • アイコンSTA/MTAというものを全く知らなかったのですが
    とりあえずThreadクラスを使用することでアイコンを正しくロードすることを確認出来ました。
    もうちょっと複雑なことをしている本番プログラムの方で試したところ色々と別の問題が出てきてしまいましたが
    なんとか動かせるように頑張ってみようと思います。
    情報ありがとうございました。
解決み!
引用返信 削除キー/



トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

Mode/  Pass/


- Child Tree -