Что нового

[Окна, Диалоги] Как работать с окнами многооконного приложения с одинаковыми Title/Class?

Крепыш

Новичок
Сообщения
105
Репутация
2
Подскажите, пожалуйста, как работать с окнами многооконного приложения, которые имеют один и тот же Handle - родительского окна и одинаковые Title и Class?
Пример такого приложения - AkelPad.
Нужно активировать, например, активировать какое-нибудь из окон и закрыть другое.
Как это сделать?
 

oesoes

xor eax,eax
Сообщения
171
Репутация
9
Re: [Окна, Диалоги] Как работать с окнами, которые имеют один и тот же Handle

Не понятно, про какие вы окна говорите. Например в моем акельпаде окно настроек и главное имеют конечно же разные дескрипторы ) Даже если файл->создать окно, то все равно разные дескрипторы. Да и не могут они быть одинаковые.
 
Автор
К

Крепыш

Новичок
Сообщения
105
Репутация
2
Re: [Окна, Диалоги] Как работать с окнами, которые имеют один и тот же Handle

Я про те окна, в которых пишется текст. Многооконный режим в AkelPad включается: Настройки - Оконный режим - Многооконный (MDI)
 

oesoes

xor eax,eax
Сообщения
171
Репутация
9
Re: [Окна, Диалоги] Как работать с окнами, которые имеют один и тот же Handle

Аа вот оно чего, ты про вкладки ) Даже и не знаю, если даже заголовок вкладки у тебя один и тот же, то тут даже не соображу, что можно придумать :(
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Re: [Окна, Диалоги] Как работать с окнами, которые имеют один и тот же Handle

Крепыш [?]
Пример такого приложения - AkelPad.
В AkelPad в многооконном режиме создаются вкладки в SysTabControl32. С ними можно попробовать работать функциями _GUICtrlTab_*.


Добавлено:
Сообщение автоматически объединено:

Простой пример (сначала откройте несколько файлов в AkelPad в многооконном режиме).
Код:
#include <GuiTab.au3>

$hWin = WinGetHandle('[Class:AkelPad4]')
If Not $hWin Then Exit 1
$hTab = ControlGetHandle($hWin, '', '[CLASS:SysTabControl32; INSTANCE:1]')
If Not $hTab Then Exit 2
$iCount = _GUICtrlTab_GetItemCount($hTab)
ConsoleWrite('ItemCount: ' & $iCount & @LF)
For $i = 0 To $iCount - 1
	If _GUICtrlTab_GetCurFocus($hTab) <> $i Then _GUICtrlTab_SetCurFocus($hTab, $i)
	Sleep(1000)
	ConsoleWrite('Item index: ' & $i & ', Item text: ' & _GUICtrlTab_GetItemText($hTab, $i) & @LF)
Next
 
Автор
К

Крепыш

Новичок
Сообщения
105
Репутация
2
Re: [Окна, Диалоги] Как работать с окнами, которые имеют один и тот же Handle

madmasles сказал(а):
В AkelPad в многооконном режиме создаются вкладки в SysTabControl32. С ними можно попробовать работать функциями _GUICtrlTab_*.
Хотелось бы без панели вкладок переключаться между окнами, т.к. в других приложениях такой панели нет.

oesoes сказал(а):
Даже и не знаю, если даже заголовок вкладки у тебя один и тот же
У вкладок одинаковые
Код:
Title=AkelPad; Class=AkelPad4
А заголовки у всех вкладок разные, и отображаются в Au3Info.exe в поле Text
Насчёт Handle я ступил (не там посмотрел): они у всех вкладок разные. С помощью Handle можно переключаться между окнами. Но как это сделать, не зная его заранее, а зная только имя вкладки?
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
Re: [Окна, Диалоги] Как работать с окнами, которые имеют один и тот же Handle

Крепыш
Это обычные MDI-окна. В стандартном режиме AutoIt "видит" эти окна, как элементы (контролы) главного окна. Поэтому с ними можно работать, как и с другими элементами, такими как кнопки, поля ввода и т.д.
Код:
$hAkel = WinGetHandle("AkelPad")
ControlFocus($hAkel, "", "D:\filename.txt")


Ещё один вариант - включить режим поиска дочерних окон. Теперь с MDI-окнами можно работать, как с окнами верхнего уровня
Код:
Opt("WinSearchChildren", 1)
WinActivate("D:\filename.txt")
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
Крепыш сказал(а):
Подскажите, пожалуйста, как работать с окнами многооконного приложения
Можно зацепиться за положение на экране, размер, дочерние элементы
 
Автор
К

Крепыш

Новичок
Сообщения
105
Репутация
2
Как работать с окнами многооконного приложения с одинаковыми Title/Class?

InnI,
спасибо! Так работает.
А без включения режима поиска дочерних окон можно узнать Handle окна, имея такие параметры, как Text и Class окна?
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
Крепыш [?]
без включения режима поиска дочерних окон можно узнать Handle окна
Код:
; используем только текст заголовка
$hMDI = ControlGetHandle("AkelPad", "", "D:\filename.txt")
; класс и текст заголовка
$hMDI = ControlGetHandle("AkelPad", "", "[class:AkelPad MDI Class; text:D:\filename.txt]")
; класс и порядковый номер (самый верхний 1, под ним 2, ниже 3 и т.д.)
$hMDI = ControlGetHandle("AkelPad", "", "AkelPad MDI Class2")
; активируем найденное MDI-окно без активации главного окна
#include <WinAPISys.au3>
_WinAPI_BringWindowToTop($hMDI)



Добавлено:
Сообщение автоматически объединено:

Кстати, зная дескриптор MDI-окна, с ним можно работать, как с обычным окном
Код:
; переместить/изменить размер
WinMove($hMDI, "", 10, 10, 100, 100)
; развернуть
WinSetState($hMDI, "", @SW_MAXIMIZE)
; закрыть
WinClose($hMDI)
 
Автор
К

Крепыш

Новичок
Сообщения
105
Репутация
2
А вот
Код:
WinActive($hMDI)
возвращает 0 для активного окна. Как узнать активно ли MDI-окно с дескриптором $hMDI?
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
Крепыш [?]
Согласен, не все Win*-функции работают должным образом. Но зачем вам узнавать активность? Просто активируйте его и всё ;)
Но если вам очень нужно узнать верхнее ("активное") MDI-окно, то можно так
Код:
$hMDI = ControlGetHandle("AkelPad", "", "AkelPad MDI Class1")
$Title = WinGetTitle($hMDI)
Напоминаю, у верхнего окна instance=1.
 

