ランチャーアプリを作ります。
最初は基礎編
ボタンを押すとテキストボックスに入力されているファイルやフォルダを開いたり、ウェブサイトにアクセスすることができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { string path = textBox1.Text; OpenFile(path); } void OpenFile(string path) { try { Icon appIcon = Icon.ExtractAssociatedIcon(path); pictureBox1.Image = appIcon.ToBitmap(); pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage; System.Diagnostics.Process.Start(path); } catch { MessageBox.Show("ファイルが存在しません"); } } } |
以上です。
・・・では面白くないのでもうちょっと付け加えてみます。
Icon appIcon = Icon.ExtractAssociatedIcon(filePath);
とやるとファイルのアイコンを取得することができます。そこでPictureBoxにドラッグするとファイルが登録され、PictureBoxをクリックするとファイルが開くというアプリを作ってみます。
まず、以下のようなクラスをつくります。PictureBoxを継承してドロップされたら・・・と考えたのですが、PictureBoxは直接 AllowDropを操作することは考慮されていません。親コントロールの AllowDropとD&D のイベントを使用するしかないようです。ここではPanelを継承して使います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
class PanelEx : Panel { string path = ""; PictureBox box = new PictureBox(); public PanelEx() { AllowDrop = true; box.Parent = this; box.Dock = DockStyle.Fill; box.Click += Box_Click; box.MouseMove += Box_MouseMove; } public string GetPath() { return path; } public void SetPath(string path0) { path = path0; box.SizeMode = PictureBoxSizeMode.StretchImage; if (File.Exists(path)) { Icon appIcon = Icon.ExtractAssociatedIcon(path0); box.Image = appIcon.ToBitmap(); } else if (Directory.Exists(path0)) { box.Image = GetFolderImage(); } } private void Box_MouseMove(object sender, MouseEventArgs e) { Form1 f = (Form1)FindForm(); f.label1.ForeColor = Color.White; f.label1.Text = path; } private void Box_Click(object sender, EventArgs e) { try { Icon appIcon = Icon.ExtractAssociatedIcon(path); System.Diagnostics.Process.Start(path); } catch { MessageBox.Show("ファイルが存在しません"); } } protected override void OnDragOver(DragEventArgs e) { e.Effect = DragDropEffects.All; } protected override void OnDragDrop(DragEventArgs e) { if (e.Data.GetDataPresent(DataFormats.FileDrop)) { string[] files = (string[])e.Data.GetData(DataFormats.FileDrop); path = files[0]; box.SizeMode = PictureBoxSizeMode.StretchImage; if (File.Exists(path)) { Icon appIcon = Icon.ExtractAssociatedIcon(path); box.Image = appIcon.ToBitmap(); } else if (Directory.Exists(path)) { box.Image = GetFolderImage(); } } } Image GetFolderImage() { SHFILEINFO shinfo = new SHFILEINFO(); IntPtr hSuccess = SHGetFileInfo("", 0, ref shinfo, (uint)System.Runtime.InteropServices.Marshal.SizeOf(shinfo), SHGFI_ICON | SHGFI_LARGEICON); if (hSuccess != IntPtr.Zero) { Icon appIcon = Icon.FromHandle(shinfo.hIcon); return appIcon.ToBitmap(); } return null; } // SHGetFileInfo関数 [System.Runtime.InteropServices.DllImport("shell32.dll")] private static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags); // SHGetFileInfo関数で使用する構造体 private struct SHFILEINFO { public IntPtr hIcon; public IntPtr iIcon; public uint dwAttributes; [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 260)] public string szDisplayName; [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 80)] public string szTypeName; }; // SHGetFileInfo関数で使用するフラグ private const uint SHGFI_ICON = 0x100; // アイコン・リソースの取得 private const uint SHGFI_LARGEICON = 0x0; // 大きいアイコン private const uint SHGFI_SMALLICON = 0x1; // 小さいアイコン } |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { this.BackColor = Color.Black; label1.BackColor = Color.Black; } } |
これでファイルをドロップしてクリックするとファイルが開けるようになります。
スタイリッシュ?にするために背景を黒にしてみました。これまでつくってきたものと比べるとちょっとだけ見た目もよくなったように思います。(自画自賛)
ただこれだけではアプリを終了させると登録したファイル情報も消えてしまいます。そこでシリアル化してしまいましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
public partial class Form1 : Form { public Form1() { InitializeComponent(); panels.Add(panelEx1); panels.Add(panelEx2); panels.Add(panelEx3); panels.Add(panelEx4); panels.Add(panelEx5); panels.Add(panelEx6); panels.Add(panelEx7); panels.Add(panelEx8); panels.Add(panelEx9); panels.Add(panelEx10); panels.Add(panelEx11); panels.Add(panelEx12); panels.Add(panelEx13); panels.Add(panelEx14); panels.Add(panelEx15); } List<PanelEx> panels = new List<PanelEx>(); private void buttonSave_Click(object sender, EventArgs e) { List<string> vs = new List<string>(); foreach (var panel in panels) vs.Add(panel.GetPath()); var xml = new System.Xml.Serialization.XmlSerializer(typeof(List<string>)); SaveFileDialog save = new SaveFileDialog(); if (save.ShowDialog() == DialogResult.OK) { var sw = new System.IO.StreamWriter(save.FileName); xml.Serialize(sw, vs); sw.Close(); } } private void buttonLoad_Click(object sender, EventArgs e) { var xml = new System.Xml.Serialization.XmlSerializer(typeof(List<string>)); OpenFileDialog open = new OpenFileDialog(); if (open.ShowDialog() == DialogResult.OK) { var sr = new System.IO.StreamReader(open.FileName); var paths = (List<string>)xml.Deserialize(sr); sr.Close(); int i = 0; foreach (var panel in panels) { panel.SetPath(paths[i]); i++; } } } } |
アイコンのうえにマウスがあると登録されているパスを表示するようにしています。
凄く参考になる記事ありがとうございます。
質問させていただきたいのですが、getPath()関数とsetPath()関数はどこで宣言されているのでしょうか? おそらく自作メソッドで宣言されていると考えているのですが…。
ご指摘ありがとうございます。PanelExクラス内にある自作メソッドです。修正しておきました。
いつも大変面白く見させて頂いてます。
このランチャーアプリですが、ドラッグアンドドロップでアイコンの入れ替えができるようになると最高なのですが、可能なのでしょうか?
新しく記事を書きました。
ランチャーアプリを改良する ドラッグアンドドロップで順序を入れ替える
https://lets-csharp.com/improve-launcher-app/