OVH Cloud OVH Cloud

Quelle application précédente ?

10 réponses
Avatar
Gloops
Bonjour tout le monde,

J'ai quelques programmes qui traitent le contenu du presse-papiers, tant
qu'à faire j'aimerais bien pousser le bouchon un peu plus loin, et
épargner à l'utilisateur d'avoir à presser Ctrl C avant le raccourci qui
déclenche mon programme.

J'ai cherché comment connaître le programme appelant. On a déjà séché
cinq fois ici à ce sujet. Peut-être bien que la liste des fenêtres peut
être une piste, pour ça. A titre de curiosité on peut adapter la fiche
188404, mais attention elle est écrite pour Fox Pro, il faut gratter un
peu (et pour ça avoir un peu pratiqué les API). Bon, c'est pour se
marrer et parce que je suis tombé dessus, parce que ça fait quand même
partie des sujets bâteaux j'imagine.

Mais finalement, je me rends compte que ce n'est pas le programme
appelant, que je cherche, mais la fenêtre précédemment active.

Imaginons que le bloc-notes soit ouvert, avec du texte de sélectionné
dedans, et que je presse les touches d'un raccourci sur mon programme,
se trouvant sur le bureau. Le programme appelant est explorer, mais je
voudrais que mon programme traite les données du bloc-notes.

Il y aurait bien SendKeys "%+{tab}", mais j'ai l'impression qu'il doit y
avoir plus orthodoxe -ça serait bien capable de ne pas marcher en plus.
Dans la liste des fenêtres, il semble que ça ne soit ni celle qui
précède celle du programme, ni celle qui suit.

Une idée ?

10 réponses

Avatar
François Picalausa
Hello,

Trouver la liste des applications en cours d'exécution n'est pas bien
compliqué (façon de parler - http://support.microsoft.com/kb/187913/en-us).
Mais ce que tu cherche se trouverait plutôt dans l'API GetClipboardOwner
(95+/NT3.1+) qui "In general, the clipboard owner is the window that last
placed data in clipboard." (En général, le possesseur du presse papier est
la fenêtre qui a, la dernière, placé des données dans le presse papier).

Voici un exemple qui insère la fenêtre dans la chaine des "clipboard
viewers", mais qui au lieu d'afficher des données affiche le titre de la
fenêtre ayant fournit celles-ci. Un composant qui sousclasse la fenêtre
utilisée afin de recevoir les messages WM_DRAWCLIPBOARD et WM_CHANGECBCHAIN.

Option Explicit

'API message queue
Private Declare Function SendMessage _
Lib "User32" _
Alias "SendMessageA" _
( _
ByVal hWnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
lParam As Any _
) _
As Long

'API clipboard viewer chain
Private Declare Function GetClipboardOwner _
Lib "User32" _
( _
) _
As Long
Private Declare Function SetClipboardViewer _
Lib "User32" _
( _
ByVal hWndNewViewer As Long _
) _
As Long
Private Declare Function ChangeClipboardChain _
Lib "User32" _
( _
ByVal hWndRemove As Long, _
ByVal hWndNewNext As Long _
) _
As Long

'API windowing
Private Declare Function GetWindowText _
Lib "User32" _
Alias "GetWindowTextA" _
( _
ByVal hWnd As Long, _
ByVal lpString As String, _
ByVal nMaxCount As Long _
) _
As Long
Private Declare Function GetWindowTextLength _
Lib "User32" _
Alias "GetWindowTextLengthA" _
( _
ByVal hWnd As Long _
) _
As Long
Private Declare Function GetParent _
Lib "User32" _
( _
ByVal hWnd As Long _
) _
As Long

'Messages
Private Const WM_DRAWCLIPBOARD = &H308
Private Const WM_CHANGECBCHAIN = &H30D

'Private vars
Private m_hwndNextViewer As Long 'Fenêtre suivante dans la chaine
des clipboard viewers
Private WithEvents Suclasser As SubClassing 'Objet de sousclassement

Private Sub Form_Load()
'Initialisations des variables
Set Suclasser = New SubClassing 'Objet de sousclassement

