OVH Cloud OVH Cloud

Form_GotFocus/LostFocus/Activate/Deactivate

3 réponses
Avatar
Guy Lafrenière
Bonjour,

J'ai créé un serveur dll qui affiche un chronomètre. Le Caption de la
fenêtre Chrono est "Chrono". Quand je clique sur la fenêtre de l'application
cliente, la fenêtre Chrono disparaît derrière celle-ci, ce qui est correct.

Si je minimise la fenêtre Chrono, l'événement Resize modifie sa propriété
Caption pour afficher le temps écoulé. On peut ainsi suivre le temps écoulé
en regardant le bouton du chrono sur la barre de tâche. Si la fenêtre Chrono
reprend sa taille normale, son Caption redevient "Chrono".

Mon problème arrive ici. Si je clique sur la fenêtre de l'application
cliente sans d'abord minimisé la fenêtre Chrono, celle-ci n'affiche pas le
temps écoulé dans la barre de tâches parce l'événement Resize n'intervient
pas et qu'elle ne sait pas qu'elle n'a plus le focus. J'ai essayé de jouer
avec les événements GotFocus/LostFocus/Activate/Deactivate de ma fenêtre
Chrono, rien n'y fait.

Comment faire savoir à la fenêtre Chrono qu'elle n'a plus le focus et
qu'elle doit modifier son Caption? Comment lui faire savoir qu'elle a à
nouveau le focus et qu'elle doit à nouveau modifier son Caption?

Bien sûr vous me direz qu'il suffit de laisser le Caption de la fenêtre
Chrono afficher en permanence le temps écoulé et mon problème est résolu.
Mais pourquoi faire simple quand on peut faire compliqué?

Merci pour toute aide!

Guy Lafrenière

3 réponses

Avatar
Jacques93
Bonjour Guy Lafrenière,
Guy Lafrenière a écrit :
Bonjour,

J'ai créé un serveur dll qui affiche un chronomètre. Le Caption de la
fenêtre Chrono est "Chrono". Quand je clique sur la fenêtre de l'application
cliente, la fenêtre Chrono disparaît derrière celle-ci, ce qui est correct.

Si je minimise la fenêtre Chrono, l'événement Resize modifie sa propriété
Caption pour afficher le temps écoulé. On peut ainsi suivre le temps écoulé
en regardant le bouton du chrono sur la barre de tâche. Si la fenêtre Chrono
reprend sa taille normale, son Caption redevient "Chrono".

Mon problème arrive ici. Si je clique sur la fenêtre de l'application
cliente sans d'abord minimisé la fenêtre Chrono, celle-ci n'affiche pas le
temps écoulé dans la barre de tâches parce l'événement Resize n'intervient
pas et qu'elle ne sait pas qu'elle n'a plus le focus. J'ai essayé de jouer
avec les événements GotFocus/LostFocus/Activate/Deactivate de ma fenêtre
Chrono, rien n'y fait.

Comment faire savoir à la fenêtre Chrono qu'elle n'a plus le focus et
qu'elle doit modifier son Caption? Comment lui faire savoir qu'elle a à
nouveau le focus et qu'elle doit à nouveau modifier son Caption?

Bien sûr vous me direz qu'il suffit de laisser le Caption de la fenêtre
Chrono afficher en permanence le temps écoulé et mon problème est résolu.
Mais pourquoi faire simple quand on peut faire compliqué?

Merci pour toute aide!

Guy Lafrenière





En supposant que ton chrono est basé sur un contrôle Timer, tu peux
utiliser l'api GetForegroundWindow :

Option Explicit
Private Declare Function GetForegroundWindow Lib "user32" () As Long

Private Sub Timer1_Timer()
If GetForegroundWindow() = Me.hWnd Then
Me.Caption = "Chrono"
Else
Me.Caption = Time() 'A remplacer par la valeur de ton chrono
End If
End Sub


--
Cordialement,

Jacques.
Avatar
Jacques93
Bonjour Guy Lafrenière
Jacques93 a écrit :
Bonjour Guy Lafrenière,
Guy Lafrenière a écrit :
Bonjour,

J'ai créé un serveur dll qui affiche un chronomètre. Le Caption de la
fenêtre Chrono est "Chrono". Quand je clique sur la fenêtre de
l'application
cliente, la fenêtre Chrono disparaît derrière celle-ci, ce qui est
correct.

Si je minimise la fenêtre Chrono, l'événement Resize modifie sa propriété
Caption pour afficher le temps écoulé. On peut ainsi suivre le temps
écoulé
en regardant le bouton du chrono sur la barre de tâche. Si la fenêtre
Chrono
reprend sa taille normale, son Caption redevient "Chrono".

Mon problème arrive ici. Si je clique sur la fenêtre de l'application
cliente sans d'abord minimisé la fenêtre Chrono, celle-ci n'affiche
pas le
temps écoulé dans la barre de tâches parce l'événement Resize
n'intervient
pas et qu'elle ne sait pas qu'elle n'a plus le focus. J'ai essayé de
jouer
avec les événements GotFocus/LostFocus/Activate/Deactivate de ma fenêtre
Chrono, rien n'y fait.

