掲示板お問い合わせランダムジャンプ

Top Index
Yahooは検索方式が変わったせいか、うまくサイト内検索できないなぁ。つーわけでグーグルに変更。


2006年08月06日
Windowsスタートボタンを作ってみる
[VB2005用]
スタートボタンっぽいものを作ってみました。
(スタートボタンの「プログラム」だけを作ったというか、
(コンテキストメニューでエクスプローラーを作ったというか・・・

FileContextMenuStrip

スタートボタンを押すと、任意フォルダ配下のフォルダとファイルが列挙されます。

以下、コントロールのクラスのソース。
どうやって作ろうかと試作品を作りながら考えていたんですが、結局、「ContextMenuStrip」を拡張するのが一番簡単だという結論に到着。
あとは中身である「ToolStripMenuItem」を動的に作成し、「ContextMenuStrip」に突っ込んだらOK。

これだけだと表示しか対応していないので、「ToolStripMenuItem」をクリックしたときに発生するイベントを独自イベントとして定義。
フォームへ通知するようにしたら、完成ってことで。

001Imports System.Windows.Forms
002Imports System.IO
003
004Public Class FileContextMenuStrip
005    Inherits ContextMenuStrip
006
007    Public Event ToolStripMenuItemClick(ByVal sender As Object, ByVal e As System.EventArgs)
008
009    Private _RootDirectory As String
010    Private WithEvents MenuItem As ToolStripMenuItem
011
012    Public Sub New()
013        Me.MenuItem = New ToolStripMenuItem
014    End Sub
015
016    '基点となるディレクトリ情報。
017    '"C:\"、"C:\Documents and Settings"のような値を設定する
018    Public Property RootDirectory() As String
019        Get
020            Return _RootDirectory
021        End Get
022        Set(ByVal value As String)
023            _RootDirectory = value
024        End Set
025    End Property
026
027    'コンテキストメニュー展開前
028    'RootDirectoryを元にアイテムの初期化処理
029    Private Sub FileContextMenuStrip_Opening(ByVal sender As Object, _
030            ByVal e As System.ComponentModel.CancelEventArgs) Handles Me.Opening
031
032        Me.Items.Clear()
033        If Me.RootDirectory = "" Then Exit Sub
034
035        Me.Cursor = Cursors.WaitCursor
036
037        Dim em As IEnumerator = Me.GetItemArray(Me.RootDirectory).GetEnumerator
038        Do While em.MoveNext
039            Dim s As String = DirectCast(em.Current, String)
040
041            Me.MenuItem = Me.CreateMenuItem(s)
042
043            Me.Items.Add(Me.MenuItem)
044
045            AddHandler MenuItem.MouseHover, AddressOf MenuItem_MouseHover
046            AddHandler MenuItem.Click, AddressOf MenuItem_Click
047        Loop
048
049        Me.Cursor = Cursors.Default
050        e.Cancel = False
051    End Sub
052
053    'アイテムがフォルダである場合のみ呼び出されるイベント
054    'フォルダ内をスキャンし、ドロップダウンアイテムを検索する
055    Private Sub MenuItem_MouseHover(ByVal sender As Object, ByVal e As System.EventArgs)
056
057        Dim MItem As ToolStripMenuItem = DirectCast(sender, ToolStripMenuItem)
058        If MItem.DropDownItems.Count = 0 Then Exit Sub
059
060        Me.Cursor = Cursors.WaitCursor
061
062        '初期化
063        MItem.DropDownItems.Clear()
064
065        'アイテム配列を取得し、アイテムとして追加する
066        Dim em As IEnumerator = Me.GetItemArray(MItem.Name).GetEnumerator
067        Do While em.MoveNext
068            Dim s As String = DirectCast(em.Current, String)
069
070            Me.MenuItem = Me.CreateMenuItem(s)
071
072            MItem.DropDownItems.Add(Me.MenuItem)
073
074            AddHandler MenuItem.MouseHover, AddressOf MenuItem_MouseHover
075            AddHandler MenuItem.Click, AddressOf MenuItem_Click
076        Loop
077
078        Me.Cursor = Cursors.Default
079
080        Me.Refresh()
081    End Sub
082
083    'アイテム情報の配列。
084    'ここを書き換えれば、任意のショートカット集も作成可能 のはず
085    Friend Overridable Function GetItemArray(ByVal Path) As ArrayList
086        Dim ary As New ArrayList
087
088        Try
089            'ディレクトリ追加
090            Dim em As IEnumerator
091            em = Directory.GetDirectories(Path).GetEnumerator
092            Do While em.MoveNext
093                ary.Add(DirectCast(em.Current, String))
094            Loop
095
096            'ファイル追加
097            em = Directory.GetFiles(Path).GetEnumerator
098            Do While em.MoveNext
099                ary.Add(DirectCast(em.Current, String))
100            Loop
101        Catch ex As Exception
102            'アクセス権限がない場合、トラップしておく
103        End Try
104
105        Return ary
106    End Function
107
108    'ToolStripMenuItemを作成する
109    Private Function CreateMenuItem(ByVal Path As StringAs ToolStripMenuItem
110        Dim MItem As New ToolStripMenuItem
111        Dim hIcon As System.IntPtr
112
113        If Directory.Exists(Path) Then
114            MItem.Text = Me.LastDirectryName(Path)
115            MItem.DropDownItems.Add("") 'ダミー
116        ElseIf File.Exists(Path) Then
117            MItem.Text = IO.Path.GetFileName(Path)
118        End If
119        MItem.Name = Path
120
121        Return MItem
122    End Function
123
124    'MenuItemクリックのイベントを発生させ、実ロジックの実装を切り離す
125    Private Sub MenuItem_Click(ByVal sender As Object, ByVal e As System.EventArgs)
126        RaiseEvent ToolStripMenuItemClick(sender, e)
127    End Sub
128
129    Private Function LastDirectryName(ByVal Path As StringAs String
130        Dim c As Char = IO.Path.DirectorySeparatorChar
131        Dim Folders() As String = Split(Path, c)
132        Return Folders(UBound(Folders))
133    End Function
134End Class
 powered by vb2html ver2.1b


アイコン表示についてのロジックは以下のサイトを思いっきり参考したので、とりあえず非公開。
@IT 実行ファイルからアプリケーションのアイコンを取得するには?
http://www.atmarkit.co.jp/fdotnet/dotnettips/280getappicon/getappicon.htm

ここに記述されていることを「CreateMenuItem」関数に盛り込んだらいい感じですね。
[ 投稿者:mk3008 at 11:27 | コントロールTips | コメント(5) | トラックバック(1) ]

この記事へのコメント
たいへん勉強になります
たいへん勉強になります。しかしVB2005へ実装方法がわかりません。サンプルがあればアップしていただけないでしょうか?
投稿者: みのる at 2007-06-16 13:53:58
使い方
お返事遅れまして失礼しました。

改めてみると・・・使い方の説明はないですね^^;

利用方法としては
RootDirectoryプロパティに、ディレクトリのルートを設定(C:\,D:\など)し、Showメソッドでコントロールを表示させればOK。

具体的なサンプルはこちら。
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Me.FileContextMenuStrip1.RootDirectory = "c:\"
Me.FileContextMenuStrip1.Show(Me.Button1, Me.Button1.Width, 0)
End Sub

Showメソッドでは、どこに表示させるかを設定できます。
お好みに合わせて座標させていただければと思います。

不明点があれば、また書き込んでね。
投稿者: mk3008 at 2007-06-18 23:04:31
たびたびすみません
サンプルありがとうございます。

しかしサンプルを書いたところ「'RootDirectory' は 'System.Windows.Forms.ContextMenuStrip' のメンバではありません。」と表示されます。
クラスの使い方は超初心者のため対処法を教えてください
投稿者: みのる at 2007-06-19 06:19:34
ユーザーコントロールは難易度高め
エラーメッセージありがとうです。何が原因かわかりました。

私の作ったユーザーコントロールのプロパティやメソッドの利用方法がわからないのではなく、
ユーザーコントロール自体がわからないと思われます。


まず、お断りを入れさせてもらいますと・・・
上記のユーザーコントロールのTipsは、正直なところ初心者さんには難しすぎます。
理由は以下に関する知識が必要になるからです。

  ●継承、Inherits
  ●ユーザーコントロールの作成と使い方

もしこれらのことがわからない場合、申し訳ないですがコメントでは説明しきれません。
 (継承については、オブジェクト指向の3大機能の1つであり、
 (私の理解度では、わかりやすく説明することは不可能でしょう
書籍、googleなどで知識を得てから再度トライしてみてください。

もし、上記の知識があるのであれば、本文のプログラムソースを一度読み解いてください。
「RootDirectory」プロパティは、どのクラスのプロパティなのか、一目瞭然ですよね?
投稿者: mk3008 at 2007-06-20 00:41:00
勉強してみます
初心者に対しここまで対応していただきありがとうございます。私なりに解読しようとソースみなおがらいろいろ試みたのですがわからず、質問したしだいです。
今一度勉強しトライしてみることにします。それでもわからなければまた援助願います。ありがとうございました。
投稿者: みのる at 2007-06-20 06:06:30

この記事へのトラックバック
Windowsスタートボタンを作ってみる (フォーム側)
[VB2005用]コンテキストメニューをクリックイベントで呼ぶ処理なんてまず書かないだろうからメモ。...
投稿者: VB.NETで作る! at 2006-08-06 11:54:01

この記事へのトラックバックURL
http://shinshu.fm/MHz/88.44/a03196/0000141652.trackback

この記事の固定URL
http://shinshu.fm/MHz/88.44/archives/0000141652.html

記事へのコメント
 
認証コード:
画像に表示されるコードを半角英数字で入力して下さい。画像が読み難い場合はこちら
簡単演算認証: 5 + 9 =
足し算の答えを半角英数字で入力して下さい。
名前: [必須]
URL/Email:
タイトル:
コメント: