Модераторы: gambit, Partizan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> EnumChildWindows - не могу найти под-окно, не могу разобраться... 
V
    Опции темы
theHelg
Дата 17.10.2009, 18:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 74
Регистрация: 23.6.2009

Репутация: нет
Всего: нет



Добрый день!

не могу разобраться!
Пытаюсь найти хэндл на суб-окно в клиенте.
Вижу через InqSoft Window Scanner, что в чужом клиенте у главного окна есть под-окно с классом Internet Explorer_Server.

И что-то у меня не получается правильно все прописать...
В чем ошибка?


Код

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
        [DllImport("user32.dll")]
        public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
        [DllImport("User32.dll")]
        public static extern bool EnumChildWindows(IntPtr hWndParent,
            EnumChildProcDelegate lpEnumFunc,
            IntPtr lParam);

        public delegate bool EnumChildProcDelegate(IntPtr hWnd, IntPtr LParam);

        static bool EnumChildProc(IntPtr hWnd, IntPtr lParam)
        {
            const int CAPACITY = 256;
            StringBuilder className = new StringBuilder(CAPACITY);
            GetClassName(hWnd, className, CAPACITY);

            if (className.ToString() == "Internet Explorer_Server")
            {
                //нашли нужный класс
                ClassNativeMethods.handle = hWnd;
                return false;
            }
            //продолжаем поиск
            return true;
        }

        public void findIEwindow()
        {
            //IntPtr hWndExplorer - ссылка на мое окно;
            EnumChildProcDelegate enumChildProc = new EnumChildProcDelegate(EnumChildProc);
            //Перечисляем все дочерние окна моего окна
            EnumChildWindows(tksClientHandle, enumChildProc, tksClientHandle);
        }

// ну и собственно сам вызов
        public static void Main()
        {
            //IntPtr tClientHandle - ссылка на главное окно;
            EnumChildProcDelegate enumChildProc = new EnumChildProcDelegate(EnumChildProc);
            //Перечисляем все дочерние окна моего окна
            EnumChildWindows(tClientHandle, enumChildProc, tClientHandle);
        }


PM MAIL   Вверх
LamerTM
Дата 18.10.2009, 14:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 97
Регистрация: 11.3.2006

Репутация: нет
Всего: 0



Код

        [DllImport("User32.dll")]
        public static extern bool EnumChildWindows(IntPtr hWndParent,
            EnumChildProcDelegate lpEnumFunc,
            IntPtr lParam);

        public delegate bool EnumChildProcDelegate(IntPtr hWnd, IntPtr LParam);


Попробуй этот код изменить на такой:

Код

        [DllImport("User32.dll")]
        public static extern bool EnumChildWindows(IntPtr hWndParent,
            EnumChildProcDelegate lpEnumFunc,
            ref IntPtr lParam);

        public delegate bool EnumChildProcDelegate(IntPtr hWnd, ref IntPtr LParam);


Ну и соответственно во всех вызовах этих функций сделать то же самое.
У меня аналогичный код работает.
PM MAIL   Вверх
LamerTM
Дата 18.10.2009, 15:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 97
Регистрация: 11.3.2006

Репутация: нет
Всего: 0



Хотя нет, это не причина.

Имя класса по-моему не может содержать пробел. А у тебя оно с пробелом.
PM MAIL   Вверх
theHelg
Дата 19.10.2009, 00:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 74
Регистрация: 23.6.2009

Репутация: нет
Всего: нет



А что мне даст ref?
Если я этот третий параметр тупо игнорю...
А имя класса я взял из шпиона... это он такой класс видит у внутреннего окна IE например...

Но мне кажется, что эта процеда вообще не отрабатывает... 
Так как даже если я вне проверки на класс делаю - то есть:


Код

 static bool EnumChildProc(IntPtr hWnd, IntPtr lParam)
        {
            const int CAPACITY = 256;
            StringBuilder className = new StringBuilder(CAPACITY);
            GetClassName(hWnd, className, CAPACITY);

                ClassNativeMethods.handle = hWnd;

            //продолжаем поиск
            return true;
        }



