[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 6
Niveau 6
Messages : 292
Enregistré le : lun. 03 oct. 2011 21:37
Localisation : Liévin
Contact :
Status : Hors ligne

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

#1

Message par franco » mer. 21 nov. 2018 18:35

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 : 1478
Enregistré le : lun. 23 mars 2009 04:50
Localisation : ::1
Contact :
Status : Hors ligne

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

#2

Message par orax » mer. 21 nov. 2018 19:45

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 6
Niveau 6
Messages : 292
Enregistré le : lun. 03 oct. 2011 21:37
Localisation : Liévin
Contact :
Status : Hors ligne

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

#3

Message par franco » lun. 26 nov. 2018 14:27

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