Что нового

Окно не восстанавливается из трея

vovsla

Осваивающий
Сообщения
607
Репутация
36
После длительного нахождения программы в свернутом виде (сворачивается в трей) периодически возникают ситуации когда программа не восстанавливается из трея и ее приходится завершать как процесс.

Кусок кода который отвечает за сворачивание/восстановление окна.
Код:
GUISetOnEvent($GUI_EVENT_MINIMIZE, 'TrayPrimDown')
TraySetOnEvent($TRAY_EVENT_PRIMARYDOWN, 'TrayPrimDown')


Func TrayPrimDown()
	$State=WinGetState($Form1)
	If $State=23 Or $State=15 Or $State=7  Then
 		FileWrite(@ScriptDir&'\log.txt', WinGetState($Form1)&' HideToTray'&@CRLF)
		WinSetState($Form1, '', @SW_HIDE)
	Else
 		FileWrite(@ScriptDir&'\log.txt', WinGetState($Form1)&' RestoreFromTray'&@CRLF)
		WinSetState($Form1, '', @SW_SHOW)
		WinSetState($Form1, '', @SW_RESTORE)
		WinSetOnTop($Form1, '', 1)
		WinSetOnTop($Form1, '', 0)
	EndIf
EndFunc


Когда окно не хочет восстанавливаться запись в log.txt идет, т.е. программа отлавливает событие, но почему-то не срабатывает WinSetState.
 

MnM

Post-Hardcore
Сообщения
679
Репутация
90
Vovsla
Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
HotKeySet("^e","__ShowGUI");Ctrl+e
$gui = GUICreate("", 333, 71)
$Button = GUICtrlCreateButton("Кнопка - ""свернуть""", 0, 0, 139, 25)
GUISetState(@SW_SHOW)
While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case $Button
			GUISetState(@SW_HIDE,$gui)
		Case $GUI_EVENT_CLOSE
			Exit
	EndSwitch
WEnd
Func __ShowGUI()
	GUISetState(@SW_SHOW,$gui)
EndFunc

Ctrl+e восстанавливает окно, а кнопка сворачивает


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

Если с треем то:
Код:
#NoTrayIcon
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
Opt("TrayMenuMode",3)
$hideashow=TrayCreateItem("Свернуть окно")
$exit=TrayCreateItem("Выход")
$gui = GUICreate("", 333, 71)
$Button = GUICtrlCreateButton("Кнопка - ""свернуть""", 0, 0, 139, 25)
GUISetState(@SW_SHOW)
TraySetState(1)
While 1
	Switch TrayGetMsg()
		Case $hideashow
			Local $Stats=WinGetState($gui)
			If BitAND($Stats,2)=2 Then
				TrayItemSetText($hideashow,"Отобразить окно")
				GUISetState(@SW_HIDE,$gui)
			ElseIf $Stats=5 Then
				TrayItemSetText($hideashow,"Свернуть окно")
				GUISetState(@SW_SHOW,$gui)
			EndIf
		Case $exit
			Exit
	EndSwitch
	Switch GUIGetMsg()
		Case $Button
			GUISetState(@SW_HIDE,$gui)
		Case $GUI_EVENT_CLOSE
			Exit
	EndSwitch
WEnd
 
Автор
V

vovsla

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

Код:
Func TrayPrimDown()
	$Status=WinGetState($Form1)
	If BitAND($Status, 2)=2  Then
		GUISetState(@SW_HIDE, $Form1)
	Else
		GUISetState(@SW_SHOW, $Form1)
	EndIf
EndFunc


Кстати через какое-то время после сворачивания/разворачивания программа из сообщения "Если с треем то:" перестала разворачиваться из трея.
 

MnM

Post-Hardcore
Сообщения
679
Репутация
90
Vovsla
Это скорее всего из-за того что вы блок условий для восстановления определили как "иначе"(т.е. ко всем возвращаемым значениям WinGetState если 1-й блок не подошел), у меня же в последнем условии для восстановления определяется число 5 - "окно существует и доступно".
Попробуйте так:
Код:
Func TrayPrimDown()
    $Status=WinGetState($Form1)
    If BitAND($Status, 2)=2  Then;Если окно отображается, то есть возможность его скрыть
        GUISetState(@SW_HIDE, $Form1)
    ElseIf $Status=5 Then;Если окно скрыто но существует и доступно для обращения к нему
        GUISetState(@SW_SHOW, $Form1)
    EndIf
EndFunc



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

Если это не будет хорошо работать то скорее всего что-то происходит в программе или с программой.
 
Автор
V

vovsla

