Click here to Skip to main content
15,895,746 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
See more:
How To Find main Window Title name of application In running In Tray Or Taskbar
Posted
Comments
Sergey Alexandrovich Kryukov 31-Aug-13 2:11am    
Not clear. Why would you need to find anything? if the form is in your application, you already have a reference to it...
—SA

It seems like you want to get a list of all the running applications on your machine so you can look for one by main window title, right?

Here's a class I found somewhere online, and modified a bit:

VB
Imports System.Runtime.InteropServices

Public Class clsEnumWindows
    <unmanagedfunctionpointerattribute(callingconvention.stdcall)> _
    Public Delegate Function EnumWindowsProc(ByVal hwnd As System.IntPtr, ByVal lparam As System.IntPtr) As Boolean

    <dllimportattribute("user32.dll",> _
    Public Shared Function EnumWindows(ByVal lpEnumFunc As EnumWindowsProc, <marshalasattribute(unmanagedtype.sysint)> ByVal lParam As IntPtr) As <marshalasattribute(unmanagedtype.bool)> Boolean
    End Function

    <dllimportattribute("user32.dll",> _
    Public Shared Function IsWindowVisible(<inattribute()> ByVal hWnd As System.IntPtr) As <marshalasattribute(unmanagedtype.bool)> Boolean
    End Function

    <dllimportattribute("user32.dll",> _
    Public Shared Function GetWindowText(<inattribute()> ByVal hWnd As System.IntPtr, <outattribute(),> ByVal lpString As System.Text.StringBuilder, ByVal nMaxCount As Integer) As Integer
    End Function

    <dllimportattribute("user32.dll",> _
    Public Shared Function GetWindowTextLength(<inattribute()> ByVal hWnd As System.IntPtr) As Integer
    End Function

    <dllimportattribute("user32.dll",> _
    Public Shared Function GetWindowThreadProcessId(<inattribute()> ByVal hWnd As System.IntPtr, <outattribute()> ByRef lpdwProcessId As Integer) As UInteger
    End Function

    <dllimportattribute("user32.dll",> _
    Public Shared Function GetClassName(<inattribute()> ByVal hWnd As System.IntPtr, <outattribute(),> ByVal lpClassName As System.Text.StringBuilder, ByVal nMaxCount As Integer) As Integer
    End Function

    Public Shared Function GetWindows() As List(Of ManagedWindow)
        Dim WindowList As New List(Of ManagedWindow)
        Dim ListHandle As GCHandle = GCHandle.Alloc(WindowList)
        Try
            clsEnumWindows.EnumWindows(New clsEnumWindows.EnumWindowsProc(AddressOf EnumWindowsCallBack), GCHandle.ToIntPtr(ListHandle))
        Finally
            ListHandle.Free()
        End Try
        Return WindowList
    End Function

    Private Shared Function EnumWindowsCallBack(ByVal handle As IntPtr, ByVal lParam As IntPtr) As Boolean
        If clsEnumWindows.IsWindowVisible(handle) Then
            Dim TitleBuilder As New System.Text.StringBuilder(clsEnumWindows.GetWindowTextLength(handle) + 1)
            Dim WndList As List(Of ManagedWindow) = DirectCast(GCHandle.FromIntPtr(lParam).Target, List(Of ManagedWindow))
            clsEnumWindows.GetWindowText(handle, TitleBuilder, TitleBuilder.Capacity)
            Dim ProcessID As Integer = -1
            clsEnumWindows.GetWindowThreadProcessId(handle, ProcessID)
            Dim ClassNameBuilder As New System.Text.StringBuilder(255)
            clsEnumWindows.GetClassName(handle, ClassNameBuilder, ClassNameBuilder.Capacity)
            WndList.Add(New ManagedWindow(handle, TitleBuilder.ToString, Process.GetProcessById(ProcessID), ClassNameBuilder.ToString))
        End If
        Return True 'Tells the EnumWindows API to keep going and call this function again for the next window
    End Function

    Public Class ManagedWindow
        Private _Title As String = String.Empty

        Public Property Title() As String
            Get
                Return _Title
            End Get
            Set(ByVal value As String)
                _Title = value
            End Set
        End Property

        Private _Handle As IntPtr

        Public Property Handle() As IntPtr
            Get
                Return _Handle
            End Get
            Set(ByVal value As IntPtr)
                _Handle = value
            End Set
        End Property

        Private _OwningProcess As Process

        Public Property OwningProcess() As Process
            Get
                Return _OwningProcess
            End Get
            Set(ByVal value As Process)
                _OwningProcess = value
            End Set
        End Property

        Private _ClassName As String = String.Empty

        Public Property ClassName() As String
            Get
                Return _ClassName
            End Get
            Set(ByVal value As String)
                _ClassName = value
            End Set
        End Property

        Public Sub New()
        End Sub

        Public Sub New(ByVal Hwnd As IntPtr, ByVal TitleText As String, ByVal Owner As Process, ByVal NativeClassName As String)
            _Handle = Hwnd
            _Title = TitleText
            _OwningProcess = Owner
            _ClassName = NativeClassName
        End Sub

        Public Overrides Function ToString() As String
            If OwningProcess Is Nothing Then
                Return Handle.ToString & " —- " & ClassName & " —- " & Title
            Else
                Return Handle.ToString & " —- " & ClassName & " —- " & Title & " —- " & OwningProcess.ProcessName
            End If
        End Function

    End Class

End Class


To see how it works, create a new vb.net windows forms application. Add this class, drop a listbox on form1, and put this code in Form1_Load:

VB
Dim windows As List(Of clsEnumWindows.ManagedWindow) = clsEnumWindows.GetWindows

For Each window As clsEnumWindows.ManagedWindow In windows
   Me.ListBox1.Items.Add(window.Title)
Next


Then run it. I hope looking at that simple code example (the stuff in form_load), this class's usage is clear.

- Pete
 
Share this answer
 
v2
Comments
Yogesh N Sh 3-Sep-13 1:50am    
Yes.Its Work But it work only when My application Is Minimize in task Bar.But Not Working In tray When My Application is Running In tray Its Not Work
I ti snot absolutely clear what your final goal is, but run this snippet, and see:
C#
foreach(var p in Process.GetProcesses()){
    Console.WriteLine("Process: {0} ID: {1}, Main window title: {2}", p.ProcessName, p.Id, p.MainWindowTitle);
}


[Update: listing all window titles, based on the link below]

C#
delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam);

[DllImport("user32.dll")]
static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn,
    IntPtr lParam);

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, 
    StringBuilder lParam);

private const uint WM_GETTEXT = 0x000D;

static IEnumerable<IntPtr> EnumerateProcessWindowHandles(int processId)
{
    var handles = new List<IntPtr>();

    foreach (ProcessThread thread in Process.GetProcessById(processId).Threads)
        EnumThreadWindows(thread.Id, 
            (hWnd, lParam) => { handles.Add(hWnd); return true; }, IntPtr.Zero);

    return handles;
}

[STAThread]
void Main()
{
	foreach(var p in Process.GetProcesses()){
		Console.WriteLine(">> Process: {0} ID: {1}, Main window title: {2}\nWindows:", p.ProcessName, p.Id, p.MainWindowTitle);
	    foreach (var handle in EnumerateProcessWindowHandles(p.Id))
		{
			StringBuilder message = new StringBuilder(1000);
			SendMessage(handle, WM_GETTEXT, message.Capacity, message);
			Console.WriteLine(message.ToString());
		}
		Console.WriteLine("<<\n\n");
	}
}
 
Share this answer
 
v2
Comments
Yogesh N Sh 3-Sep-13 1:52am    
Yes.Its Work But it work only when My application Is Minimize in task Bar.But Not Working In tray When My Application is Running In tray Its Not Work
Zoltán Zörgő 3-Sep-13 4:30am    
You won't be able to get that title, because the try icon is not a minimized window. It is a separate object, and in general it will create the window on a specific event and destroy it when not needed anymore. If it is only hidden, you will see it in the list.
If you need all windows not only the main ones, you can use the EnumThreadWindows API function. The P/Invoke for it and sample can be found here: http://stackoverflow.com/questions/2531828/how-to-enumerate-all-windows-belonging-to-a-particular-process-using-net#answer-2584672.
But remember: you can not list widows, that do not exist at a specific point in time!
If you just want to get a list of ALL the running processes on the machine so you can find an application running in the systray, it's even simpler. Use this:

VB
For Each proc As Process In Process.GetProcesses
   ListBox1.Items.Add(proc.ProcessName)
Next


I tested this a moment ago, and found two of my own apps that are running in the systray.

- Pete
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900