Page 1 sur 1

Utilisation de AddSysTrayIcon

Publié : ven. 01/janv./2016 1:19
par cage
Bonjour a tous,

Lorsque qu'une application installe une icône dans le SysTray, cette icône disparait si l’Explorateur Windows (explorer.exe) vient a se cracher ou que par nécessité on redémarre l’Explorateur Windows.
Si l'application n'a d'icône ni dans la barre de tache ni dans le SysTray, il n'est plus possible de contrôler cette application.
Pour résoudre le problème, l'icône est ajoutée dans le SysTray toutes les N secondes via un Timer
L'icône étant déjà présente dans le SysTray, cela ne devrait avoir aucune incidence.
Mais tout se passe comme si l'icône était d'abord retirée puis ensuite ajoutée dans le SysTray ce qui a pour effet de faire sauter l'icône et de faire trembloter le groupe d'icône situé a gauche de celle-ci.
Auriez-vous une idée pour empêcher ce tremblement sachant que j'ai souvent plusieurs utilitaires PB ouverts en même temps et que j'aime avoir les icônes visibles dans le SysTray (mes utilitaires une fois réduits ne sont plus présents dans la barre de tache pour gagner de la place.)
Augmenter le Timer n'est pas vraiment une solution.
Voici une partie du code que j'utilise

Code : Tout sélectionner

EnableExplicit

#WinApp=0

DataSection ; Images
  Image_App:
  IncludeBinary "MyApp.ico"
EndDataSection

Enumeration Images
  #Image_App
EndEnumeration