'Sousclasse notre fenêtre
Suclasser.SubClass Me.hWnd

'Rend notre fenêtre un clipboard viewer
m_hwndNextViewer = SetClipboardViewer(Me.hWnd)

Debug.Print m_hwndNextViewer
Debug.Print Err.LastDllError
End Sub

Private Sub Form_Unload(Cancel As Integer)
'Enlève notre fenêtre de la chaine des clipboard viewers
ChangeClipboardChain Me.hWnd, m_hwndNextViewer

'Désousclasse notre fenêtre, sousclassée à l'initialisation
Suclasser.UnSubclassAll
End Sub

Private Sub Suclasser_Message(ByVal hWnd As Long, ByVal Msg As Long, ByVal
wParam As Long, ByVal lParam As Long, SetNewValue As Boolean, NewValue As
Long)
'Debug.Print Msg
Select Case Msg
Case WM_DRAWCLIPBOARD
'Données fraiches!
Debug.Print "WM_DRAWCLIPBOARD"

Dim t_hwndOwner As Long 'Fenêtre d'où proviennent les
données
Dim t_szTitle As String 'Titre de cette fenêtre
Dim t_nTitleCount As Long 'Taille du titre

'Récupère la fenêtre
t_hwndOwner = GetClipboardOwner


'Initialise l'affichage des données
Me.Cls
Me.CurrentY = 10 * Screen.TwipsPerPixelY

'Affiche le titre de la fenêtre et des fenêtres parentes
While t_hwndOwner
Debug.Print Hex(t_hwndOwner)
Me.CurrentX = 10 * Screen.TwipsPerPixelX

'Récupère la longueur du titre
t_nTitleCount = GetWindowTextLength(t_hwndOwner)

'Si un titre est présent
If t_nTitleCount Then
'Détermine le titre
t_szTitle = String$(t_nTitleCount, vbNullChar)
GetWindowText t_hwndOwner, t_szTitle, t_nTitleCount + 1

'Et l'affiche
Me.Print t_szTitle
End If

'Fenêtre suivante
t_hwndOwner = GetParent(t_hwndOwner)
Wend
Case WM_CHANGECBCHAIN
If wParam = m_hwndNextViewer Then 'On a enlevé notre suivant
m_hwndNextViewer = lParam 'Le suivant suivant est stoqué
dans lParam

SetNewValue = True
NewValue = 0
ElseIf m_hwndNextViewer <> 0 Then
'On a enlevé le suivant d'une fenêtre plus loin dans la
liste
'On en informe le prochain viewer
SendMessage m_hwndNextViewer, WM_CHANGECBCHAIN, wParam,
lParam
End If
End Select
End Sub
-----------------------------------------------------------------

Il faut remarquer que la méthode pour récupérer le titre de la fenêtre n'est
pas géniale. Elle fonctionne dans le cas du bloc note et de l'une ou l'autre
application, mais il ne faut pas espérer de miracles!
On pourrait améliorer la technique en déterminant, par exemple, la process
qui a créé la fenêtre et en retrouvant les fenêtres principales de ce
process... Peut être un exemple à ce sujet plus tard...

Sinon, pour retrouver la fenêtre précédente ou suivante, on peut utiliser
l'API GetWindow. Mais les termes "fenêtre", "précédente" et "suivante" ne
sont pas ici ceux forcément voulus...
--
François Picalausa

"Gloops" a écrit dans le message de news:
428e1e2d$0$1224$
Bonjour tout le monde,

J'ai quelques programmes qui traitent le contenu du presse-papiers,
tant qu'à faire j'aimerais bien pousser le bouchon un peu plus loin,
et épargner à l'utilisateur d'avoir à presser Ctrl C avant le
raccourci qui déclenche mon programme.

