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

質問
-
お世話になります。
VB.NET 2003なのですが、
現在タイトルバーのアイコンを一括して変更する方法を探しております。
exeのアイコンがそのまま適用されるかと思っていたのですが、
どうやら、フォーム毎に設定できるようで、フォームが20以上あるため
アイコンが変更された場合すべて手動でデザイナを変更しなければならず
大変時間がかかる上やり残しが発生する可能性があります・・・。
一括で設定する方法はあるのでしょうか?
一つ考えた方法ですと、
アイコンをロードしてそのアイコンを設定する方法です。
Me.Icon = "アイコンのロードするパス"
これをフォーム毎に記述するようにすれば
一度コードさえ書いてしまえばICOファイルの入れ替えで
更新が反映されると思うのです。
何か良い方法がありますでしょうか?
すべての返信
-
まどか様ご返信ありがとうございます。
プロジェクトのオプションなどから一括変更できないものか・・・と探していたのですが
すべてのフォームの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に設定されているアイコンを取得してそのアイコンを設定する方法が
一番好ましい方法ではないかと感じました。
-
tomonori_tomo さんからの引用 どうやら、フォーム毎に設定できるようで、フォームが20以上あるため
アイコンが変更された場合すべて手動でデザイナを変更しなければならず
大変時間がかかる上やり残しが発生する可能性があります・・・。
デザイナ画面でフォームにアイコンを設定してやる ( Icon プロパティに、 アイコンのファイルを指定してやる) と、 アイコンのデータだけが、 フォームのリソースファイル ( .resx ) に取り込まれるようです。 ( VB2005 で確認。 リソースファイルの $this.Icon になる。 )取り込む際に、 アイコンファイルのパスは記録されないようです。 そのために、 アイコンファイルの内容を変更してからリビルドしても、 フォームのアイコンは変わらないのですね。
デザイナ画面でアイコンを設定するやりかたを残すなら、 .resx ファイルをまとめて書き換えるプログラムを作ってしまうことが考えられます。 あるいは、 デザイナ画面でアイコンを設定せずに (設定してしまっていたら、 手動で削除してから) …
tomonori_tomo さんからの引用 アイコンをロードしてそのアイコンを設定する方法です。
…という方法もありますね。 -
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() メソッドを呼び出すコードが一箇所だけになるからです。