Skif_off

Знающий
Сообщения
173
Репутация
12
Обратите внимание, скрипт вида
Код:
#include <SendMessage.au3>

Global Const $WM_COMMAND = 0x0111

$hAkelPad = WinGetHandle("[CLASS:AkelPad4]")
_SendMessage($hAkelPad, $WM_COMMAND, NNNN, 0)
If @error Then
    MsgBox(4096, "", "_SendMessage Error: " & @error)
    Exit
EndIf

где NNNN - внутренняя команда AkelPad (см. \AkelFiles\Docs\AkelHelp-Rus.htm), отлично работает.
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
OffTopic:
Skif_off [?]
внутренняя команда AkelPad
Я так понимаю, что Крепыш использует AkelPad в качестве тренажёра. А работать будет с другим приложением.
 
Автор
К

Крепыш

Новичок
Сообщения
105
Репутация
2
[Окна, Диалоги] [Окна, Диалоги] Как работать с окнами многооконного приложения с одинаковыми Title

InnI сказал(а):
Я так понимаю, что Крепыш использует AkelPad в качестве тренажёра. А работать будет с другим приложением.
Да, Вы верно понимаете. Просто AkelPad есть у большинства программистов - на нём проще объяснять.


Добавлено:
Сообщение автоматически объединено:

InnI сказал(а):
Но зачем вам узнавать активность? Просто активируйте его и всё ;)
Но если вам очень нужно узнать верхнее ("активное") MDI-окно, то можно так
Код:
$hMDI = ControlGetHandle("AkelPad", "", "AkelPad MDI Class1")
$Title = WinGetTitle($hMDI)
Напоминаю, у верхнего окна instance=1.
Мне как раз не и не нужно активировать выбранное окно. Мне просто нужно узнать находится ли оно в фокусе.
С параметром
Код:
Opt('WinSearchChildren', 1)
функция WinActive() также возвращает 0 для дочернего окна.
Ваш пример также даст неверный результат, если к примеру в фокусе находится окно "Поиск"
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
Крепыш [?]
не нужно активировать выбранное окно. Мне просто нужно узнать находится ли оно в фокусе.
Ну, хорошо. Допустим, вы узнали, что оно не в фокусе. Что вы будете делать? Скорее всего - активировать?
Вот и активируйте его в любом случае - и будете уверены, что оно в фокусе.

Следующие функции активируют указанное MDI-окно, даже если в фокусе окно поиска
Код:
WinActivate($hMDI)
ControlFocus("AkelPad", "", $hMDI)
 
Автор
К

Крепыш

Новичок
Сообщения
105
Репутация
2
InnI,
да нет же. Как раз и нужно выяснить в фокусе ли заданное окно, и, если оно находится в фокусе, то перенести фокус на любое другое окно, например нажатием
Код:
Send('^{TAB}')

Поясню: дело в том, что в том приложении, где я буду работать, "горячие клавиши" не работают, если в фокусе находится определённое окно. Так вот, надо с него перенести фокус, чтобы можно было пользоваться "горячими клавишами".
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
Крепыш
Не может MDI-окно быть в фокусе - оно может быть верхним (instance=1). В фокусе могут быть элементы внутри MDI-окна. Применительно к AkelPad - это поле редактирования (class:AkelEditW). Поэтому я и предлагал вам поиск по верхнему окну
Код:
; определяем, какое MDI-окно верхнее
$hMDI = ControlGetHandle("AkelPad", "", "[class:AkelPad MDI Class; instance:1]")
; если это проблемное окно с заголовком "D:\filename.txt"
If WinGetTitle($hMDI) = "D:\filename.txt" Then
  ; принудительно активируем на случай, если в фокусе окно поиска
  ControlFocus("AkelPad", "", $hMDI)
  Send("^{TAB}")
EndIf
 
Автор
К

Крепыш

Новичок
Сообщения
105
Репутация
2
Можно и так. Просто, мы ищем верхнее окно среди определённого класса окон данного приложения.
А можно ли получить дескриптор верхнего окна среди всех классов?

И ещё: правильно я понимаю, что чтобы вводить текст, независимо от раскладки клавиатуры, нужно использовать ASCII коды символов, типа так?
Код:
Send('{ASC '&Asc('R')&'}')
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
Re: [Окна, Диалоги] [Окна, Диалоги] Как работать с окнами многооконного приложения с одинаковыми T

Крепыш сказал(а):
Да, Вы верно понимаете. Просто AkelPad есть у большинства программистов - на нём проще объяснять.
Речь не о QUIK?
 
Верх