tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板)
VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板)
[ツリー表示へ]  [ワード検索]  [Home]

タイトル Re: 【解決】Re^8: Process.GetProcessesの表示順につきまして
投稿日: 2011/05/09(Mon) 12:16
投稿者YuO
解決されてはいる物の,やらない方がよいことをされているようなので……。

>         Public 配列_notepad(1)() As Object
>         Dim リスト_StartTime As ArrayList = New ArrayList
>         Dim リスト_WindowTitle As ArrayList = New ArrayList

これらはやめた方が良いです。

・Objectの配列→本当にObjectの配列でないなら使わない
 今回の場合,クラスまたは構造体を一つ作って使うことになります。
 .NET Framework4以降にはTupleクラスという物があるのですが……。
・System.Collectionsのコレクション→System.Collections.Genericのコレクションを使う
 ArrayListよりList(Of T),HashtableよりDictionary(Of TKey, TValue)


ちなみに,Array.FindAllメソッドを使うと,配列の絞り込みができます。
MSDN: Array.FindAll(T) メソッド (System)
http://msdn.microsoft.com/ja-jp/library/1kkxfxdd(VS.90).aspx
また,配列のソートに比較関数を渡すことができます。
MSDN: Array.Sort(T) メソッド (T[], Comparison(T)) (System)
http://msdn.microsoft.com/ja-jp/library/cxt053xf(VS.90).aspx
これらを使って,

' ここから
' 元のコードの置き換え部分
Dim processes As Process() = Process.GetProcesses()
Dim notepads As Process() = Array.FindAll(processes, AddressOf Notepadプロセスの検索)
Array.Sort(notepads, AddressOf Notepadプロセスのソート)

' ここから下はメソッドの外側
' 絞り込みやソートの為の関数群
Shared Function Notepadプロセスの検索 (ByVal p As Process) As Boolean
  If p Is Nothing Then Return False
  If p.MainWindowHandle = IntPtr.Zero Then Return False
  ' 明示的に「大文字・小文字を区別しない」比較を行う
  Return String.Equals(p.ProcessName, "notepad", StringComparison.InvariantCultureIgnoreCase)
End Function

Shared Function Notepadプロセスのソート (ByVal x As Process, ByVal y As Process) As Integer
  If x Is y Then Return 0
  If x Is Nothing Then Return -1
  If y Is Nothing Then Return 1
  ' ウィンドウタイトルでの比較
  Dim titleResult As Integer = x.MainWindowTitle.CompareTo(y.MainWindowTitle)
  ' ウィンドウタイトルが異なれば,ウィンドウタイトルの比較結果でソートする
  If startTimeResult <> 0 Then Return startTimeResult
  ' ウィンドウタイトルが同じであれば,開始時間の比較結果でソートする
  Return x.StartTime.CompareTo(y.StartTime)
End Function
' ここまで

のようにも書けます。


VB 2008ならLINQが使えるので……。
For Each p In _
  From p0 In Process.GetProcesses() _
  Where p0 IsNot Nothing _
  Where p0.MainWindowHandle <> IntPtr.Zero _
  Where String.Equals(p0.ProcessName, "notepad", StringComparison.InvariantCultureIgnoreCase) _
  Order By p0.MainWindowTitle, p0.StartTime

    MsgBox(p.StartTime & "/" & p.MainWindowTitle)
Next
または,
For Each p In _
  Process.GetProcesses() _
  .Where(Function(p0) p0 IsNot Nothing) _
  .Where(Function(p0) p0.MainWindowHandle <> IntPtr.Zero) _
  .Where(Function(p0) String.Equals(p0.ProcessName, "notepad", StringComparison.InvariantCultureIgnoreCase)) _
  .OrderBy(Function(p0) p0.MainWindowTitle) _
  .ThenBy(Function(p0) p0.StartTime)

    MsgBox(p.StartTime & "/" & p.MainWindowTitle)
Next
と書くこともできます。
# 個人的には後者が好きだけれど,VBだとFunctionって記述が面倒……。

- 関連一覧ツリー をクリックするとツリー全体を一括表示します)

古いスレッドにレスはつけられません。