Global IconApp = CatchImage(#Image_App  , ?Image_App)

Enumeration Timers
  #Timer
EndEnumeration

Procedure initSysTray()
  AddSysTrayIcon(#WinApp, WindowID(#WinApp), IconApp)
  SysTrayIconToolTip(#WinApp, "MyApp")
EndProcedure

ExamineDesktops()
#W=300 : #H=200
Define X = (DesktopWidth(0) -#W)/2
Define Y = (DesktopHeight(0)-#H)/2
Define Event
If OpenWindow(0, X, Y, #W, #H, "AddSysTrayIcon", #PB_Window_MinimizeGadget|#PB_Window_Minimize|#PB_Window_WindowCentered)
  initSysTray()
  SetWindowState(0, #PB_Window_Normal)
  AddWindowTimer(#WinApp, #Timer, 3000)
  Repeat
    Event = WaitWindowEvent()
    Select Event
      Case #PB_Event_CloseWindow : End
      Case #PB_Event_Timer       : initSysTray()
    EndSelect
  ForEver
EndIf
J’espère que vous avez tous passés de bonnes fêtes.
Je vous souhaite mes meilleurs vœux pour cette nouvelle année qui commence et que Fred nous concocte un PB encore meilleur dans les mois a venir.
Gérard

Re: Utilisation de AddSysTrayIcon

Publié : ven. 01/janv./2016 9:28
par Marc56
Est-ce que ton application "voit" que l'icône n'est plus là ? en d'autres termes, que donne IsSysTrayIcon() ?
Je ne sais pas ce que ça donne, car c'est Windows qui gère et non pas l'application, mais à voir:
Car à ce moment là on peut l'empêcher de clignoter en ne l'affichant que si elle n'est plus initialisée.
À tester:

Code : Tout sélectionner

Procedure initSysTray()
  If Not IsSysTrayIcon(IconApp)
    AddSysTrayIcon(#WinApp, WindowID(#WinApp), )
    SysTrayIconToolTip(#WinApp, "MyApp")
  EndIf
EndProcedure
Bonne Année.
:)

Re: Utilisation de AddSysTrayIcon

Publié : ven. 01/janv./2016 13:12
par cage
L'application ne voit pas que l'icône n'est plus présente dans le SysTray.
La fonction IsSysTrayIcon(IconApp) retourne toujours Vrai
A l'époque ou je programmais en VB, je n'avais pas ce phénomène.
Pour info, voila le code que j'utilisais:

Code : Tout sélectionner

Private Type NOTIFYICONDATA
	cbSize As Long
	hWnd   As Long
	uId    As Long
	uFlags As Long
	ucallbackMessage As Long
	hIcon As Long
	szTip As String * 64
End Type

Private Const NIM_ADD     As Integer = &H0
Private Const NIM_MODIFY  As Integer = &H1
Private Const NIM_DELETE  As Integer = &H2
Private Const NIF_MESSAGE As Integer = &H1
Private Const NIF_ICON    As Integer = &H2
Private Const NIF_TIP     As Integer = &H4

Private Declare Function Shell_NotifyIcon Lib "Shell32" Alias "Shell_NotifyIconA" _
	(ByVal dwMessage As Long, pnid As NOTIFYICONDATA) As Boolean

Private TrayI As NOTIFYICONDATA

Private Sub Form_Load()
	'*'-------------------------------------------------------------------------
	'*' DÉFINITION DE L'ICONE A CRÉER DANS LE SYSTRAY
	'*'-------------------------------------------------------------------------

	With TrayI
		.cbSize = Len(TrayI)
		.hWnd = picHook.hWnd 'Link the trayicon to this picturebox
		.uId = 1&
		.uFlags = NIF_ICON Or NIF_TIP Or NIF_MESSAGE
		.ucallbackMessage = WM_LBUTTONDOWN
		.hIcon = Me.Icon
		.szTip = PROGRAM & vbNullChar 'chrw$(0)
	End With

	'*'-------------------------------------------------------------------------
	'*' TESTE SI ON PEUX CRÉER L'ICONE DANS LE SYSTRAY
	'*'-------------------------------------------------------------------------

	Dim retval As Boolean

	'*' Create icon
	retval = Shell_NotifyIcon(NIM_ADD, TrayI)

	If (CInt(retval = 0)) Then
		Me.Hide
		MsgBoxTexte = "Unable to create icon in systray "
		Reponse = MessageBox(Me.hWnd, MsgBoxTexte, MsgBoxTitre, vbOKOnly + vbCritical + vbMsgBoxSetTopMost)
		End
	End If

	'*'-------------------------------------------------------------------------

	Timer1.Interval = 2000
	Timer1.Enabled = True

End Sub

Private Sub Form_Unload(Cancel As Integer)
	On Error Resume Next

	TrayI.cbSize = Len(TrayI)
	TrayI.hWnd = picHook.hWnd
	TrayI.uId = 1&

	'Delete the icon
	Shell_NotifyIcon NIM_DELETE, TrayI

	End
End Sub

Private Sub Timer1_Timer()
    On Error Resume Next
    TrayI.hIcon = Me.Icon
    '*' Create the icon
    Shell_NotifyIcon NIM_ADD, TrayI
    DoEvents
End Sub
Désolé de balancer du code VB
Au départ, je pensais que PB faisait la même chose.
Je ne pense pas être le seul a avoir remarqué ce phénomène.

Re: Utilisation de AddSysTrayIcon

Publié : ven. 01/janv./2016 15:41
par Marc56
cage a écrit :Je ne pense pas être le seul a avoir remarqué ce phénomène.
C'est à dire que cela arrivait surtout avec les anciennes versions de Windows (<= XP)
Maintenant c'est rare de voir explorer se planter et il n'y a pas de raison de le fermer volontairement.

Perso, quand ça m'arrivait, je commençais par chercher et soigner la cause: aller voir dans les journaux d'évènement le programme qui a planté et lui régler son compte (mise à jour ou suppression: un programme qui plante Explorer est considéré comme toxique :x )

Il existe sur le net, des petits utilitaires pour restaurer les icônes de la trayicon, mais je n'en ai pas trouvé; la plupart datent d'XP (qui était très fragile) et les liens n'existent souvent plus.

:)

Re: Utilisation de AddSysTrayIcon

Publié : ven. 01/janv./2016 18:49
par cage
Le fait que l'explorateur Windows se plante m'arrive encore quelque fois même sous Win10 64
Cela peut se produire avec certaines applications qui ouvrent encore l'explorateur dans une instance différente de l'instance principale de l'explorateur.
Je m'explique.
Si on regarde le gestionnaire de taches dans la partie Détails, on de doit voir qu'une seule fois explorer.exe
- pourtant il arrive que l'on voit 2, 3 4 ou plus explorer.exe
- au bout d'un certain temps, il est nécessaire de killer tous les processus pour retrouver un système stable
- fermer les fenêtres Explorateur ne termine pas les processus explorer.exe
- cela permet aussi de libérer la mémoire.
Enfin, le problème n'est pas la mais du coté de PB.
Je cherche a savoir comment réinscrire l'icône dans le SysTray sans que cela produise un tremblement des icônes.
Mes anciens progs VB que j'utilise encore sous Win10 le font sans que le phénomène se produise.

J'aimerai juste pouvoir le faire en PB, vu que je ne programme plus en VB6 depuis au moins 2 ans et que PB est devenu incontournable pour moi.
Si quelqu'un avait une idée géniale, je serai acheteur.

Re: Utilisation de AddSysTrayIcon

Publié : mar. 19/janv./2016 22:27
par cage
Bonjour,

J'ai trouvé une solution sur le forum anglais.
http://www.purebasic.fr/english/viewtopic.php?t=20712
http://forums.purebasic.com/english/vie ... p?p=231726
http://www.purebasic.fr/english/viewtop ... 13#p453413

Modifications du code initial:
Suppression du Timer
Ajout de la Procedure Callback()
Modification de la Procedure initSysTray()

Fonctionne correctement sous Win10 64-bit lorsque je tue/relance le processus Explorer principal
Pas la possibilité de tester avec d'autres versions.
Quelqu'un peut-il faire le test sous Seven ? Merci.

Code : Tout sélectionner

EnableExplicit

#WinApp=0

DataSection ; Images
  Image_App:
  IncludeBinary "MyApp.ico"
EndDataSection

Enumeration Images
  #Image_App
EndEnumeration

Global IconApp = CatchImage(#Image_App, ?Image_App)

Global TB_Message = RegisterWindowMessage_("TaskbarCreated")

;  Enumeration Timers ; <=== Retrait du Timer
;    #Timer
;  EndEnumeration

Procedure initSysTray()
  If FindWindow_("Progman", #NUL) <> 0 ; <=== Ajout du test
    AddSysTrayIcon(#WinApp, WindowID(#WinApp), IconApp)
    SysTrayIconToolTip(#WinApp, "MyApp")
  EndIf  
EndProcedure

Procedure Callback(hWnd, Msg, wParam, lParam)
  If Msg = TB_Message
    Debug Msg
    initSysTray()
  EndIf
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

ExamineDesktops()
#W=300 : #H=200
Define X = (DesktopWidth(0) -#W)/2
Define Y = (DesktopHeight(0)-#H)/2
Define Event
If OpenWindow(0, X, Y, #W, #H, "AddSysTrayIcon", #PB_Window_MinimizeGadget|#PB_Window_Minimize|#PB_Window_WindowCentered)
  initSysTray()
  SetWindowState(0, #PB_Window_Normal)
;    AddWindowTimer(#WinApp, #Timer, 3000) ; <=== Retrait du Timer
  SetWindowCallback(@Callback())
  Repeat
    Event = WaitWindowEvent()
    Select Event
      Case #PB_Event_CloseWindow : End
;        Case #PB_Event_Timer : initSysTray() ; <=== Retrait du Timer
    EndSelect
  ForEver
EndIf


Re: Utilisation de AddSysTrayIcon

Publié : mer. 20/janv./2016 0:49
par Ar-S
Cool que tu ais trouvé la réponse, ça pourra surement me servir aussi.
Merci.