Осваивающий
Сообщения
607
Репутация
36
C " ElseIf $Status=5 Then" я уже пробовал, окно стабильно перестает восстанавливаться после сворачивания в трей по событию "$GUI_EVENT_MINIMIZE", т.е. нажал свернуть и все...
Причем перестает работать вся функция TrayPrimDown(), лог не пишется
Возможно это связано с этими опциями
Код:
Opt("TrayMenuMode", 1)
Opt("TrayOnEventMode", 1)
Opt("GUIOnEventMode", 1)
 

MnM

Post-Hardcore
Сообщения
679
Репутация
90
Vovsla сказал(а):
Возможно это связано
Можно же тестировать методом исключения, или добавления...
К 1 параметру TrayMenuMode 3 лучше ставить, потому что при нажатии на пункт меню он будет с галочкой(Если это вам конечно не нужно)


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

А еще лучше сделайте примерную копию вашего кода с проблемной работой и покажите
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,323
Vovsla,
Попробуйте примерно так.
Код:
#NoTrayIcon
#include <Constants.au3>
#include <GUIConstantsEx.au3>

Opt('TrayMenuMode', 3)
Opt('TrayOnEventMode', 1)

$hGUI = GUICreate('Test', 200, 200)
GUISetState()
TrayCreateItem('Exit')
TrayItemSetOnEvent(-1, '_Exit')
TraySetOnEvent($TRAY_EVENT_PRIMARYUP, '_TrayWin')
TraySetIcon ('user32.dll', -3)
TraySetState(1)
TraySetClick(16)
While 1
	Switch GUIGetMsg()
		Case $GUI_EVENT_MINIMIZE
			TraySetIcon ('user32.dll', -4)
		Case $GUI_EVENT_RESTORE
			TraySetIcon ('user32.dll', -3)
		Case $GUI_EVENT_CLOSE
			_Exit()
	EndSwitch
WEnd

Func _TrayWin()
	Local $i_WinState = WinGetState($hGUI)
	Switch BitAND($i_WinState, 16)
		Case 0
			TraySetIcon ('user32.dll', -4)
			GUISetState(@SW_MINIMIZE, $hGUI)
		Case Else
			TraySetIcon ('user32.dll', -3)
			GUISetState(@SW_RESTORE, $hGUI)
	EndSwitch
EndFunc   ;==>_TrayToWin

Func _Exit()
	Exit
EndFunc   ;==>_Exit
Или так.
Код:
#NoTrayIcon
#include <Constants.au3>
#include <GUIConstantsEx.au3>

Opt('TrayMenuMode', 3)

$hGUI = GUICreate('Test', 200, 200)
GUISetState()
$nExit = TrayCreateItem('Exit')
TraySetIcon('user32.dll', -3)
TraySetState(1)
TraySetClick(16)
While 1
	Switch TrayGetMsg()
		Case $nExit
			_Exit()
		Case $TRAY_EVENT_PRIMARYUP
			_TrayWin()
	EndSwitch
	Switch GUIGetMsg()
		Case $GUI_EVENT_MINIMIZE
			TraySetIcon('user32.dll', -4)
		Case $GUI_EVENT_RESTORE
			TraySetIcon('user32.dll', -3)
		Case $GUI_EVENT_CLOSE
			_Exit()
	EndSwitch
WEnd

Func _TrayWin()
	Local $i_WinState = WinGetState($hGUI)
	Switch BitAND($i_WinState, 16)
		Case 0
			TraySetIcon('user32.dll', -4)
			GUISetState(@SW_MINIMIZE, $hGUI)
		Case Else
			TraySetIcon('user32.dll', -3)
			GUISetState(@SW_RESTORE, $hGUI)
	EndSwitch
EndFunc   ;==>_TrayWin

Func _Exit()
	Exit
EndFunc   ;==>_Exit
 
Автор
V

vovsla

Осваивающий
Сообщения
607
Репутация
36
В вышеуказанном примере окно сворачивается не в трей а на панель пуск, в таком варианте проблем нет.
Когда приложение залипает в трее WinGetState($Form1) возвращает 0, при этом функция GUISetState(@SW_SHOW, $Form1) просто не срабатывает.
 

MnM

Post-Hardcore
Сообщения
679
Репутация
90
Vovsla
WinGetState($Form1) возвращает 0
Если эта функция правда возвращает такое число, то у вас окна не существует, либо его из скрипта удалили либо еще какими либо "окольными" путями
 
Автор
V

vovsla

Осваивающий
Сообщения
607
Репутация
36
У меня есть подозрение, что GUIDelete($TaskForm1) удаляет $Form1 при отсутствии $TaskForm1.
Заплатку уже поставил, посмотрю как будет работать...
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,487
Vovsla [?]
есть подозрение, что GUIDelete($TaskForm1) удаляет $Form1 при отсутствии $TaskForm1
Вполне реально. Нужно проверять $TaskForm1 (с IsHwnd()).
 
Автор
V

vovsla

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