Что нового

Отлавливание и очистка "мёртвых" иконок в системном трее

HukpoFuJl

AццkuЙ HukpoFuJl
Сообщения
98
Репутация
38
В общем бывают такие случаи, что программа при неудачном завершении (например при уничтожении процесса) оставляет от себя иконку в трее. При наведении мыши на эту иконку - она исчезает. Вот хотелось бы узнать как "отлавливать" такие иконки и убирать их... Возюкать программно мышью в трее (каждые 5 сек к примеру) - не очень "гуд" решение, но пока единственное, приходящее в голову...

Готовое решение:
Код:
#NoTrayIcon
#include <SysTray_UDF.au3>
Local $a1, $a2

While 1
	$a1 = _SysTrayIconPids()
	$a2 = _SysTrayIconProcesses()
	For $i = 0 To UBound($a1)-1
		If $a1[$i] = -1 And $a2[$i] = "" Then
			_SysTrayIconRemove($i)
			Opt('TrayIconHide', 0)
			Opt('TrayIconHide', 1)
		EndIf
	Next
	Sleep(3000)
WEnd


SysTray_UDF.au3
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 472
Репутация
2 401
HukpoFuJl [?]
вопрос всё же от части соответствует названию темы
Только потому что в нём есть слова «значку» и «трее»?

И ещё, даже если название темы отвечает критериям твоего вопроса, это ещё не значит что это одна и та же тема.

P.S
И по твоему вопросу кажется уже была тема, поищи по форуму.
 
Автор
HukpoFuJl

HukpoFuJl

AццkuЙ HukpoFuJl
Сообщения
98
Репутация
38
В общем сам нашел ответ, стоило изучить выложенную тут библиотеку SysTray_UDF.au3 =)
Вот, например, такой скриптик каждые 3 секунды будет проверять наличие "пустых" иконок в трее и убирать их :smile:
Код:
#NoTrayIcon
#include <SysTray_UDF.au3>

While 1
	$PID = _SysTrayIconPids()
	For $i = 0 To UBound($PID)-1
		If $PID[$i] = -1 Then _SysTrayIconRemove($i)
	Next
	Sleep(3000)
WEnd


Странное дело, что винда сама этого не делает...
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 472
Репутация
2 401
OffTopic:
HukpoFuJl [?]
мой админский взгляд всегда склонялся к тому, что лучше решить несколько схожих вопросов в одной теме, чем запостить несколько схожих тем, в которых будет по 2 сообщения (вопрос и ответ). Видимо в этом отношении у нас разные взгляды на жизнь
Да, и у тебя мнения на эту тему будут расходиться ещё с многими админами.
 
Автор
HukpoFuJl

HukpoFuJl

AццkuЙ HukpoFuJl
Сообщения
98
Репутация
38
OffTopic:
CreatoR сказал(а):
OffTopic:
HukpoFuJl [?]
мой админский взгляд всегда склонялся к тому, что лучше решить несколько схожих вопросов в одной теме, чем запостить несколько схожих тем, в которых будет по 2 сообщения (вопрос и ответ). Видимо в этом отношении у нас разные взгляды на жизнь
Да, и у тебя мнения на эту тему будут расходиться ещё с многими админами.
Просто я администрирую сайты(форумы) немного других тематик, например форум провайдера, на котором каждый, кому не лень пытается создать тему "А пачиму у миня не работаит и-нет!?" и т.п.. Видимо от этого у меня и отношение такое к этому вопросу :smile:

PS: Думаю оффтоп можно удалить, свои посты я подправил, дабы соответствовало новой теме :smile:
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 472
Репутация
2 401
HukpoFuJl [?]
такой скриптик каждые 3 секунды будет проверять наличие "пустых" иконок в трее и убирать их
Проблема в том что он оставляет пустые ячейки.

Вот метод с мышкой:

Код:
#NoTrayIcon
#include <WinAPI.au3>

_RefreshSystemTray()

