Что нового

[Окна, Диалоги] Как получить handle окна при запуске?

Dimmak

Знающий
Сообщения
185
Репутация
9
$hWnd = ShellExecute('C:\00')
Пробовал так, но $hwnd = 1...
Подскажите, как получить handle окна именно при запуске?
:scratch:
 

sngr

AutoIT Гуру
Сообщения
1,010
Репутация
408
Код:
#include'winapiex.au3'
$run=Run('notepad.exe'); запускаем искомую программу
ProcessWait('notepad.exe',20)
$ha=_WinAPI_EnumProcessWindows($run); это определяет handle
MsgBox(0,'',$ha[1][0])

http://autoit-script.ru/index.php/topic,47.0.html
winapiex.au3 распакуй в папку с установленным autoit\include
Чисто из любопытства, $hWnd = ShellExecute('C:\00') - на что ты надеялся?
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
ошибка
Код:
Subscript used with non-Array variable
 

sngr

AutoIT Гуру
Сообщения
1,010
Репутация
408
Блокнот запустился? Winapiex последней версии? Из архива с winapiex кинул все .au3 в папку с установленным autoit\include?
 

Zaramot

I ♥ AutoIt
Сообщения
1,160
Репутация
660
Код:
$nPID = Run('notepad.exe')
ProcessWait($nPID)
$hWnd = _Process2Handle($nPID)
MsgBox(0, 'Handle', $hWnd)

func _Process2Handle($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][1]
        EndIf
    next
    return -1
endfunc
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Zaramot,
Код:
$nPID = Run('notepad.exe')
ProcessWait($nPID);??? посмотрите в справке
;...
А если видимое (добавлено) окно не одно, и почему у него обязательно должен быть заголовок?
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
sngr, ага :smile:
Zaramot, возвращает -1 ..так и должно быть?
madmasles [?]
А если окно не одно
а их и так не одно ..одно видим, другие в скрытом режиме. у всех есть дескрипторы..
и какой нужен? дескриптор видимого окна или ?


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

madmasles
вот твой скрипт. я добавил MsgBox который показывает только дескриптор видимого окна
Код:
#include <WinAPI.au3>
#include <Array.au3>

$sFileExe = @WindowsDir & '\notepad.exe'

$sProcess = StringRegExpReplace($sFileExe, '^.*\\', '')
$iCount = 0
If Not ProcessExists($sProcess) Then
    Run($sFileExe)
EndIf
$iPID = ProcessWait($sProcess, 5)
If Not $iPID Then
    MsgBox(16, 'Error', 'Error')
    Exit
EndIf
$aList = WinList()
If Not $aList[0][0] Then
    MsgBox(16, 'Error', 'Error')
    Exit
EndIf
Dim $aResult[$aList[0][0] + 1][4]
For $i = 1 To $aList[0][0]
    If WinGetProcess($aList[$i][1]) = $iPID Then
        $iCount += 1
        $aResult[$iCount][0] = $aList[$i][0] ;Title
        $aResult[$iCount][1] = $aList[$i][1] ;Handle
        $aResult[$iCount][2] = _WinAPI_GetClassName($aList[$i][1]);ClassName
        If BitAND(WinGetState($aList[$i][1]), 2) Then
            $aResult[$iCount][3] = 'visible'
        Else
            $aResult[$iCount][3] = 'hide'
        EndIf
    EndIf
Next
If $iCount Then
    ReDim $aResult[$iCount + 1][4]
    $aResult[0][0] = $iCount
    _ArrayDisplay($aResult, 'Все окна процесса ' & $sProcess)
	MsgBox(0,'',$aResult[1][1]); тут как раз то, что надо
Else
    MsgBox(16, 'Error', 'Error')
EndIf

в принципе то, что нужно автору темы.. получения дескриптора окна запускаемого приложения..не зная какой заголовок будет у окна.. вроде так :smile:
взято отсюда http://autoit-script.ru/index.php/topic,6419.0.html

но не все так просто. с блокнотом и диспетчером задач срабатывает, а вот к примеру запустить скайп ..и в массиве первым идет скрытое окно, когда запускается программа, а иногда первым идет видимое окно
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
В функции _WinAPI_EnumProcessWindows() надо ставить вторым параметром 0, для получения не только видимых, но и скрытых окон.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
А вот так не проще:

Код:
$iPID = Run(@WindowsDir & "\Notepad.exe")
$hNotepad = _WinWaitByPID($iPID)