J'ai cherché comment connaître le programme appelant. On a déjà séché
cinq fois ici à ce sujet. Peut-être bien que la liste des fenêtres
peut être une piste, pour ça. A titre de curiosité on peut adapter la
fiche 188404, mais attention elle est écrite pour Fox Pro, il faut
gratter un peu (et pour ça avoir un peu pratiqué les API). Bon, c'est
pour se marrer et parce que je suis tombé dessus, parce que ça fait
quand même partie des sujets bâteaux j'imagine.

Mais finalement, je me rends compte que ce n'est pas le programme
appelant, que je cherche, mais la fenêtre précédemment active.

Imaginons que le bloc-notes soit ouvert, avec du texte de sélectionné
dedans, et que je presse les touches d'un raccourci sur mon programme,
se trouvant sur le bureau. Le programme appelant est explorer, mais je
voudrais que mon programme traite les données du bloc-notes.

Il y aurait bien SendKeys "%+{tab}", mais j'ai l'impression qu'il
doit y avoir plus orthodoxe -ça serait bien capable de ne pas marcher
en plus. Dans la liste des fenêtres, il semble que ça ne soit ni
celle qui précède celle du programme, ni celle qui suit.

Une idée ?


Avatar
Gloops
Bonjour,

Oui, seulement il y a un os dans ce que tu dis : une fois que
l'application a mis ses données dans le presse-papiers, elle ne
m'intéresse plus. Le but était précisément d'aller chercher les données,
là où on était avant, pour que le programme fasse lui-même la copie.

Là je fais Ctrl-C puis Ctrl-T pour téléphoner, j'aimerais bien que ça se
fasse juste par Ctrl-T.

Donc, a priori, tant qu'on n'a pas copié le numéro dans le
presse-papiers, celui-ci est vide. Une fois que c'est fait, la question
ne se pose plus.

Même chose pour le programme qui va chercher une adresse avec des sauts
de lignes à supprimer.

Pas commode, la question, hein ...














François Picalausa a écrit, le 21/05/2005 01:21 :
Hello,

Trouver la liste des applications en cours d'exécution n'est pas bien
compliqué (façon de parler - http://support.microsoft.com/kb/187913/en-us).
Mais ce que tu cherche se trouverait plutôt dans l'API GetClipboardOwner
(95+/NT3.1+) qui "In general, the clipboard owner is the window that last
placed data in clipboard." (En général, le possesseur du presse papier est
la fenêtre qui a, la dernière, placé des données dans le presse papier).

Voici un exemple qui insère la fenêtre dans la chaine des "clipboard
viewers", mais qui au lieu d'afficher des données affiche le titre de la
fenêtre ayant fournit celles-ci. Un composant qui sousclasse la fenêtre
utilisée afin de recevoir les messages WM_DRAWCLIPBOARD et WM_CHANGECBCHAIN.

Option Explicit

'API message queue
Private Declare Function SendMessage _
Lib "User32" _
Alias "SendMessageA" _
( _
ByVal hWnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
lParam As Any _
) _
As Long

'API clipboard viewer chain
Private Declare Function GetClipboardOwner _
Lib "User32" _
( _
) _
As Long
Private Declare Function SetClipboardViewer _
Lib "User32" _
( _
ByVal hWndNewViewer As Long _
) _
As Long
Private Declare Function ChangeClipboardChain _
Lib "User32" _
( _
ByVal hWndRemove As Long, _
ByVal hWndNewNext As Long _
) _
As Long

'API windowing
Private Declare Function GetWindowText _
Lib "User32" _
Alias "GetWindowTextA" _
( _
ByVal hWnd As Long, _
ByVal lpString As String, _
ByVal nMaxCount As Long _
) _
As Long
Private Declare Function GetWindowTextLength _
Lib "User32" _
Alias "GetWindowTextLengthA" _
( _
ByVal hWnd As Long _
) _
As Long
Private Declare Function GetParent _
Lib "User32" _
( _
ByVal hWnd As Long _
) _
As Long

'Messages
Private Const WM_DRAWCLIPBOARD = &H308
Private Const WM_CHANGECBCHAIN = &H30D

'Private vars
Private m_hwndNextViewer As Long 'Fenêtre suivante dans la chaine
des clipboard viewers
Private WithEvents Suclasser As SubClassing 'Objet de sousclassement