То не меняется содержимое статичной переменной статичного класса...
И туда даже дебагер не заходит, и как отладить - без понятия...
Ничего не пишет, ничего не происходит :(

Как это все выглядит.
У меня есть сторонний клиент, в котором мне нужно выполнить набор авто-тестов. К сожалению, требуется именно C#...

У меня есть handle главного окна. 

Код

PostMessage(handle, WMConstants.WM_LBUTTONDOWN, IntPtr.Zero, new IntPtr(y * 0x10000 + x));


для данного окна не работает — видимо не реагирует на команды. То есть, как я думаю — нужно сюда поставлять уже непосредственно handle окна с нужным классом ("Internet Explorer_Server"). Или я не прав?

Данным кодом пытаюсь найти все дочерние окна и запомнить нужный хандл.

Но вот не получается... :(

PM MAIL   Вверх
LamerTM
Дата 19.10.2009, 08:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 97
Регистрация: 11.3.2006

Репутация: нет
Всего: 0



Посмотрел в Spy. Имя класса всё таки может содержать пробел.
Запустил твой код. Он работает. Находит хэндл окна по имени класса. Так что в коде что ты привёл всё правильно. Значит ошибка у тебя в чём-то другом.

На всякий случай скопипасчу код что у меня заработал в студии:

На форме должен быть RichTextBox и кнопка.
Код

    public class Class1
    {
        public static IntPtr ClassNativeMethodsHandle;

        [DllImport("user32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
        public static extern IntPtr FindWindowExW(IntPtr parent, IntPtr child, [MarshalAs(UnmanagedType.LPWStr)] string className, [MarshalAs(UnmanagedType.LPWStr)] string windowName);






        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
        [DllImport("user32.dll")]
        public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
        [DllImport("User32.dll")]
        public static extern bool EnumChildWindows(IntPtr hWndParent,
            EnumChildProcDelegate lpEnumFunc,
            IntPtr lParam);

        public delegate bool EnumChildProcDelegate(IntPtr hWnd, IntPtr LParam);

        static bool EnumChildProc(IntPtr hWnd, IntPtr lParam)
        {
            const int CAPACITY = 256;
            StringBuilder className = new StringBuilder(CAPACITY);
            GetClassName(hWnd, className, CAPACITY);

            if (className.ToString() == "Internet Explorer_Server")
            {
                //нашли нужный класс
                ClassNativeMethodsHandle = hWnd;
                return false;
            }
            //продолжаем поиск
            return true;
        }

        public static void findIEwindow(IntPtr tksClientHandle)
        {
            //IntPtr hWndExplorer - ссылка на мое окно;
            EnumChildProcDelegate enumChildProc = new EnumChildProcDelegate(EnumChildProc);
            //Перечисляем все дочерние окна моего окна
            EnumChildWindows(tksClientHandle, enumChildProc, tksClientHandle);
        }
    }

И код кнопки на форме:
Код

        private void button1_Click(object sender, EventArgs e)
        {
            IntPtr a = Class1.FindWindowExW(IntPtr.Zero, IntPtr.Zero, "IEFrame", null);
            Class1.findIEwindow(a);
            richTextBox1.AppendText(Class1.ClassNativeMethodsHandle.ToString());
        }

Работает так. Запускаешь IE. Нажимаешь кнопку на форме. В ричтекстбоксе пишется хэндл его подокна с именем класса "Internet Explorer_Server".
PM MAIL   Вверх
theHelg
Дата 19.10.2009, 13:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 74
Регистрация: 23.6.2009

Репутация: нет
Всего: нет



Хм...
действительно работает...

Видимо все дело было в том, что я handle окна искал через:
Код

            IntPtr result = IntPtr.Zero;

            Process[] ps = Process.GetProcessesByName(processName);
            if (ps != null && ps.Length > 0)
            {
                result = ps[0].MainWindowHandle;
                Process temp = ps[0];
            }
            return result;


И это, судя по всему, явно не правильно - так он не отрабатывает...
Вечером буду тестировать, но судя по всему - то, что мне нужно smile
PM MAIL   Вверх
LamerTM
Дата 19.10.2009, 14:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 97
Регистрация: 11.3.2006

Репутация: нет
Всего: 0



Если тебе надо найти конкретное окно и ты точно знаешь его место в иерархии, то незачем использовать EnumChildWindows. Всё можно сделать через FindWindowEx.

Код получится вроде такого:

Код

IntPtr a = FindWindowExW(IntPtr.Zero, IntPtr.Zero, "IEFrame", null);
a = FindWindowExW(a, IntPtr.Zero, "Shell DocObject View", null);
a = FindWindowExW(a, IntPtr.Zero, "Internet Explorer_Server", null);

PS
3 строчки вместо того, что у тебя в первом посте.

Это сообщение отредактировал(а) LamerTM - 19.10.2009, 14:19
PM MAIL   Вверх
theHelg
Дата 21.10.2009, 12:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 74
Регистрация: 23.6.2009

Репутация: нет
Всего: нет



Да, спасибо!

как говорит один мой знакомый охотник - Вот она почему не стреляла! не заряжена была!! smile
С этим намного проще, так как действительно я знаю и главное окно, и место в иерархии... 

Хотя еще не понятно, почему теперь уже по правильному хандлу окна не могу послать клики мышки... это окно не реагирует :(

Это сообщение отредактировал(а) theHelg - 21.10.2009, 12:05
PM MAIL   Вверх
LamerTM
Дата 21.10.2009, 13:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 97
Регистрация: 11.3.2006

Репутация: нет
Всего: 0



Нацель Spy на окно и кликни мышкой вручную. Посмотри какие сообщения получало окно при клике. Пошли такие же (обычно достаточно только какого-то одного из них, надо только узнать какого). Как правило, это работает. Но не всегда. Иногда может не работать. Я, правда, уже забыл почему.
Я когда посылал клики мыши, то (сейчас глянул в свой код) у меня wParam был равен единице. А у тебя там ноль. Может в этом причина. А может и нет. smile
PM MAIL   Вверх
theHelg
Дата 21.10.2009, 14:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 74
Регистрация: 23.6.2009

Репутация: нет
Всего: нет



хм,
да, спасибо!
хорошая мысль, попробую в ручном режиме слать сообщения через указателя...
хотя я и не знал, что можно спаем выяснить, какие сообщения шлются окну при клике...

Я шщлю клик вот так:

Код

            NativeMethods.PostMessage(handle, WMConstants.WM_LBUTTONDOWN, IntPtr.Zero, new IntPtr(y * 0x10000 + x));


в этот handle и подставляю полученные хандлы....
PM MAIL   Вверх
LamerTM
Дата 21.10.2009, 14:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 97
Регистрация: 11.3.2006

Репутация: нет
Всего: 0



А ты по вэб-станице кликать собираешься? Я читал что это дело сложное, и сам такого не делал. Вернее делал, но ламерским образом (правда в опере).
PM MAIL   Вверх
theHelg
Дата 21.10.2009, 14:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 74
Регистрация: 23.6.2009

Репутация: нет
Всего: нет



Угу, судя по всему да...

Есть сторонний клиент, внутри которого что-то похожее на WebBrowser.
Очень похоже на это, так как действительно клики мыши не принимает, а класс у него как у IE...

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Разработка Windows Forms | Следующая тема »


 




[ Время генерации скрипта: 0.0771 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.