Что нового

Как получить имя окна с помощью процесса?

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,487
Код:
;GUI to check the function
$hGUI = GUICreate("Our GUI")
GUISetState()

$aWindow = _ProcessGetWindow(@AutoItPID, -1, 1)

MsgBox(64, "Results", _
	StringFormat("Win Title \t\t\t= %s \nWin Handle \t\t= %s\nOriginal Win Handle \t\t= %s", $aWindow[0], $aWindow[1], $hGUI))

Func _ProcessGetWindow($iPID, $iRet = -1, $iRetVisibleOnly = 0)
	Local $aWinList = WinList(), $aRet[2]
	
	If IsString($iPID) Then
		$iPID = ProcessExists($iPID)
	EndIf
	
	For $i = 1 To UBound($aWinList)-1
		If (($iRetVisibleOnly And BitAND(WinGetState($aWinList[$i][1]), 2)) Or Not $iRetVisibleOnly) And WinGetProcess($aWinList[$i][1]) = $iPID Then
			$aRet[0] = $aWinList[$i][0] ;Title
			$aRet[1] = $aWinList[$i][1] ;WinHandle
			
			If $iRet = 0 Then
				Return $aRet[0]
			EndIf
			
			If $iRet = 1 Then
				Return $aRet[1]
			EndIf
			
			Return $aRet
		EndIf
	Next
	
	Return SetError(1, 0, $aRet)
EndFunc
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
_WinAPI_EnumProcessWindows()

:smile:
 

Zaramot

I ♥ AutoIt
Сообщения
1,160
Репутация
660
Ещё вариант:
Код:
func _Process2Win($pid)
    if isstring($pid) then $pid = processexists($pid)
    if $pid = 0 then return -1
    $list = WinList()
    for $i = 1 to $list[0][0]
        if $list[$i][0] <> "" AND BitAnd(WinGetState($list[$i][1]),2) then
            $wpid = WinGetProcess($list[$i][0])
            if $wpid = $pid then return $list[$i][0]
        EndIf
    next
    return -1
endfunc


Пример:
Код:
MsgBox(0, 'Title', _Process2Win('notepad.exe'))
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Процесс может иметь несколько окон.
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
Yashied [?]
Процесс может иметь несколько окон.

Дествительно. Как быть при наличии дочернего окна?
Код:
#include <WindowsConstants.au3>
#Include <GuiTreeView.au3>
;GUI to check the function
$hGUI = GUICreate("Our GUI")


$aWindow = _ProcessGetWindow(@AutoItPID);, -1, 1)

MsgBox(64, "Results", _
    StringFormat("Win Title \t\t\t= %s \nWin Handle \t\t= %s\nOriginal Win Handle \t\t= %s", $aWindow[0], $aWindow[1], $hGUI))

$hGUI2 = GUICreate('Выберите папку', 200, 400, -1, -1,  BitOR($WS_CAPTION, $WS_POPUP),-1, $hGUI)
;$hTV = _GUICtrlTreeView_Create($hGUI2, 5, 5, 190, 390, -1, $WS_EX_CLIENTEDGE);   ********   Нарушает работу *******

$aWindow = _ProcessGetWindow(@AutoItPID);, -1, 1)

MsgBox(64, "Results", _
    StringFormat("Win Title \t\t\t= %s \nWin Handle \t\t= %s\nOriginal Win Handle \t\t= %s", $aWindow[0], $aWindow[1], $hGUI2))

GUISetState(@SW_SHOW, $hGUI)
GUISetState(@SW_SHOW, $hGUI2)

