WuLabs
asked on
I need FindWindowLike for C#
I need a FindWindowLike implementation in C#, or at least something that does the same thing. THe idea is a findwindow with wildcards. THere is currently an implementation in VB but i was not able to convert it.
ASKER
Maybe i was not clear. I need findwindow WITH WILDCARDS. Like this: http://support.microsoft.com/kb/147659
Here is an implementation after converting the code from that Micro$oft article:
using System;
using System.Collections;
using System.Runtime.InteropServ ices;
using System.Text;
namespace My.Computer
{
public class FindWindowLike
{
public class Window
{
public string Title;
public string Class;
public int Handle;
}
[DllImport("user32")]
private static extern int GetWindow(int hwnd, int wCmd);
[DllImport("user32")]
private static extern int GetDesktopWindow();
[DllImport("user32", EntryPoint="GetWindowLongA ")]
private static extern int GetWindowLong(int hwnd, int nIndex);
[DllImport("user32")]
private static extern int GetParent(int hwnd);
[DllImport("user32", EntryPoint="GetClassNameA" )]
private static extern int GetClassName(
int hWnd, [Out] StringBuilder lpClassName, int nMaxCount);
[DllImport("user32", EntryPoint="GetWindowTextA ")]
private static extern int GetWindowText(
int hWnd, [Out] StringBuilder lpString, int nMaxCount);
private const int GWL_ID = (-12);
private const int GW_HWNDNEXT = 2;
private const int GW_CHILD = 5;
public static Window[] Find(int hwndStart, string findText, string findClassName)
{
ArrayList windows = DoSearch(hwndStart, findText, findClassName);
return (Window[])windows.ToArray( typeof(Win dow));
} //Find
private static ArrayList DoSearch(int hwndStart, string findText, string findClassName)
{
ArrayList list = new ArrayList();
if (hwndStart == 0)
hwndStart = GetDesktopWindow();
int hwnd = GetWindow(hwndStart, GW_CHILD);
while (hwnd != 0)
{
// Recursively search for child windows.
list.AddRange(DoSearch(hwn d, findText, findClassName));
StringBuilder text = new StringBuilder(255);
int rtn = GetWindowText(hwnd, text, 255);
string windowText = text.ToString();
windowText = windowText.Substring(0, rtn);
StringBuilder cls = new StringBuilder(255);
rtn = GetClassName(hwnd, cls, 255);
string className = cls.ToString();
className = className.Substring(0, rtn);
if (GetParent(hwnd) != 0)
rtn = GetWindowLong(hwnd, GWL_ID);
if (windowText.Length > 0 && windowText.StartsWith(find Text) &&
(className.Length == 0 || className.StartsWith(findC lassName)) )
{
Window currentWindow = new Window();
currentWindow.Title = windowText;
currentWindow.Class = className;
currentWindow.Handle = hwnd;
list.Add(currentWindow);
}
hwnd = GetWindow(hwnd, GW_HWNDNEXT);
}
return list;
} //DoSearch
} //Class
} //Namespace
Test usage:
My.Computer.FindWindowLike .Window[] list = My.Computer.FindWindowLike .Find(0, "Document1", "");
Bob
using System;
using System.Collections;
using System.Runtime.InteropServ
using System.Text;
namespace My.Computer
{
public class FindWindowLike
{
public class Window
{
public string Title;
public string Class;
public int Handle;
}
[DllImport("user32")]
private static extern int GetWindow(int hwnd, int wCmd);
[DllImport("user32")]
private static extern int GetDesktopWindow();
[DllImport("user32", EntryPoint="GetWindowLongA
private static extern int GetWindowLong(int hwnd, int nIndex);
[DllImport("user32")]
private static extern int GetParent(int hwnd);
[DllImport("user32", EntryPoint="GetClassNameA"
private static extern int GetClassName(
int hWnd, [Out] StringBuilder lpClassName, int nMaxCount);
[DllImport("user32", EntryPoint="GetWindowTextA
private static extern int GetWindowText(
int hWnd, [Out] StringBuilder lpString, int nMaxCount);
private const int GWL_ID = (-12);
private const int GW_HWNDNEXT = 2;
private const int GW_CHILD = 5;
public static Window[] Find(int hwndStart, string findText, string findClassName)
{
ArrayList windows = DoSearch(hwndStart, findText, findClassName);
return (Window[])windows.ToArray(
} //Find
private static ArrayList DoSearch(int hwndStart, string findText, string findClassName)
{
ArrayList list = new ArrayList();
if (hwndStart == 0)
hwndStart = GetDesktopWindow();
int hwnd = GetWindow(hwndStart, GW_CHILD);
while (hwnd != 0)
{
// Recursively search for child windows.
list.AddRange(DoSearch(hwn
StringBuilder text = new StringBuilder(255);
int rtn = GetWindowText(hwnd, text, 255);
string windowText = text.ToString();
windowText = windowText.Substring(0, rtn);
StringBuilder cls = new StringBuilder(255);
rtn = GetClassName(hwnd, cls, 255);
string className = cls.ToString();
className = className.Substring(0, rtn);
if (GetParent(hwnd) != 0)
rtn = GetWindowLong(hwnd, GWL_ID);
if (windowText.Length > 0 && windowText.StartsWith(find
(className.Length == 0 || className.StartsWith(findC
{
Window currentWindow = new Window();
currentWindow.Title = windowText;
currentWindow.Class = className;
currentWindow.Handle = hwnd;
list.Add(currentWindow);
}
hwnd = GetWindow(hwnd, GW_HWNDNEXT);
}
return list;
} //DoSearch
} //Class
} //Namespace
Test usage:
My.Computer.FindWindowLike
Bob
ASKER
Hi Bob,
Your code compiles and runs, but does not provide the exact same functionality as http://support.microsoft.com/kb/147659. For example when I run to find window caption "*", * does not work as a wildcard. See examples in the link provided. Such examples do not work with your code. The code you provided only searches for windows which contain X, where X is the window caption I am looking for.
What you provided works for what I need. But, I will not award you the full points unless you provide me with the exact function that fullfills the spec.
I will award 500 pts + A to you if you can provide me with an updated full function.
Otherwise I will award 250 points + B to you.
You have a few days. Thanks!
Your code compiles and runs, but does not provide the exact same functionality as http://support.microsoft.com/kb/147659. For example when I run to find window caption "*", * does not work as a wildcard. See examples in the link provided. Such examples do not work with your code. The code you provided only searches for windows which contain X, where X is the window caption I am looking for.
What you provided works for what I need. But, I will not award you the full points unless you provide me with the exact function that fullfills the spec.
I will award 500 pts + A to you if you can provide me with an updated full function.
Otherwise I will award 250 points + B to you.
You have a few days. Thanks!
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Will this code work in a C# Service
You could use Windows API to do this.
For example, this will get handles and window text's of all windows which have text (titles).
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServ
using System.Text;
namespace WindowsApplication6
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Butto
private System.Windows.Forms.ListB
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Cont
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Butto
this.listBox1 = new System.Windows.Forms.ListB
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(544, 40);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(160, 40);
this.button1.TabIndex = 0;
this.button1.Text = "Find";
this.button1.Click += new System.EventHandler(this.b
//
// listBox1
//
this.listBox1.Location = new System.Drawing.Point(24, 32);
this.listBox1.Name = "listBox1";
this.listBox1.Size = new System.Drawing.Size(512, 264);
this.listBox1.TabIndex = 1;
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(704, 334);
this.Controls.AddRange(new
this.listBox1,
this.button1});
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[DllImport("user32.dll")]
public static extern bool EnumWindows(CallBack lpEnumFunc, Int32 lParam);
[DllImport("user32.dll")]
public static extern Int32 GetWindowText(Int32 hwnd, StringBuilder lpString, Int32 cch);
[DllImport("user32.dll")]
public static extern Int32 GetWindowTextLength (Int32 hwnd);
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
public delegate bool CallBack(int hwnd, int lParam);
private void button1_Click(object sender, System.EventArgs e)
{
listBox1.Items.Clear();
CallBack myCallBack = new CallBack(EnumWindowsProc);
EnumWindows (myCallBack,0);
}
private bool EnumWindowsProc (Int32 hwnd, Int32 lParam)
{
StringBuilder WindowText = new StringBuilder(1024);
int WindowTextLength;
WindowTextLength = GetWindowTextLength(hwnd) + 1;
GetWindowText(hwnd,WindowT
if (WindowText.ToString().Tri
listBox1.Items.Add(hwnd.To
return true;
}
}
}