[R] Contrôler une fenêtre avec SEND

Aide et conseils concernant AutoIt et ses outils.
Règles du forum
.
Répondre
Avatar du membre
franco
Niveau 7
Niveau 7
Messages : 342
Enregistré le : lun. 03 oct. 2011 22:37
Localisation : Liévin
Status : Hors ligne

[R] Contrôler une fenêtre avec SEND  

#1

Message par franco »

Bonjour.

J'ai un petit projet en tête, que d'autres ont déjà réalisé, mais en largement plus complet... :mrgreen:

Je n'ai besoin que d'une seule action, donc je préfère la créer moi-même.

Je vais faire donc au plus simple : j'essaye de contrôler une fenêtre avec send.
Exemple : un ALT+F pour afficher le menu "Fichier" du bon vieux notepad...

Ici, je décide de contrôler la fenêtre active, via l'icône de notification...


Voici mon script :
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <TrayConstants.au3>



Opt("TrayMenuMode", 3)

;~ HotKeySet("^!{UP}",_MoveThisWindow)
;~ HotKeySet("^!{DOWN}",_MoveThisWindow)
;~ HotKeySet("^!{LEFT}",_MoveThisWindow)
;~ HotKeySet("^!{RIGHT}",_MoveThisWindow)

$Action_Move = TrayCreateItem("action")
TrayCreateItem("") ; Create a separator line.
Local $SystrayEXIT = TrayCreateItem("Quitter")
TraySetState($TRAY_ICONSTATE_SHOW) ; Show the tray menu

While 1
   Switch TrayGetMsg()
      Case $SystrayEXIT ; Exit the loop.
         Exit
      case $Action_Move
         _MoveThisWindow()


   EndSwitch
WEnd






Func _MoveThisWindow()

$hWindow = WinGetHandle("[active]")
$title = WinGetTitle("[active]")
ConsoleWrite($title&@CRLF&$hWindow & @CRLF)
WinSetState($hWindow,"",@SW_MAXIMIZE) ; juste un test, pour voir si j'aggrandis la bonne fenêtre
Send("!f") ; le fameux ALT+F ^^

EndFunc

Et là, c'est le drame :lol:

Récapitulons
;
  1. J'affiche comme titre AutoIt v3 et comme handle 0x0000000000080966, à chaque fois...
  2. J’agrandis donc la fenêtre l'icône de notification (XD)

En gros : je contrôle pas le bon élément, puisqu'il détecte l'icone de notification, comme étant actif...


Question : comment faire pour que ce dernier ne soit pas systématiquement pris en compte ?

Réflexion : Dois-je, pour m'assurer de la bonne détection de la fenêtre active, liste les derniers fenêtres actifs, en excluant le titre et le handle d'AutoIt V3 ?


Merci d'avance pour vos lumières ;)



PS : Pour info, je cherche juste à déplacer une fenêtre (active ici) sur un second écran, avec la combinaison WIn+Shift+Gauche (ou droite)


++
Modifié en dernier par franco le lun. 26 nov. 2018 14:27, modifié 1 fois.
L'entraide, c'est mon dada ;)
Avatar du membre
orax
Modérateur
Modérateur
Messages : 1479
Enregistré le : lun. 23 mars 2009 04:50
Localisation : ::1
Status : Hors ligne

Re: [..] Contrôler une fenêtre avec SEND

#2

Message par orax »

Il faudrait activer la fenêtre précédemment activée. Quand on clique on dehors de la fenêtre affichée, elle n'est plus active.
Tu pourrais essayer une fonction de jguinch (_WinGetNextWindow). Lien vers le code : https://www.autoitscript.com/forum/topi ... nt=1220745
De petits détails peuvent faire toute la différence. — Quand la boule de neige commence à rouler… poussez-la. (Columbo)
Avatar du membre
franco
Niveau 7
Niveau 7
Messages : 342
Enregistré le : lun. 03 oct. 2011 22:37
Localisation : Liévin
Status : Hors ligne

Re: [..] Contrôler une fenêtre avec SEND

#3

Message par franco »

Salut.

Désolé de répondre que maintenant, mais le boulot me prend trop de temps.
Et, de plus, j'attendais que le script soit fini et opérationnel avant de poster. ^^

Voici le code (merci à toi orax, et jguinch)
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=n
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <WindowsConstants.au3>
#include <TrayConstants.au3>

$item = ""

Opt("TrayMenuMode", 3)

Global $Form1 = GUICreate("Form1", 800, 800, 192, 124)

Local $aList = WinList()

; Loop through the array displaying only visable windows with a title.
For $a = 1 To $aList[0][0]
   If $aList[$a][0] <> "" And BitAND(WinGetState($aList[$a][1]), 2) Then
      $item &= $aList[$a][0] & "|" & $aList[$a][1] & @CRLF
   EndIf