Comment faire savoir à la fenêtre Chrono qu'elle n'a plus le focus et
qu'elle doit modifier son Caption? Comment lui faire savoir qu'elle a à
nouveau le focus et qu'elle doit à nouveau modifier son Caption?

Bien sûr vous me direz qu'il suffit de laisser le Caption de la fenêtre
Chrono afficher en permanence le temps écoulé et mon problème est résolu.
Mais pourquoi faire simple quand on peut faire compliqué?

Merci pour toute aide!

Guy Lafrenière








Sinon, pour faire plus simple ;-) . Sans contrôle Timer et en
interceptant les messages Windows. Dans le code de feuille (avec un
Texbox) :

' -----------------------------------------------------------------
Option Explicit

Private Sub Form_Load()
With Me.Text1
.Locked = True
.BackColor = vbButtonFace
.Font.Name = "Comic Sans MS"
.Font.Size = 24
.Alignment = vbCenter
.Text = "00:00:00"
End With
HookWndProc Me.hWnd, Me.Text1.hWnd
End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
UnHookWndProc Me.hWnd
End Sub
' --------------------------------------------------------------------

Et dans un module :

' --------------------------------------------------------------------

Option Explicit

Private Declare Function SetWindowLong Lib "user32" _
Alias "SetWindowLongA" _
(ByVal hWnd As Long, ByVal nIndex As Long, _
ByVal dwNewLong As Long) As Long
Private Const GWL_WNDPROC = (-4)
Private Const WM_NCACTIVATE = &H86&
Private Const WM_SIZE = &H5
Private Const SIZE_MINIMIZED = &H1

Private Declare Function CallWindowProc Lib "user32" _
Alias "CallWindowProcA" _
(ByVal lpPrevWndFunc As Long, _
ByVal hWnd As Long, _
ByVal Msg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long

Private Declare Function SetTimer Lib "user32" _
(ByVal hWnd As Long, _
ByVal nIDEvent As Long, _
ByVal uElapse As Long, _
ByVal lpTimerFunc As Long) As Long

Private Declare Function KillTimer Lib "user32" _
(ByVal hWnd As Long, ByVal nIDEvent As Long) As Long

Private Const WM_TIMER = &H113&

Private Declare Function IsIconic Lib "user32" _
(ByVal hWnd As Long) As Long

Private Declare Function SetWindowText Lib "user32" _
Alias "SetWindowTextA" _
(ByVal hWnd As Long, ByVal lpString As String) As Long

Dim lpPrevWndProc As Long
Dim bShowChrono As Boolean
Dim StartTime As Date
Dim hWndChrono As Long


Public Sub HookWndProc(hWnd As Long, txtHwnd As Long)
StartTime = Time
hWndChrono = txtHwnd
lpPrevWndProc = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf WindowProc)
SetTimer hWnd, 1&, 1000, 0&
End Sub


Public Sub UnHookWndProc(hWnd As Long)
Dim lResult As Long

KillTimer hWnd, 1&
lResult = SetWindowLong(hWnd, GWL_WNDPROC, lpPrevWndProc)
End Sub


Public Function WindowProc(ByVal hWnd As Long, _
ByVal uMsg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long

Select Case uMsg
Case WM_NCACTIVATE
bShowChrono = (wParam = 0)
ChangeCaption hWnd

Case WM_SIZE
If wParam = SIZE_MINIMIZED Then
ChangeCaption hWnd
End If

Case WM_TIMER
ChangeCaption hWnd

End Select
WindowProc = CallWindowProc(lpPrevWndProc, hWnd, uMsg, wParam, lParam)
End Function


Private Sub ChangeCaption(hWnd As Long)
Dim txt As String

txt = Format(Now - StartTime, "hh:nn:ss")
If bShowChrono Then
SetWindowText hWnd, txt & " (Caché)"
ElseIf IsIconic(hWnd) Then
SetWindowText hWnd, txt & " (Réduit)"
Else
SetWindowText hWnd, "Chrono"
End If
SetWindowText hWndChrono, txt
End Sub

' --------------------------------------------------------------------

Testé sur un projet standard, mais doit être OK avec une Dll ActiveX

--
Cordialement,

Jacques.
Avatar
Guy Lafrenière
Bonjour Jacque93,

Ta première réponse était tout à fait ce qu'il me fallait.

Merci beaucoup!

Guy Lafrenière


"Jacques93" a écrit dans le message de
news:

En supposant que ton chrono est basé sur un contrôle Timer, tu peux
utiliser l'api GetForegroundWindow :

Option Explicit
Private Declare Function GetForegroundWindow Lib "user32" () As Long

Private Sub Timer1_Timer()
If GetForegroundWindow() = Me.hWnd Then
Me.Caption = "Chrono"
Else
Me.Caption = Time() 'A remplacer par la valeur de ton chrono
End If
End Sub


--
Cordialement,

Jacques.