Private Sub Form_Load()
'Initialisations des variables
Set Suclasser = New SubClassing 'Objet de sousclassement

'Sousclasse notre fenêtre
Suclasser.SubClass Me.hWnd

'Rend notre fenêtre un clipboard viewer
m_hwndNextViewer = SetClipboardViewer(Me.hWnd)

Debug.Print m_hwndNextViewer
Debug.Print Err.LastDllError
End Sub

Private Sub Form_Unload(Cancel As Integer)
'Enlève notre fenêtre de la chaine des clipboard viewers
ChangeClipboardChain Me.hWnd, m_hwndNextViewer

'Désousclasse notre fenêtre, sousclassée à l'initialisation
Suclasser.UnSubclassAll
End Sub

Private Sub Suclasser_Message(ByVal hWnd As Long, ByVal Msg As Long, ByVal
wParam As Long, ByVal lParam As Long, SetNewValue As Boolean, NewValue As
Long)
'Debug.Print Msg
Select Case Msg
Case WM_DRAWCLIPBOARD
'Données fraiches!
Debug.Print "WM_DRAWCLIPBOARD"

Dim t_hwndOwner As Long 'Fenêtre d'où proviennent les
données
Dim t_szTitle As String 'Titre de cette fenêtre
Dim t_nTitleCount As Long 'Taille du titre

'Récupère la fenêtre
t_hwndOwner = GetClipboardOwner


'Initialise l'affichage des données
Me.Cls
Me.CurrentY = 10 * Screen.TwipsPerPixelY

'Affiche le titre de la fenêtre et des fenêtres parentes
While t_hwndOwner
Debug.Print Hex(t_hwndOwner)
Me.CurrentX = 10 * Screen.TwipsPerPixelX

'Récupère la longueur du titre
t_nTitleCount = GetWindowTextLength(t_hwndOwner)

'Si un titre est présent
If t_nTitleCount Then
'Détermine le titre
t_szTitle = String$(t_nTitleCount, vbNullChar)
GetWindowText t_hwndOwner, t_szTitle, t_nTitleCount + 1

'Et l'affiche
Me.Print t_szTitle
End If

'Fenêtre suivante
t_hwndOwner = GetParent(t_hwndOwner)
Wend
Case WM_CHANGECBCHAIN
If wParam = m_hwndNextViewer Then 'On a enlevé notre suivant
m_hwndNextViewer = lParam 'Le suivant suivant est stoqué
dans lParam

SetNewValue = True
NewValue = 0
ElseIf m_hwndNextViewer <> 0 Then
'On a enlevé le suivant d'une fenêtre plus loin dans la
liste
'On en informe le prochain viewer
SendMessage m_hwndNextViewer, WM_CHANGECBCHAIN, wParam,
lParam
End If
End Select
End Sub
-----------------------------------------------------------------

Il faut remarquer que la méthode pour récupérer le titre de la fenêtre n'est
pas géniale. Elle fonctionne dans le cas du bloc note et de l'une ou l'autre
application, mais il ne faut pas espérer de miracles!
On pourrait améliorer la technique en déterminant, par exemple, la process
qui a créé la fenêtre et en retrouvant les fenêtres principales de ce
process... Peut être un exemple à ce sujet plus tard...

Sinon, pour retrouver la fenêtre précédente ou suivante, on peut utiliser
l'API GetWindow. Mais les termes "fenêtre", "précédente" et "suivante" ne
sont pas ici ceux forcément voulus...


Avatar
Alain CROS
Bonjour.

J'ai pas tout compris mais ...

|
| Mais finalement, je me rends compte que ce n'est pas le programme
| appelant, que je cherche, mais la fenêtre précédemment active.
|

Regarder le message WM_ACTIVATE qui fournit le handle de la fenêtre active précédente.

Alain CROS

"Gloops" a écrit dans le message de news: 428e1e2d$0$1224$
| Bonjour tout le monde,
|
Avatar
François Picalausa
Hello,