MsgBox(64, 'Title', WinGetTitle($hNotepad))

Func _WinWaitByPID($iPID, $iWaitTime = -1)
	Local $iTimer = TimerInit()
	Local $aWinList
	
	While 1
		$aWinList = WinList()
		
		For $i = 1 To $aWinList[0][0]
			If WinGetProcess($aWinList[$i][1]) = $iPID And BitAND(WinGetState($aWinList[$i][1]), 2) Then
				Return $aWinList[$i][1]
			EndIf
		Next
		
		If $iWaitTime > 0 And TimerDiff($iTimer) >= $iWaitTime * 1000 Then ExitLoop
	WEnd
	
	Return 0
EndFunc


:scratch:

madmasles [?]
посмотрите в справке
В справке написано:
Эта функция является единственной из раздела функций "Процессы" не принимающая PID в качестве параметра "process". Поскольку PID распределяются случайным образом, ожидать процесс с конкретным PID не имеет смысла.
:smile:
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
все-таки можно и так . только прикрутить запуск..
из той же темы
Код:
#Include <Array.au3>
#Include <WinAPIEx.au3>

$list = ProcessList("notepad.exe")
for $i = 1 to $list[0][0]
 $Data=_WinAPI_EnumProcessWindows($list[$i][1], 1)
 _ArrayDisplay($Data)
next
MsgBox(0,'',$Data[1][0])


CreatoR
твой скрипт я так понял для получения заголовка? что по сути и происходит
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Александр [?]
твой скрипт я так понял для получения заголовка?
Для ожидания окна по PID, возвращает Handle, заголовок получается через WinGetTitle.
 
Автор
Dimmak

Dimmak

Знающий
Сообщения
185
Репутация
9
Это хорошо, но все примеры относятся к процессам, а мне нужно получить handle окна проводника при запуске.

Результат, который мне нужно получить:
ShellExecute( 'C:\' )
$hWnd = WinGetHandle( 'C:\' )

Есть ли рабочий аналог данной строчки?

$hWnd = ShellExecute( 'C:\' )
( Чтоб при запуске сразу получить handle )
 

sngr

AutoIT Гуру
Сообщения
1,010
Репутация
408
Код:
ShellExecute( 'C:\' )
sleep(500)
MsgBox(0,'',WinGetHandle('[active]'))
ShellExecute( 'C:\' )
sleep(500)
$list=WinList('[class:CabinetWClass]')
MsgBox(0,'',$list[1][1])
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Dimmak
Если при shellexecute у тебя вызывается проводник, то зачем мучаться? используй
Код:
Run(@WindowsDir&"\explorer.exe C:\")
, таким образом получишь процесс..
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Тогда получай все handles окон процесса Explorer. Вызывай shellexecute. Получай снова все handles окон тогоже explorera - делай сравнение. :smile: - какой хэндл будет новым - будет твоим искомым
Или же как в примере sngr.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Вот так получилось, учитывается также предыдущие открытые окна проводника:

Код:
#include <WinAPIEx.au3>

$iPID = Run("Explorer.exe C:\")
ProcessWaitClose($iPID)

$aProcs = ProcessList("Explorer.exe")
$sWin = ''

For $i = 1 To UBound($aProcs)-1
	$aWins = _WinAPI_EnumProcessWindows($aProcs[$i][1])
	
	For $j = 1 To UBound($aWins)-1
		If $aWins[$j][1] = 'CabinetWClass' Then
			$sWin = WinGetTitle($aWins[$j][0])
		EndIf
	Next
Next

MsgBox(64, 'Title', $sWin)



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

Вариант по методу от inververs:

Код:
#include <Array.au3>

$aWins1 = WinList('[CLASS:CabinetWClass]')
$iPID = Run("Explorer.exe C:\")
ProcessWaitClose($iPID)

While 1
	$aWins2 = WinList('[CLASS:CabinetWClass]')
	If $aWins2[1][0] <> 'Проводник' Then ExitLoop
WEnd

For $i = 1 To UBound($aWins2)-1
	If _ArraySearch($aWins1, $aWins2[$i][1], 0, 0, 0, 0, 1, 1) = -1 Then
		MsgBox(64, 'Title', $aWins2[$i][0])
		ExitLoop
	EndIf
Next
 
Автор
Dimmak

Dimmak

Знающий
Сообщения
185
Репутация
9
CreatoR, inververs, sngr
Я понял! :smile:
Спасибо! :IL_AutoIt_1:
 
Верх