How to read another windows from a different program
I tried it with findwindow
and process
but it didn't work, how can I find a specific button ?
For example I have the button class AfxWnd90u
and the instance 21
. I want to check if this button is visible. I tried it with this code, but I couldn't find the button. I think I made a mistake with the instance.
Between I didn't use findwindow
here because I experimented a little bit.
//////IMPORTANT/////////////
System.Diagnostics.Process[] move = System.Diagnostics.Process.GetProcessesByName("PartyGaming");
ArrayList save = new ArrayList();
RECT rct = new RECT();
listBox1.Items.Add(move.Length);
List<System.Diagnostics.Process> process = new List<System.Diagnostics.Process>();
// use only the process with the button AfxWnd90u21
for (int i = 0; i < move.Length;++i )
{
IntPtr hCheck = FindWindowEx(move[i].MainWindowHandle, IntPtr.Zero, "AfxWnd90u21", null);
//if button is visible
if (hCheck != IntPtr.Zero)
process.Add(move[i]);
//////IMPORTANT/////////////
}
Solution 1:
I believe a combination of FindWindow and SendMessage Windows API functions will give you want you want. The tricky part will be discovering the window class names, but something like WinSpy++ could help you there.
Here's a sample of how to use the API. Open Notepad.exe a few times, type in some text and then run this sample.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
List<WinText> windows = new List<WinText>();
//find the "first" window
IntPtr hWnd = FindWindow("notepad", null);
while (hWnd != IntPtr.Zero)
{
//find the control window that has the text
IntPtr hEdit = FindWindowEx(hWnd, IntPtr.Zero, "edit", null);
//initialize the buffer. using a StringBuilder here
System.Text.StringBuilder sb = new System.Text.StringBuilder(255); // or length from call with GETTEXTLENGTH
//get the text from the child control
int RetVal = SendMessage(hEdit, WM_GETTEXT, sb.Capacity, sb);
windows.Add(new WinText() { hWnd = hWnd, Text = sb.ToString() });
//find the next window
hWnd = FindWindowEx(IntPtr.Zero, hWnd, "notepad", null);
}
//do something clever
windows.OrderBy(x => x.Text).ToList().ForEach(y => Console.Write("{0} = {1}\n", y.hWnd, y.Text));
Console.Write("\n\nFound {0} window(s).", windows.Count);
Console.ReadKey();
}
private struct WinText
{
public IntPtr hWnd;
public string Text;
}
const int WM_GETTEXT = 0x0D;
const int WM_GETTEXTLENGTH = 0x0E;
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", SetLastError = true)]
public static extern int SendMessage(IntPtr hWnd, int msg, int Param, System.Text.StringBuilder text);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
}
}
Solution 2:
Autoit provides a great way to interact with Windows.
Install the nuget package called AutoItX.Dotnet
using AutoIt;
class Program
{
static void Main(string[] args)
{
var buttonVisible = AutoItX.ControlCommand("Untitled - Notepad", "", "[CLASSNN:Edit1]", "IsVisible", "");
//in your case it would be:
//var buttonVisible = AutoItX.ControlCommand("Put the application title here", "", "[CLASSNN:AfxWnd90u21]", "IsVisible", "");
if (buttonVisible == "1")
{
Console.WriteLine("Visible");
} else
{
Console.WriteLine("Not visible");
}
}
}