Je comprends mieux la question... Peut-être est-il possible de ne pas
changer l'état du système avant d'effectuer la copie, en manipulant
différemment le raccourci clavier?
Voici un exemple avec RegisterHotKey:
Option Explicit

Private Declare Function RegisterHotKey _
Lib "user32" _
( _
ByVal hwnd As Long, _
ByVal id As Long, _
ByVal fsModifiers As Long, _
ByVal vk As Long _
) _
As Long
Private Declare Function UnregisterHotKey _
Lib "user32" _
( _
ByVal hwnd As Long, _
ByVal id As Long _
) _
As Long

Private WithEvents Subclasser As SubClassing

Private Sub Form_Load()
'Sousclasse notre form
Set Subclasser = New SubClassing
Subclasser.SubClass Me.hwnd

Me.Visible = False 'La feuille ne doit pas être visible... envisager
une icône dans le tray

'Enregistre les touches de raccourci
RegisterHotKey Me.hwnd, 0, MOD_CONTROL, &H46 'Ctrl+F - Quitte
RegisterHotKey Me.hwnd, 1, MOD_CONTROL, &H54 'Ctrl+T - Copie
End Sub

Private Sub Subclasser_Message(ByVal hwnd As Long, ByVal Msg As Long, ByVal
wParam As Long, ByVal lParam As Long, SetNewValue As Boolean, NewValue As
Long)
Select Case Msg
Case WM_HOTKEY 'On a appelé l'une des hotkeys?
DispatchInput wParam 'Informe la procédure de traitement
End Select
End Sub

Private Sub DispatchInput(lID As Long)
Select Case lID
Case 0 'Ctrl+F
Unload Me
Case 1 'Ctrl+T
'Envoie une commande de copie
SendKeys "^C", True
'Lance l'application qui doit recevoir l'entrée du clipboard
MsgBox Clipboard.GetText
End Select
End Sub

Private Sub Form_Unload(Cancel As Integer)
'Vire les hotkeys
UnregisterHotKey Me.hwnd, 0
UnregisterHotKey Me.hwnd, 1

'Désousclasse la feuille
Subclasser.UnSubclassAll
End Sub