Func _ProcessGetWindow($iPID, $iRet = -1, $iRetVisibleOnly = 0)
    Local $aWinList = WinList(), $aRet[2]
    
    If IsString($iPID) Then
        $iPID = ProcessExists($iPID)
    EndIf
    
    For $i = 1 To UBound($aWinList)-1
        If (($iRetVisibleOnly And BitAND(WinGetState($aWinList[$i][1]), 2)) Or Not $iRetVisibleOnly) And WinGetProcess($aWinList[$i][1]) = $iPID Then
            $aRet[0] = $aWinList[$i][0] ;Title
            $aRet[1] = $aWinList[$i][1] ;WinHandle
            
            If $iRet = 0 Then
                Return $aRet[0]
            EndIf
            
            If $iRet = 1 Then
                Return $aRet[1]
            EndIf
            
            Return $aRet
        EndIf
    Next
    
    Return SetError(1, 0, $aRet)
EndFunc


Работает только при пустом дочернем окне . Достаточно вставить в него элемент (например TreeView)
и определение не получается.
Может я что-то не так делаю ?



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

Однако ф-ия от Zaramot , слегка подкорректированная под мой пример вроде отрабатывает верно:
Код:
#include <WindowsConstants.au3>
#Include <GuiTreeView.au3>

$hGUI = GUICreate("Our GUI")

$w=_Process2Win(@AutoItPID)
MsgBox(0,"$w", $w)

$hGUI2 = GUICreate('Выберите папку', 200, 400, -1, -1,  BitOR($WS_CAPTION, $WS_POPUP),-1, $hGUI)

$hTV = _GUICtrlTreeView_Create($hGUI2, 5, 5, 190, 390, -1, $WS_EX_CLIENTEDGE);   ********   Нарушает работу *******

$w=_Process2Win(@AutoItPID)
MsgBox(0,"$w", $w)

GUISetState(@SW_SHOW, $hGUI)
GUISetState(@SW_SHOW, $hGUI2)

Func _Process2Win($pid, $iRetVisibleOnly=0)
    if isstring($pid) then $pid = processexists($pid)
    if $pid = 0 then return -1
    $list = WinList()
    for $i = 1 to $list[0][0]
       ; if $list[$i][0] <> "" AND BitAnd(WinGetState($list[$i][1]),2) then
		if ($list[$i][0] <> "" AND BitAnd(WinGetState($list[$i][1]),2)) Or Not $iRetVisibleOnly then  
		   $wpid = WinGetProcess($list[$i][0])
            if $wpid = $pid then return $list[$i][0]
        EndIf
    next
    return -1
endfunc
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,487
gregaz [?]
Работает только при пустом дочернем окне . Достаточно вставить в него элемент (например TreeView)
и определение не получается.
Нужно проверять текст окна, не пустой ли он...
Код:
If $aWinList[$i][0] <> '' And (($iRetVisibleOnly And BitAND(WinGetState($aWinList[$i][1]), 2)) Or Not $iRetVisibleOnly) And WinGetProcess($aWinList[$i][1]) = $iPID Then
            ...
        EndIf



Как быть при наличии дочернего окна?
Код:
#Include <WinAPIEx.au3>

$hParent = GUICreate('My GUI')
$hChild = GUICreate('Child', 200, 200, 1, -1, -1, -1, $hParent)

$aWins = _WinAPI_EnumProcessWindows(@AutoItPID, 0)

For $i = 1 To $aWins[0][0]
	ConsoleWrite('Handle: ' & $aWins[$i][0] & ', Title: ' & WinGetTitle($aWins[$i][0]) & @LF)
Next
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
CreatoR [?]
Нужно проверять текст окна, не пустой ли он...

Действительно.

Однако долго не мог понять причину различного поведения в 2-х практически одинаковых вариантах
Оказалось если в варианте Creatora заменить ;
Код:
; If (($iRetVisibleOnly And BitAND(WinGetState($aWinList[$i][1]), 2)) Or Not $iRetVisibleOnly) And WinGetProcess($aWinList[$i][1]) = $iPID Then
If (($iRetVisibleOnly And BitAND(WinGetState($aWinList[$i][1]), 2)) Or Not $iRetVisibleOnly) And WinGetProcess($aWinList[$i][0]) = $iPID Then


то и здесь начинает корректно работать, хотя как корректней ?

а вариант с WinAPI не дает ответа на конкретный GUI в момент запроса, а лишь перечень имеющихся


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