|
С# Средство разработки на платформе .Net |
30.09.2011, 05:14
|
#1
|
Бывалый
Регистрация: 16.09.2011
Сообщений: 863
Написано 257 полезных сообщений (для 546 пользователей)
|
Пару вопросов на счет окон.
Как получить список всех открытых окон? (их handle)
Как узнать координаты и размеры окна по его handle.
Как изменить координаты и размеры окна по его handle.
Как прочитать заголовок окна по его handle.
???
|
(Offline)
|
|
30.09.2011, 09:24
|
#2
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: Пару вопросов на счет окон.
Вам дорога в WinAPI. Стандартных средств в NetFramework вроде нет для таких целей.
Получение окон:
private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern bool EnumWindows(EnumWindowsProc callback, IntPtr extraData);
Получение размера:
[DllImport("user32.dll")] private static extern bool GetWindowRect(IntPtr hWnd, ref Rectangle rect);
и т.д.
Вобщем ищите тут: Window Functions
|
(Offline)
|
|
Эти 2 пользователя(ей) сказали Спасибо pax за это полезное сообщение:
|
|
04.10.2011, 10:35
|
#3
|
Бывалый
Регистрация: 16.09.2011
Сообщений: 863
Написано 257 полезных сообщений (для 546 пользователей)
|
Ответ: Пару вопросов на счет окон.
Кстати, ради интереса.
Что означают эти флаги?)
CharSet = CharSet.Auto, SetLastError = true
кстати заметил багу +) У выдоваемого прямоугольника свойства Height и Width эквивалентны значениям Bottom и Right(тем что должны быть на самом деле). Bottom и Right получаются совсем бредовыми,
т.к. они равны Height + Top и Width + Left соответственно.
Но при неправильных Height и Width , получается что Bottom = Height + 2*Top и Right = Width + 2*Left (с правильными Height и Width).
|
(Offline)
|
|
04.10.2011, 18:05
|
#4
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: Пару вопросов на счет окон.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
01.11.2013, 03:36
|
#5
|
AnyKey`щик
Регистрация: 01.11.2013
Сообщений: 14
Написано 0 полезных сообщений (для 0 пользователей)
|
Ответ: Пару вопросов на счет окон.
Прошу прощения. Я совсем начинающий программист и обладаю минимальными познаниями. Я медленно и уверено продолжаю своё обучение. И пробую написание простейших программ. У меня убедительная просьба не игнорить меня как это делали на других форумах.
Дело в том что я столкнулся с проблемой(для меня) это API(EnumWindows function в частности), и ни как не могу понять принцип её работы. И не могу найти подходящей для меня(чайника) статьи урока на русском где разжёвано описывалось нужная информация.
Я прошу помогите найти что-нибудь. Или попробуйте объяснить как мне использовать эту функцию EnumWindows function . Я хочу вывести все окна выбранного мной процесса на консоль. Привожу код. Может быть поправите мой код полностью , а я попробую сообразить что и как для чего делалась. Постараюсь больше не кляньчить ...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
namespace pb0._1
{
class Program
{
private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool EnumWindows(EnumWindowsProc callback, IntPtr extraData);
static void Main(string[] args)
{
System.Diagnostics.Process[] allprocess = System.Diagnostics.Process.GetProcesses();
Console.WriteLine("Создана allprocess, в неё записаны все процессы. Количество : " + allprocess.Length);
System.Diagnostics.Process[] xxxprocess = System.Diagnostics.Process.GetProcessesByName("xxx");
Console.WriteLine("Создана xxxprocess, в неё записаны процессы с именем xxx. Количество : " + xxxprocess.Length);
// Console.WriteLine("{0}", allprocess); // вывести имя процесса под номером указанном в "{}"
// проинициализировать переменную NeedHandle
foreach (System.Diagnostics.Process anti in System.Diagnostics.Process.GetProcesses()) // перебираем все процесы
{
if (anti.MainWindowTitle.ToString() == "abcd") // находим окно по точному заголовку окна
// if (anti.MainWindowTitle.StartsWith("abcd")) // находим окно по первой букве заголовка окна
{
Console.WriteLine("Найдено окно c заголовком abcd");
IntPtr handle = anti.MainWindowHandle;
Console.WriteLine("Создаём IntPtr handle переменную и присваиваем ей указатель на найденое окно");
}
}
Console.ReadLine();
// using System.Diagnostics;
// using System.IO;
// Process process = Process.GetProcesses().FirstOrDefault(x => x.ProcessName == "calc");
// IntPtr handle = (process != null) ? process.MainWindowHandle : IntPtr.Zero;
}
}
}
|
(Offline)
|
|
01.11.2013, 07:15
|
#6
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: Пару вопросов на счет окон.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
01.11.2013, 20:14
|
#7
|
AnyKey`щик
Регистрация: 01.11.2013
Сообщений: 14
Написано 0 полезных сообщений (для 0 пользователей)
|
Ответ: Пару вопросов на счет окон.
Спасибо. Код делает именно то что мне нужно. Пытаюсь понять как он работает, но без подходящего урока нечего не выходит.
|
(Offline)
|
|
02.11.2013, 09:21
|
#8
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: Пару вопросов на счет окон.
EnumThreadWindows - перебирает окна указанного потока
EnumerateProcessWindowHandles - для переданного id процесса получает все потоки и для каждого потока вызывает функцию EnumThreadWindows с лямбда-выражением - функция которая записывает хэндлы окон в коллекцию.
SendMessage с мессаджем WM_GETTEXT получает текст окна по его хэндлу, потом этот текст выводится в консоль.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
02.11.2013, 17:52
|
#9
|
AnyKey`щик
Регистрация: 01.11.2013
Сообщений: 14
Написано 0 полезных сообщений (для 0 пользователей)
|
Ответ: Пару вопросов на счет окон.
Вопрос немного про другую функцию
FindWindow("Class", "Windows")
Можноли присвоить с помощью её указатель на окно зная только имя класса? Название окна постоянно меняется, а окно с нужным классом единственное.
|
(Offline)
|
|
02.11.2013, 18:04
|
#10
|
AnyKey`щик
Регистрация: 01.11.2013
Сообщений: 14
Написано 0 полезных сообщений (для 0 пользователей)
|
Ответ: Пару вопросов на счет окон.
Сам нашёл ответ на свой глупый вопрос, может быть кому-то будет полезным.
Вместо неизвестного имени окна ставим значение null
FindWindow("Class", null)
Поправьте если чтото не так.
И сразу возникает второй вопрос. А если всёже этих окон будет больше чем одно. Как присвоить каждому указатель на окно?
|
(Offline)
|
|
02.11.2013, 21:12
|
#11
|
AnyKey`щик
Регистрация: 01.11.2013
Сообщений: 14
Написано 0 полезных сообщений (для 0 пользователей)
|
Ответ: Пару вопросов на счет окон.
Как должна выглядеть запись чтобы FindWindow искало только в указанном процессе?
|
(Offline)
|
|
02.11.2013, 22:44
|
#12
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: Пару вопросов на счет окон.
Собрал в один исходник
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks;
namespace ConsoleApplication1 { class Program { delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam);
[DllImport("user32.dll")] static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam);
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; }
private const uint WM_GETTEXT = 0x000D;
[DllImport("user32.dll", CharSet = CharSet.Auto)] static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, StringBuilder lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount );
public static string GetWindowClassName(IntPtr hWnd) { StringBuilder buffer = new StringBuilder(128); GetClassName(hWnd, buffer, buffer.Capacity); return buffer.ToString().Trim(); }
public static string GetWindowName(IntPtr hWnd) { StringBuilder message = new StringBuilder(1000); SendMessage(hWnd, WM_GETTEXT, message.Capacity, message); return message.ToString().Trim(); }
public static IntPtr FindWindowByNameInProcess(string windowName, string processName) { var processWindowHandles = EnumerateProcessWindowHandles( Process.GetProcessesByName("explorer").First().Id);
foreach (var handle in processWindowHandles) { if (GetWindowName(handle).StartsWith(windowName)) { return handle; } }
return IntPtr.Zero; }
public static IntPtr FindWindowByClassInProcess(string windowClassName, string processName) { var processWindowHandles = EnumerateProcessWindowHandles( Process.GetProcessesByName("explorer").First().Id);
foreach (var handle in processWindowHandles) { if (GetWindowClassName(handle).StartsWith(windowClassName)) { return handle; } }
return IntPtr.Zero; }
[STAThread] static void Main(string[] args) { foreach (var handle in EnumerateProcessWindowHandles( Process.GetProcessesByName("explorer").First().Id)) { Console.WriteLine("Name: "+GetWindowName(handle)); Console.WriteLine("Class: " + GetWindowClassName(handle)); }
// поиск по имени класса var hwnd = FindWindowByClassInProcess("tool", "explorer"); if (hwnd != IntPtr.Zero) { Console.WriteLine("Finded Name: " + GetWindowName(hwnd)); Console.WriteLine("Finded Class: " + GetWindowClassName(hwnd)); }
// поиск по имени окна hwnd = FindWindowByNameInProcess("Перек", "explorer"); if (hwnd != IntPtr.Zero) { Console.WriteLine("Finded Name: " + GetWindowName(hwnd)); Console.WriteLine("Finded Class: " + GetWindowClassName(hwnd)); }
Console.ReadLine();
} } }
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
02.11.2013, 22:57
|
#13
|
AnyKey`щик
Регистрация: 01.11.2013
Сообщений: 14
Написано 0 полезных сообщений (для 0 пользователей)
|
Ответ: Пару вопросов на счет окон.
Спасибо большое, за твою помощь. Сейчас буду вникать в твой код.
У меня появился ещё вопрос. Про функцию EnumChildWindows.
Console.WriteLine(EnumChildWindows(hwnd, xxx, yyy );
Что нужно указать вместо ххх и yyy?
Привожу код.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
namespace proba01
{
class Program
{
delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
[DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool EnumChildWindows(IntPtr hWndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam);
static void Main(string[] args)
{
IntPtr hwnd = FindWindow("Class", null);
if (hwnd == IntPtr.Zero)
{
Console.WriteLine("окно не найдено");
}
else
{
Console.WriteLine("окно найдено. Указатель : "+hwnd);
Console.WriteLine(EnumChildWindows(hwnd, xxx, yyy );
}
Console.ReadKey();
}
}
}
|
(Offline)
|
|
02.11.2013, 23:23
|
#14
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: Пару вопросов на счет окон.
Примерно так:
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Runtime.InteropServices; using System.Text;
namespace ConsoleApplication1 { class Program { delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam);
[DllImport("user32.dll")] static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam);
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; }
private const uint WM_GETTEXT = 0x000D;
[DllImport("user32.dll", CharSet = CharSet.Auto)] static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, StringBuilder lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount );
public static string GetWindowClassName(IntPtr hWnd) { StringBuilder buffer = new StringBuilder(128); GetClassName(hWnd, buffer, buffer.Capacity); return buffer.ToString().Trim(); }
public static string GetWindowName(IntPtr hWnd) { StringBuilder message = new StringBuilder(1000); SendMessage(hWnd, WM_GETTEXT, message.Capacity, message); return message.ToString().Trim(); }
public static IntPtr FindWindowByNameInProcess(string windowName, string processName) { var processWindowHandles = EnumerateProcessWindowHandles( Process.GetProcessesByName("explorer").First().Id);
foreach (var handle in processWindowHandles) { if (GetWindowName(handle).StartsWith(windowName)) { return handle; } }
return IntPtr.Zero; }
public static IntPtr FindWindowByClassInProcess(string windowClassName, string processName) { var processWindowHandles = EnumerateProcessWindowHandles( Process.GetProcessesByName("explorer").First().Id);
foreach (var handle in processWindowHandles) { if (GetWindowClassName(handle).StartsWith(windowClassName)) { return handle; } }
return IntPtr.Zero; }
public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
[DllImport("USER32.DLL", CharSet = CharSet.Unicode)] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool EnumChildWindows(IntPtr hWndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam);
[STAThread] static void Main(string[] args) { foreach (var handle in EnumerateProcessWindowHandles( Process.GetProcessesByName("explorer").First().Id)) { Console.WriteLine("Name: " + GetWindowName(handle)); Console.WriteLine("Class: " + GetWindowClassName(handle)); }
// поиск по имени класса var hwnd = FindWindowByClassInProcess("tool", "explorer"); if (hwnd != IntPtr.Zero) { Console.WriteLine("Finded Name: " + GetWindowName(hwnd)); Console.WriteLine("Finded Class: " + GetWindowClassName(hwnd)); }
// поиск по имени окна hwnd = FindWindowByNameInProcess("Меню", "explorer"); if (hwnd != IntPtr.Zero) { Console.WriteLine("Finded Name: " + GetWindowName(hwnd)); Console.WriteLine("Finded Class: " + GetWindowClassName(hwnd));
var childWindows = new List<IntPtr>();
EnumChildWindows( hwnd, (childHandle, lParam) => { childWindows.Add(childHandle); return true; }, IntPtr.Zero);
foreach (var handle in childWindows) { Console.WriteLine("Child Window Name: " + GetWindowName(handle)); Console.WriteLine("Child Window Class: " + GetWindowClassName(handle)); } }
Console.ReadLine();
} } }
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
02.11.2013, 23:28
|
#15
|
AnyKey`щик
Регистрация: 01.11.2013
Сообщений: 14
Написано 0 полезных сообщений (для 0 пользователей)
|
Ответ: Пару вопросов на счет окон.
Спасибо ещё раз, материала переваривать предостаточно +_-
|
(Offline)
|
|
Ваши права в разделе
|
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 09:55.
|