Le problème vient alors de la méthode de copie... toutes les applications ne
sont pas obligées de supporter Ctrl+C pour copier (ni WM_COPY d'ailleurs).
Il est possible de retrouver le nom de l'exécutable
(GetWindowModuleFileName) à partir de la fenêtre active
(GetForegroundWindow) pour envoyer la combinaison de touches correctes. Pour
envoyer WM_COPY, la technique me semble plus compliquée. Il faudrait (non
testé) retrouver la fenêtre qui a le focus, ce qui peut être fait en
attachant (AttachThreadInput) ton thread (GetCurrentThreadId) au thread de
la fenêtre active (GetForegroundWindow - GetWindowThreadProcessId) pour
ensuite appeler GetFocus et envoyer WM_COPY à la fenêtre.
Donc, amha, trouver un moyen pour conserver le ctrl+c (donc clipboard
viewer) est plus propre (pas besoin de connaitre les détails de
l'application appelante).

--
François Picalausa

"Gloops" a écrit dans le message de news:
428ec68f$0$11682$
Bonjour,

Oui, seulement il y a un os dans ce que tu dis : une fois que
l'application a mis ses données dans le presse-papiers, elle ne
m'intéresse plus. Le but était précisément d'aller chercher les
données, là où on était avant, pour que le programme fasse lui-même
la copie.
Là je fais Ctrl-C puis Ctrl-T pour téléphoner, j'aimerais bien que ça
se fasse juste par Ctrl-T.

Donc, a priori, tant qu'on n'a pas copié le numéro dans le
presse-papiers, celui-ci est vide. Une fois que c'est fait, la
question ne se pose plus.

Même chose pour le programme qui va chercher une adresse avec des
sauts de lignes à supprimer.


François Picalausa a écrit, le 21/05/2005 01:21 :
Hello,
<blah blah blah>




Avatar
Gloops
Hello,

Il faudra que je relise ça tranquillement.
Au premier survol, tu envisages de créer un raccourci qui simule deux
combinaisons de touches successives ?
C'est bien astucieux.

Il y aurait aussi le programme chargé en permanence qui guetterait une
touche magique, mais gare à la taille mémoire.

Comme je n'ai pas encore vraiment épluché le truc je n'ai pas vu si
c'était prêt à l'emploi ou juste une piste de recherche. Je regarde ce
soir ou demain.

Pour le support de Ctrl C il ne devrait pas y avoir de problème avec les
applications utilisées. Dans un cas il y a surtout les applications de
messagerie et newsgroups, dans l'autre le bloc notes ou Excel.

Il faut juste ne pas se gourrer sur le focus, surtout avec SendKeys.
J'ai fait une tentative d'utiliser SendMessage l'autre jour pour autre
chose, ce n'était pas une gloire.

Je m'étais basé sur
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/keyboardinput/keyboardinputreference/keyboardinputmessages/wm_keydown.asp
(dit autrement, http://minilien.fr/a0k065 )
avec l'impression que j'avais dû me tromper sur le contenu de lparam

Il fallait envoyer un + à une fenêtre, j'avais essayé
SendMessage hWndFen, WM_KEYDOWN, VK_ADD, &H2B03
SendMessage hWndFen, WM_KEYUP, VK_ADD, &H2B03

ainsi que
SendMessage hWndFen, WM_CHAR, VK_ADD, &H2B03

Ben que dalle, ça s'est soldé par un SendKeys.

D'ailleurs pour la sélection de la fenêtre j'y ai mis les moyens :

Public Sub SelFen(hwnd As Long)
ShowWindow hwnd, SW_RESTORE
SetFocus hwnd
SetForegroundWindow hwnd
SetActiveWindow hwnd
End Sub

et elle a fini par se sélectionner, ah mais.

Il faudra que je me remette à tout ça en ayant du temps devant moi, ça
aide à se concentrer ...

Merci pour ton exemple.

François Picalausa a écrit, le 21/05/2005 11:57 :

Hello,

Je comprends mieux la question... Peut-être est-il possible de ne pas
changer l'état du système avant d'effectuer la copie, en manipulant
différemment le raccourci clavier?
Voici un exemple avec RegisterHotKey:
Option Explicit

Private Declare Function RegisterHotKey _
Lib "user32" _
( _
ByVal hwnd As Long, _
ByVal id As Long, _
ByVal fsModifiers As Long, _
ByVal vk As Long _
) _
As Long
Private Declare Function UnregisterHotKey _
Lib "user32" _
( _
ByVal hwnd As Long, _
ByVal id As Long _
) _
As Long

Private WithEvents Subclasser As SubClassing

Private Sub Form_Load()
'Sousclasse notre form
Set Subclasser = New SubClassing
Subclasser.SubClass Me.hwnd

Me.Visible = False 'La feuille ne doit pas être visible... envisager
une icône dans le tray

'Enregistre les touches de raccourci
RegisterHotKey Me.hwnd, 0, MOD_CONTROL, &H46 'Ctrl+F - Quitte
RegisterHotKey Me.hwnd, 1, MOD_CONTROL, &H54 'Ctrl+T - Copie
End Sub

Private Sub Subclasser_Message(ByVal hwnd As Long, ByVal Msg As Long, ByVal
wParam As Long, ByVal lParam As Long, SetNewValue As Boolean, NewValue As
Long)
Select Case Msg
Case WM_HOTKEY 'On a appelé l'une des hotkeys?
DispatchInput wParam 'Informe la procédure de traitement
End Select
End Sub

Private Sub DispatchInput(lID As Long)
Select Case lID
Case 0 'Ctrl+F
Unload Me
Case 1 'Ctrl+T
'Envoie une commande de copie
SendKeys "^C", True
'Lance l'application qui doit recevoir l'entrée du clipboard
MsgBox Clipboard.GetText
End Select
End Sub

Private Sub Form_Unload(Cancel As Integer)
'Vire les hotkeys
UnregisterHotKey Me.hwnd, 0
UnregisterHotKey Me.hwnd, 1

'Désousclasse la feuille
Subclasser.UnSubclassAll
End Sub

Le problème vient alors de la méthode de copie... toutes les applications ne
sont pas obligées de supporter Ctrl+C pour copier (ni WM_COPY d'ailleurs).
Il est possible de retrouver le nom de l'exécutable
(GetWindowModuleFileName) à partir de la fenêtre active
(GetForegroundWindow) pour envoyer la combinaison de touches correctes. Pour
envoyer WM_COPY, la technique me semble plus compliquée. Il faudrait (non
testé) retrouver la fenêtre qui a le focus, ce qui peut être fait en
attachant (AttachThreadInput) ton thread (GetCurrentThreadId) au thread de
la fenêtre active (GetForegroundWindow - GetWindowThreadProcessId) pour
ensuite appeler GetFocus et envoyer WM_COPY à la fenêtre.
Donc, amha, trouver un moyen pour conserver le ctrl+c (donc clipboard
viewer) est plus propre (pas besoin de connaitre les détails de
l'application appelante).



Avatar
Gloops
Bonjour,

Comme je disais à François, j'ai un peu travaillé avec les fonctions
message, et ça n'a pas été une gloire. Je m'y remettrai, parce que c'est
quand même le meilleur moyen d'être sûr de savoir à quelle fenêtre on
s'adresse.

Alors il ne va pas falloir confondre, il existe une constante
WM_ACTIVATE qui vaut 6, et je vois qu'il existe aussi une notification
WM_ACTIVATE qui prend deux structures en paramètres, et là pour le
moment je dois avouer que je ne sais pas du tout de quoi il retourne.

Pas à chipoter, il faudra s'y plonger sérieusement.













Alain CROS a écrit, le 21/05/2005 11:46 :

Bonjour.

J'ai pas tout compris mais ...

|
| Mais finalement, je me rends compte que ce n'est pas le programme
| appelant, que je cherche, mais la fenêtre précédemment active.
|

Regarder le message WM_ACTIVATE qui fournit le handle de la fenêtre active précédente.

Alain CROS

"Gloops" a écrit dans le message de news: 428e1e2d$0$1224$
| Bonjour tout le monde,
|




Avatar
François Picalausa
Hello,

"Gloops" a écrit dans le message de news:
428f3a96$0$1216$
Au premier survol, tu envisages de créer un raccourci qui simule deux
combinaisons de touches successives ?
C'est bien astucieux.



En réalité, il s'agit d'associer avec une fenêtre cachée un nouveau
raccourci (hotkey).
Lorsque ce raccourci clavier est appelé, il appelle lui même Ctrl+C. Puisque
la fenêtre est cachée quand on effectue l'action, "l'état" du système n'a
pas changé (la même fenêtre reste active). On peut alors effectuer le
traitement voulu et afficher une feuille ou l'autre.
S'il y a deux raccourci, c'est que pour quitter l'application autrement que
par le boutton stop, il faut un moyen... Ca montre au passage comment avec
une appli en arrière plan on peut traiter différents raccourcis.

Concernant WM_ACTIVATE, qui ne me semble pas du tout une mauvaise solution
(tant qu'on peut l'intercepter), en fait, la valeur 6 et le message avec
deux structure c'est la même chose.
Il faut savoir qu'avant tout un message que tu envoie, et qui sera une
notification reçue par la fenêtre, est avant tout un nombre. Ce nombre
décrit une action mais définit aussi les paramètres que l'on peut espérer
trouver. Ces paramètres sont stoqués dans wParam et lParam.

Dans l'exemple des hotkeys, on traite le message WM_HOTKEY, notification
envoyée par Windows dans ce cas. wParam contient pour ce message l'id de la
hotkey correspondante.

--
François Picalausa
Avatar
Gloops
François Picalausa a écrit, le 21/05/2005 16:22 :

En réalité, il s'agit d'associer avec une fenêtre cachée un nouveau
raccourci (hotkey).
Lorsque ce raccourci clavier est appelé, il appelle lui même Ctrl+C. Puisque
la fenêtre est cachée quand on effectue l'action, "l'état" du système n'a
pas changé (la même fenêtre reste active). On peut alors effectuer le
traitement voulu et afficher une feuille ou l'autre.
S'il y a deux raccourci, c'est que pour quitter l'application autrement que
par le boutton stop, il faut un moyen... Ca montre au passage comment avec
une appli en arrière plan on peut traiter différents raccourcis.



C'est bien ce qu'il m'avait semblé comprendre ...
En planchant à deux on devrait finir par pondre un truc que tout le
monde comprendrait ;)


Concernant WM_ACTIVATE, qui ne me semble pas du tout une mauvaise solution
(tant qu'on peut l'intercepter), en fait, la valeur 6 et le message avec
deux structure c'est la même chose.
Il faut savoir qu'avant tout un message que tu envoie, et qui sera une
notification reçue par la fenêtre, est avant tout un nombre. Ce nombre
décrit une action mais définit aussi les paramètres que l'on peut espérer
trouver. Ces paramètres sont stoqués dans wParam et lParam.

Dans l'exemple des hotkeys, on traite le message WM_HOTKEY, notification
envoyée par Windows dans ce cas. wParam contient pour ce message l'id de la
hotkey correspondante.



Mouais, en fait on utilise SendMessage, avec WM_ACTIVATE dans le numéro
du message, et le reste de la sauce dans les deux autres paramètres.
Tout-à-l'heure en lisant la doc ça m'avait échappé.
Avatar
Gloops
Youpi, cinq minutes pour mettre en oeuvre !

Voilà le module que j'ai ajouté :

Public Sub Main()
SendKeys "^c", True
Form1.Show
End Sub


Ensuite, plus qu'à changer l'objet de démarrage, remplacer Form1 par
Main, hop, compilation, et c'est réglé.

Merci François. Suffisait d'y penser.
Avatar
Gloops
Gloops a écrit, le 22/05/2005 00:43 :

Youpi, cinq minutes pour mettre en oeuvre !

Voilà le module que j'ai ajouté :

Public Sub Main()
SendKeys "^c", True
Form1.Show
End Sub



_____________________________________________________
Ah, nuance.
Ce que j'ai dit là fonctionne bien avec les touches rémanentes (Ctrl,
Alt et Maj provoquent un bip et restent mémorisés jusqu'à ce qu'on
presse une touche de caractère), en revanche si on garde enfoncées Alt
ou Maj., liés au raccourci de lancement, au moment du SendKeys "^c" le c
va être affecté de Alt ou Maj et ne provoquera pas de copie dans le
presse-papiers.

Dans le cas du téléphone où l'appel est lancé par Ctrl T (je parle de ma
machine bien sûr) le problème ne se pose pas, mais pour le navigateur
via presse-papiers, c'est Alt Maj N, dont là il faut avoir le doigt léger.

J'ai donc finalement introduit une finasserie supplémentaire :
================================== Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Public Sub Main()
Dim N As Integer
ClipBoard_SetData ""
N = 0
While ClipBoard_GetData() = "" And N < 10
Sleep 1000
SendKeys "^c", True
DoEvents
N = N + 1
Wend
If ClipBoard_GetData <> "" Then
Form1.Show
Else
MsgBox "Aucun texte sélectionné"
End If
End Sub
================================== On trouve facilement Clipboard_GetData() et Clipboard_SetData() en
cherchant via Google. La seule difficulté peut être, si on veut mettre
les deux dans le même module, de purger les doubles déclarations.
Vachement dur, n'est-ce pas.

Sur ce coup-là je ne me suis pas cassé la tête, je me suis contenté de
SendKeys. Après il restera à faire plus propre, et gérer ça par
SendMessage. Un chapitre de plus à potasser.

Je me rends compte juste maintenant qu'il pourrait être judicieux
d'ajouter un SendKeys "^c" juste avant le While, pour éviter le délai
d'une seconde si on utilise les touches rémanentes. A tester.