Что нового

Как получить заголовок родительского или корневого окна?

vovsla

Осваивающий
Сообщения
607
Репутация
36
Пробовал получить так, но ничего не получается
Код:
#include <MsgBoxConstants.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>

$HWin=WinGetHandle('Отчеты')
$PWin=_WinAPI_GetParent($HWin)
$Title=WinGetTitle($PWin)
MsgBox(262144, 'Debug line ~' & @ScriptLineNumber, 'Selection:' & @CRLF & '$text' & @CRLF & @CRLF & 'Return:' & @CRLF & $Title) ;### Debug MSGBfin
 
Автор
V

vovsla

Осваивающий
Сообщения
607
Репутация
36
С ним пробовал с самого начала, не помогло
После комментов указаны возвращаемые значения

Код:
#include <MsgBoxConstants.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>

$HWin=WinGetHandle('Отчеты')
;~ $PWin=_WinAPI_GetParent($HWin)
$PWin=_WinAPI_GetAncestor($HWin, $GA_PARENT) ; Return пусто
$PWin=_WinAPI_GetAncestor($HWin, $GA_ROOT ) ; Return имя дочернего окна - 'Отчеты'
$PWin=_WinAPI_GetAncestor($HWin, $GA_ROOTOWNER ) ; Return имя дочернего окна - 'Отчеты'
$Title=WinGetTitle($PWin)
MsgBox(262144, 'Debug line ~' & @ScriptLineNumber, 'Selection:' & @CRLF & '$Title' & @CRLF & @CRLF & 'Return:' & @CRLF & $Title) ;### Debug MSGBOX
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
Vovsla
Если вы определяете окно через WinGetHandle(), значит оно и есть родительское. Чтобы эта функция находила дочерние окна (например, MDI) нужно включить опцию
Код:
Opt("WinSearchChildren", 1)
 
Автор
V

vovsla

Осваивающий
Сообщения
607
Репутация
36
В общем и целом ситуация следующая.
Есть 2 программы, "программа 1" и "программа 2" с одинаковыми названиями ехешников, которые лежат в разных папках. У программ есть есть окна главного меню с разными заголовками - "окно 1" и "окно 2 ". Но все их дочерние окна называются одинаково, по названию дочернего окна нужно определить к какой программе относится окно.
"окно 1" - главное меню программы из которого можно открыть открыть основное рабочее окно - "Отчеты". "окно 1.1" и "Отчеты" относятся друг к другу как SDI интерфейс. Весь MDI интерфейс в основном рабочем окне - "Отчеты".
Т.е. мне нужно получать дочерние окна "окна 1" и "окна 2 " и искать нужное окно в списках дочерних окон или можно как-то сразу получить родительское окно?
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
Vovsla
которые лежат в разных папках
Можно узнать путь к файлу и по нему определить программу
Код:
#include <WinAPIProc.au3>
_WinAPI_GetProcessFileName(WinGetProcess('Отчеты'))


получать дочерние окна "окна 1" и "окна 2"
Похоже, что эти ваши "Отчеты" совсем не дочерние. Попробуйте так
Код:
#include <WinAPIProc.au3>
$aList = _WinAPI_EnumProcessWindows(WinGetProcess('Отчеты'))
If Not @error Then
  For $i = 1 To $aList[0][0]
    Switch WinGetTitle($aList[$i][0])
      Case "окно 1"
        MsgBox(0, "", "окно 1")
        ExitLoop
      Case "окно 2"
        MsgBox(0, "", "окно 2")
        ExitLoop
    EndSwitch
  Next
  If $i = $aList[0][0] + 1 Then MsgBox(0, "", "Не найдено")
EndIf
 
Автор
V

vovsla

Осваивающий
Сообщения
607
Репутация
36
Так не получится отловить. У меня
Программа1->Окно1->Отчеты
Программа2->Окно2->Отчеты

Программа1 и Программа2 - ехешники одинаковые но лежат в разных местах
Окно1 и Окно2 - основные окна разных программ с помощью которых можно открыть окна "Отчеты", у каждой программы свое окно "Отчеты"
Окна с заголовками "Отчеты" открыты одновременно в Программе1 и Программе2
Нужно по имени окна "Отчеты" понять к какой программе относится окно 1 или 2.
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
Vovsla
Так не получится отловить
А вы пробовали?
Код:
#include <WinAPIProc.au3>

; запускаем блокноты
For $i = 1 To 5
  Run("notepad.exe")
  ControlSetText(WinWaitActive("[class:Notepad]"), "", "Edit1", "Окно №" & $i)
  WinMenuSelectItem("[class:Notepad]", "", "&Правка", "&Найти...")
  WinWaitActive("Найти")
Next

; находим все окна поиска
$list = WinList("Найти")
If Not IsArray($list) Then Exit

; выбираем случайное окно поиска
$r = Random(1, $list[0][0], 1)
ControlSetText($list[$r][1], "", "Edit1", "hWnd = " & $list[$r][1])

; ищем родителя окна поиска
$list = _WinAPI_EnumProcessWindows(WinGetProcess($list[$r][1]))
If Not @error Then
  For $i = 1 To $list[0][0]
    $text = WinGetText($list[$i][0])
    If StringInStr($text, "№") Then
      ConsoleWrite("Главное окно:" & @CRLF)
      ConsoleWrite(" - текст: " & $text)
      ConsoleWrite(" - дескриптор: " & $list[$i][0] & @CRLF)
      ConsoleWrite(" - класс: " & $list[$i][1] & @CRLF)
      WinActivate($list[$i][0])
      ExitLoop
    EndIf
  Next
EndIf
Теоретически, функция EnumThreadWindows (используемая в _WinAPI_EnumProcessWindows) перечисляет окна таким образом, что главное окно программы находится последним в списке
Код:
$list[$list[0][0]][0]
 
Автор
V

vovsla

Осваивающий
Сообщения
607
Репутация
36
Большое спасибо за подробный пример. Разобрался, работает.
 
Верх