none
タイトルバーのアイコンを一括して変更する方法について・・・ RRS feed

  • 質問

  • お世話になります。

    VB.NET 2003なのですが、

    現在タイトルバーのアイコンを一括して変更する方法を探しております。

    exeのアイコンがそのまま適用されるかと思っていたのですが、

    どうやら、フォーム毎に設定できるようで、フォームが20以上あるため

    アイコンが変更された場合すべて手動でデザイナを変更しなければならず

    大変時間がかかる上やり残しが発生する可能性があります・・・。

    一括で設定する方法はあるのでしょうか?

    一つ考えた方法ですと、

    アイコンをロードしてそのアイコンを設定する方法です。

    Me.Icon = "アイコンのロードするパス"

    これをフォーム毎に記述するようにすれば

    一度コードさえ書いてしまえばICOファイルの入れ替えで

    更新が反映されると思うのです。

    何か良い方法がありますでしょうか?

     

     

    2006年8月17日 6:13

すべての返信

  •  tomonori_tomo さんからの引用

    Me.Icon = "アイコンのロードするパス"

    Iconクラスのコンストラクタを調べてみるとよいでしょう。

    2006年8月17日 9:28
  • まどか様ご返信ありがとうございます。

    プロジェクトのオプションなどから一括変更できないものか・・・と探していたのですが

    すべてのフォームのInitializeComponent内に

    以下の様に記述することで対応させました。

     Dim ico_file_path As String

    '呼び出すアイコンの相対パス

     ico_file_path = "..\icon\exe_icon.ico"


     Dim ico As New System.Drawing.Icon(ico_file_path)


     Me.Icon = ico

    やはり、手抜きはできないということですね^^;

    ただこの方法ですとアイコンが無い場合エラーが出る可能性が・・・

    ということで、現在exeに設定されているアイコンを取得してそのアイコンを設定する方法が

    一番好ましい方法ではないかと感じました。


     

    2006年8月18日 8:29
  •  tomonori_tomo さんからの引用
    どうやら、フォーム毎に設定できるようで、フォームが20以上あるため
    アイコンが変更された場合すべて手動でデザイナを変更しなければならず
    大変時間がかかる上やり残しが発生する可能性があります・・・。

    デザイナ画面でフォームにアイコンを設定してやる ( Icon プロパティに、 アイコンのファイルを指定してやる) と、 アイコンのデータだけが、 フォームのリソースファイル ( .resx ) に取り込まれるようです。 ( VB2005 で確認。 リソースファイルの $this.Icon になる。 )

    取り込む際に、 アイコンファイルのパスは記録されないようです。 そのために、 アイコンファイルの内容を変更してからリビルドしても、 フォームのアイコンは変わらないのですね。

    デザイナ画面でアイコンを設定するやりかたを残すなら、 .resx ファイルをまとめて書き換えるプログラムを作ってしまうことが考えられます。 あるいは、 デザイナ画面でアイコンを設定せずに (設定してしまっていたら、 手動で削除してから) …

     tomonori_tomo さんからの引用
    アイコンをロードしてそのアイコンを設定する方法です。

    …という方法もありますね。

    2006年8月21日 6:16
  •  tomonori_tomo さんからの引用
    ということで、現在exeに設定されているアイコンを取得してそのアイコンを設定する方法が
    一番好ましい方法ではないかと感じました。

    実行中のアプリケーション自身のアイコンを取得する方法は、 @IT の次の記事が参考になるかと思います。
    ・バージョン情報ダイアログを作成するには?
    実行ファイルからアプリケーションのアイコンを取得するには?

    Windows API を利用しなければならないので、 専用のクラスにまとめておくとよいでしょう。 上の記事を参考に作ってみると、 こんな感じになります。


    Imports System.Runtime.InteropServices


    Public Class SHGetFileInfoWrapper

        ' SHGetFileInfo関数で使用する構造体  
        Private Structure SHFILEINFO
            Public hIcon As IntPtr
            Public iIcon As IntPtr
            Public dwAttributes As Integer
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)> _
            Public szDisplayName As String
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)> _
            Public szTypeName As String
        End Structure

        ' SHGetFileInfo関数で使用するフラグ
        Private Const SHGFI_ICON As Integer = &H100 ' アイコン・リソースの取得
        Private Const SHGFI_LARGEICON As Integer = &H0 ' 大きいアイコン
        Private Const SHGFI_SMALLICON As Integer = &H1 ' 小さいアイコン

        ' SHGetFileInfo関数
        Private Declare Ansi Function SHGetFileInfo Lib "shell32.dll" (ByVal pszPath As String, ByVal dwFileAttributes As Integer, ByRef psfi As SHFILEINFO, ByVal cbFileInfo As Integer, ByVal uFlags As Integer) As IntPtr



        Private Shared _smallIcon As Icon = Nothing

        Private Shared Function GetAssemblyLocation() As String
            Dim mainAssembly As System.Reflection.Assembly = System.Reflection.Assembly.GetEntryAssembly()
            Return mainAssembly.Location()
        End Function

        Public Shared Function GetAppSmallIcon() As Icon
            If (_smallIcon IsNot Nothing) Then
                Return _smallIcon
            End If

            Dim shInfo As New SHFILEINFO()
            Dim hSuccess As IntPtr = SHGetFileInfo( _
                GetAssemblyLocation(), _
                0, _
                shInfo, _
                Marshal.SizeOf(shInfo), _
                SHGFI_ICON Or SHGFI_SMALLICON)

            If hSuccess.Equals(IntPtr.Zero) Then
                '// アイコン取得に失敗したとき
                Return SystemIcons.Application
            End If

            _smallIcon = Icon.FromHandle(shInfo.hIcon)
            Return _smallIcon
        End Function

    End Class

     

    ※ VB2005 で動作確認。 VB.NET2003 でも、 たぶん大丈夫… あ、IsNot キーワードは 2005 からだったっけかな?

    あとは、 フォームのロード時にでも GetAppSmallIcon() メソッドを呼び出して、 アイコンをセットしてあげればよいでしょう。


        Protected Overrides Sub OnLoad(ByVal e As EventArgs)
            Me.Icon = SHGetFileInfoWrapper.GetAppSmallIcon()
            MyBase.OnLoad(e)
        End Sub

     

    ※ OnLoad() をオーバーライドしているのは、 この新しいフォームを継承してやることで、 GetAppSmallIcon() メソッドを呼び出すコードが一箇所だけになるからです。

    2006年8月21日 6:43