; ===================================================================
; _RefreshSystemTray($nDealy = 10)
;
; Removes any dead icons from the notification area.
; Parameters:
;    $nDelay - IN/OPTIONAL - The delay to wait for the notification area to expand with Windows XP's
;        "Hide Inactive Icons" feature (In milliseconds).
; Returns:
;    Sets @error on failure:
;        1 - Tray couldn't be found.
;        2 - MouseMove error.
; ===================================================================
Func _RefreshSystemTray($nDelay = 10)
	Local $hWnd = ControlGetHandle("[CLASS:Shell_TrayWnd]", "", "[CLASS:TrayNotifyWnd]")
	If Not IsHWnd($hWnd) Then Return SetError(1, 0, 0)
	
	Local $hControl = ControlGetHandle($hWnd, "", "Button1")
	
	; We're on XP and the Hide Inactive Icons button is there, so expand it
	If @OSVersion = "WIN_XP" And IsHWnd($hControl) And ControlCommand($hWnd, "", $hControl, "IsVisible") Then
		ControlClick($hWnd, "", $hControl)
		Sleep($nDelay)
	EndIf
	
	Local $posStart = MouseGetPos()
	Local $posWin = WinGetPos($hWnd)
	
	Local $x = $posWin[0], $y = $posWin[1]
	
	_WinAPI_ShowCursor(False)
	
	While $y < $posWin[3] + $posWin[1]
		$x = $posWin[0]
		
		While $x < $posWin[2] + $posWin[0]
			;DllCall("user32.dll", "int", "SetCursorPos", "int", $x, "int", $y)
			MouseMove($x, $y, 0)
			
			If @error Then
				Return SetError(2, 0, 0)
			EndIf
			
			$x += 8
		WEnd
		
		$y += 8
	WEnd
	
	;DllCall("user32.dll", "int", "SetCursorPos", "int", $posStart[0], "int", $posStart[1])
	MouseMove($posStart[0], $posStart[1], 0)
	_WinAPI_ShowCursor(True)
	
	; We're on XP so we need to hide the inactive icons again.
	If @OSVersion = "WIN_XP" And $hControl <> "" And ControlCommand($hWnd, "", $hControl, "IsVisible") Then
		ControlClick($hWnd, "", $hControl)
	EndIf
EndFunc ; _RefreshSystemTray()
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 472
Репутация
2 401
OffTopic:
HukpoFuJl [?]
Просто я администрирую сайты(форумы) немного других тематик, например форум провайдера, на котором каждый, кому не лень пытается создать тему "А пачиму у миня не работаит и-нет!?" и т.п.
Ну если ты как админ позволяешь это, то так и будет продолжаться.

Ладно, на эту тему хватит, остальное в ПМ
 
Автор
HukpoFuJl

HukpoFuJl

AццkuЙ HukpoFuJl
Сообщения
98
Репутация
38
CreatoR сказал(а):
Проблема в том что он оставляет пустые ячейки.
Да, как-то я этого не заметил сначала... Это плохо...

CreatoR сказал(а):
Вот метод с мышкой
Такой метод работает конечно, но на фоновую работу в цикл его просто так не повесишь, т.к. это будет постоянное изнасилование курсора =) Нормальное выделение текста при таком раскладе в принципе становиться невозможным =))). Да, и _WinAPI_ShowCursor у меня почему-то не сработал, я прекрасно визуально наблюдал пробегающую по трею мышь =) (Win7)

Вот аналогичный твоему и моему вариант (А точнее что-то между ними) :smile: т.е. иконка убирается наведением мыши, но мышь наводится только в том случае, если найдена "мертвая" иконка, и наводится непосредственно на неё:
Код:
#NoTrayIcon
#include <SysTray_UDF.au3>
Local $PID

While 1
	$PID = _SysTrayIconPids()
	For $i = 0 To UBound($PID)-1
		If $PID[$i] = -1 Then _SysTrayIcon_MouseOver($i)
	Next
	Sleep(3000)
WEnd

Func _SysTrayIcon_MouseOver ($iIndex)
	Local $TrayIcon_Pos = _SysTrayIconPos($iIndex)
    Local $Old_Mouse_Pos = MouseGetPos()
    MouseMove($TrayIcon_Pos[0], $TrayIcon_Pos[1], 0)
	Sleep(10)
    MouseMove($Old_Mouse_Pos[0], $Old_Mouse_Pos[1], 0)
EndFunc


PS: Обидно, но _SysTrayIconVisible тоже оставляет за собой пустые ячейки :( Видимо всё же без наведения мыши тут никак (не криво) не обойтись...
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 711
HukpoFuJl сказал(а):
Обидно, но _SysTrayIconVisible тоже оставляет за собой пустые ячейки :( Видимо всё же без наведения мыши тут никак (не криво) не обойтись...
Вот так все будет работать.

Код:
_SysTrayIconRemove(...)
Opt('TrayIconHide', 0)
Opt('TrayIconHide', 1)
 
Верх