Next

$listwin_lv = GUICtrlCreateListView("Titre de la fenêtre|ID de la fenêtre", 0, 0, 800, 400)
GUICtrlSendMsg($listwin_lv, 4126, 0, 400)
GUICtrlSendMsg($listwin_lv, 4126, 1, 400)

For $b = 1 To StringSplit($item, @LF)[0]
   If StringSplit($item, @LF)[$b] <> "" Then GUICtrlCreateListViewItem(StringSplit($item, @LF)[$b], $listwin_lv)
Next


$deplacer_sel = GUICtrlCreateButton("Déplacer cette fenêtre sur l'autre écran", 10, 410, 220, 20)
$reset = GUICtrlCreateButton("🔄", 240, 410, 20, 20)
GUICtrlSetFont(-1, 18)




$Action_Move = TrayCreateItem("Déplacer la fenêtre active sur l'autre moniteur")
TrayCreateItem("") ; Create a separator line.
$Action_GUI =  TrayCreateItem("Afficher / Masquer l'interface")
TrayItemSetState(-1,513)
TrayCreateItem("") ; Create a separator line.

Local $SystrayEXIT = TrayCreateItem("Quitter")
TraySetState($TRAY_ICONSTATE_SHOW) ; Show the tray menu



GUISetState(@SW_HIDE)



While 1
   $nMsg = GUIGetMsg()
   Switch $nMsg
      Case $GUI_EVENT_CLOSE
         Exit

      Case $deplacer_sel

         $indice = _GUICtrlListView_GetSelectedIndices($listwin_lv)
         $ID = _GUICtrlListView_GetItem($listwin_lv, Int($indice), 0)[3]
         $titre = _GUICtrlListView_GetItem($listwin_lv, Int($indice), 1)[3]

         If $indice <> "" Then
            WinActivate($ID)
            Send("#+{LEFT}")
         EndIf

      Case $reset
         _GUICtrlListView_DeleteAllItems(GUICtrlGetHandle($listwin_lv))
         For $b = 1 To StringSplit($item, @LF)[0]
            If StringSplit($item, @LF)[$b] <> "" Then GUICtrlCreateListViewItem(StringSplit($item, @LF)[$b], $listwin_lv)
         Next

   EndSwitch

   Switch TrayGetMsg()
      Case $SystrayEXIT ; Exit the loop.
         Exit
      Case $Action_Move
         _MoveThisWindow()
      Case $Action_GUI
         $state = WinGetState($Form1, "")
         If BitAND($state, 2) Then
            GUISetState(@SW_HIDE, $Form1)
         Else
            GUISetState(@SW_SHOW, $Form1)
         EndIf


   EndSwitch
WEnd






Func _MoveThisWindow()

   $hWindow = _WinGetNextWindow()
   WinActivate($hWindow)
   Send("#+{LEFT}")

EndFunc   ;==>_MoveThisWindow


Func _WinGetNextWindow()
   Local $aGetWindow, $hWnd = WinGetHandle("[active]")
   If $hWnd = 0 Then Return SetError(2, 0, 0)

   If Not IsDeclared("GW_HWNDNEXT") Then Local Const $GW_HWNDNEXT = 2
   If Not IsDeclared("GW_HWNDPREV") Then Local Const $GW_HWNDPREV = 3

   While 1
      $aGetWindow = DllCall("User32.dll", "hwnd", "GetWindow", "hwnd", $hWnd, "uint", 2)
      If @error Then Return SetError(4, 0, 0)
      If $aGetWindow[0] = 0 Then ExitLoop

      $hWnd = $aGetWindow[0]

      $aGetWindowLong = DllCall("User32.dll", "long", "GetWindowLong", "hwnd", $hWnd, "int", -16)
      If @error Then ExitLoop

      If Not BitAND(WinGetState($hWnd), 2) Or $aGetWindowLong[0] < 0 Then ContinueLoop

      Return $hWnd
   WEnd

   Return SetError(1, 0, 0)
EndFunc   ;==>_WinGetNextWindow

Comme vous pouvez le constatez, j'ai réussi donc, grâce au lien donné, à récupérer la dernière fenêtre activée.

J'ai décidé aussi d'inclure une interface graphique, cachée par défaut, qu'on peut dévoiler via l'icône dans la zone de notification...


Via l'icone donc :
- on peut déplacer la fenêtre active sur l'autre moniteur.
- afficher l'interface.
- quitter le programme.

et via l'interface :
- afficher les fenêtre actifs et visibles.
- sélectionner et déplacer la fenêtre concernée, sur l'autre moniteur.


Merci :D
je passe en résolu.

++
L'entraide, c'est mon dada ;)
Répondre