[R] Focus sur la fenêtre principale

Aide et conseils concernant AutoIt et ses outils.
Règles du forum
.
Répondre
tyler911
Niveau 1
Niveau 1
Messages : 7
Enregistré le : mer. 01 févr. 2012 13:11
Status : Hors ligne

[R] Focus sur la fenêtre principale

#1

Message par tyler911 »

Hello,

je me décide à poster car je ne sais pas comment résoudre le problème, à savoir :

J'ai une petite application AutoIt en "eventMode" à 1 ( Opt("GUIOnEventMode", 1) ) dont je voudrais quelle effectue une opération lorsqu'elle reprend le focus.
j'y parvient partiellement en utilisant :

Code : Tout sélectionner

GUISetOnEvent($GUI_EVENT_RESTORE, "checkOnFocus")
GUISetOnEvent($GUI_EVENT_MAXIMIZE, "checkOnFocus")
GUISetOnEvent($GUI_EVENT_RESIZED, "checkOnFocus")
 
Ça fonctionne lorsque je la réduit avec le bouton de réduction ( en haut à droite ) et que je revient sur la fenêtre de l'application mais pas, et c'est là le soucis, lorsque je tabule ( Alt + tab ) de l'application vers une autre application et que j'y reviens.

Je ne sais plus par quel bout y prendre...? Merci d'avance ;)
Modifié en dernier par tyler911 le jeu. 02 févr. 2012 14:10, modifié 1 fois.
Avatar du membre
ZDS
Membre émérite
Membre émérite
Messages : 554
Enregistré le : jeu. 10 juin 2010 10:35
Localisation : 22300 Cul-d'chouette Langue-de-vache
Status : Hors ligne

Re: [..] Focus sur la fenêtre principale

#2

Message par ZDS »

Bonjour,

Je ne suis pas très calé en OEM (certains accès concurrents peuvent tout faire planter), je suis plutôt branché GGM (GuiGetMsg et traitement à la chaîne ^^). Mais je pense que tu devrais chercher du coté de GUIRegisterMsg(...)

Par contre, pour pouvoir te donner plus d'aide et/ou plus d'infos, j'aimerais bien partir d'un script fonctionnel (ou tout au moins qu'on puisse lancer), donc si tu pouvais poster ton script ça ferait gagner du temps. Tu peux aussi regarder mes messages sur ce sujet, ça traite du même principe : http://www.autoitscript.fr/forum/viewto ... f=4&t=9158

A bientôt !
ZDS : Chef de projet du nAiO (logiciel AutoIt gratuit sous licence CC 4.0 BY-NC-SA)
Tout problème a une solution, donc si il y a pas d'solution, c'est qu'il y a pas d'problème !
tyler911
Niveau 1
Niveau 1
Messages : 7
Enregistré le : mer. 01 févr. 2012 13:11
Status : Hors ligne

Re: [..] Focus sur la fenêtre principale

#3

Message par tyler911 »

Le code n'avancera guère à mon avis il est spécifique et sert à faire des impressions sur une imprimante d'un certain type.
Je souhaite juste faire un appel de fonction à chaque fois que la fenêtre de mon application récupère le focus ou mieux, à chaque fois qu'elle revient à l'avant plan...
Avatar du membre
ZDS
Membre émérite
Membre émérite
Messages : 554
Enregistré le : jeu. 10 juin 2010 10:35
Localisation : 22300 Cul-d'chouette Langue-de-vache
Status : Hors ligne

Re: [..] Focus sur la fenêtre principale

#4

Message par ZDS »

Ça serait quand même plus simple (pour celui qui tente de t'aider, aka moi en l’occurrence) de partir d'un code que tu as fait, histoire de pas passer des heures sur un script pour qu'il fonctionne alors que deux minutes auraient suffit en partant d'un exemple potable... Au pire, envoie ton script en bouchonnant les fonctions qui traitent de ta gestion d'imprimante.

Bref, un peu de bonne volonté de ta part serait pas de refus ^^ Mais en attendant, voici un exemple qui pourrait te dépanner :
► Afficher le texteexemple d'utilisation de GUIRegisterMsg en GGM
A bientôt !
ZDS : Chef de projet du nAiO (logiciel AutoIt gratuit sous licence CC 4.0 BY-NC-SA)
Tout problème a une solution, donc si il y a pas d'solution, c'est qu'il y a pas d'problème !
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [..] Focus sur la fenêtre principale

#5

Message par mikell »

Hum c'est quand même tendu...
Sur mon pc à thème customisé le seul truc qui marche sans bug c'est ça
► Afficher le texte
Sinon j'ai des comportements indésirables du genre msgbox qui s'affiche 2 fois, ou incrustations étranges persistantes dans la gui :shock:
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
tyler911
Niveau 1
Niveau 1
Messages : 7
Enregistré le : mer. 01 févr. 2012 13:11
Status : Hors ligne

Re: [..] Focus sur la fenêtre principale

#6

Message par tyler911 »

ZDS > Effectivement je pense que tu as raison il faut chercher de ce coté

Mikell > J'ai testé ton script tel quel il fonctionne correctement, de ce point de vue c'est super, par contre je l'ai modifié pour passer en mode GUIOnEventMode = 1 et là il fonctionne aussi, ça donne :

Code : Tout sélectionner

#Include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Opt("GUIOnEventMode", 1)

Global $test = 0

$gui = GUICreate("")
GUISetState()
GUIRegisterMsg(0x0007, "OnFocus")      ; 0x0007 = WM_SETFOCUS

While 1
    if WinActive($gui) Then $test = 0
    Sleep(1000)
WEnd

Func OnFocus($hWnd, $Msg, $wParam, $lParam)
 If $test = 0 Then
    msgbox(0,"","ok")
    $test = 1
   _WinAPI_RedrawWindow($gui, "", "", BitOR($RDW_INVALIDATE, $RDW_UPDATENOW))
EndIf
  Return $GUI_RUNDEFMSG
EndFunc

Func _WinAPI_RedrawWindow($hWnd, $tRect = 0, $hRegion = 0, $iFlags = 5)
    Local $pRect = 0
    If $tRect <> 0 Then $pRect = DllStructGetPtr($tRect)
    Local $aResult = DllCall("user32.dll", "bool", "RedrawWindow", "hwnd", $hWnd, "ptr", $pRect, "handle", $hRegion, "uint", $iFlags)
    If @error Then Return SetError(@error, @extended, False)
    Return $aResult[0]
EndFunc   ;==>_WinAPI_RedrawWindow
 
Du coup je me suis dis que c'était gagné et j'ai intégré tout ça à mon code original, et là les problèmes commencent, à savoir :
- A la compil il me dit que la fonction "_WinAPI_RedrawWindow" est déjà déclarée, donc je l'ai renommé en "redrawWin" pour palier au problème.
- Après renommage de la fonction susnommée ça fonctionne la première fois uniquement : J'utilise "Alt+tab" pour changer de fenêtre, je reviens sur mon appli toujours avec "Alt+tab", ça fonctionne une fois et ensuite plus rien...

Je pose ( enfin ;) ) mon code pour faciliter les choses :

Code : Tout sélectionner

#include <array.au3>
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <ComboConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiComboBox.au3>
#include <GuiEdit.au3>
#include <WinAPI.au3>
#include <mysql.au3>

#cs
#
# Opt
#
#ce
Opt("GUIOnEventMode", 1)
Opt('MustDeclareVars', 1)

Const $version = "1.0", $copyright = "©2012", $mail = "", $iniFile = @ScriptDir & "\rip.ini"
Global $test = 0, $printerList, $comboData, $paramPrinter, $paramDriver, $paramPort, $matchedDesignation = "", $messageDefault = "En attente..."
; GUI vars
Global $Refprinter, $menuConfig, $menuAbout, $menusubNotepad, $inputRef, $buttonPrint, $labelRef, $comboTotal, $labelTotal, $comboPrinters, $labelImprimantes, $statusHolder, $statusMessage
; BDD vars
Global $MysqlConn, $connected

$Refprinter = GUICreate("R.I.Printer", 301, 341, 482, 367)
GUISetState()
$menuConfig = GUICtrlCreateMenu("Configurer")
$menusubNotepad = GUICtrlCreateMenuItem("Configurer Notepad...", $menuConfig)
$menuAbout = GUICtrlCreateMenu("&A propos")
$inputRef = GUICtrlCreateInput("", 10, 123, 280, 21)
$buttonPrint = GUICtrlCreateButton("Imprimer", 106, 270, 89, 25)
$labelRef = GUICtrlCreateLabel("Référence", 123, 100, 54, 17)
$comboTotal = GUICtrlCreateCombo("1", 10, 176, 280, 25, BitOR($CBS_DROPDOWN,$CBS_AUTOHSCROLL))
GUICtrlSetData($comboTotal, "2|3|4|5|6|7|8|9|10")
$labelTotal = GUICtrlCreateLabel("Nombre d'étiquettes", 101, 154, 98, 17)
$comboPrinters = GUICtrlCreateCombo("", 10, 230, 280, 25, BitOR($CBS_DROPDOWN,$CBS_AUTOHSCROLL))
$labelImprimantes = GUICtrlCreateLabel("Imprimante", 123, 209, 55, 17)
$statusHolder = GUICtrlCreateGroup("Statut", 10, 8, 280, 73)
$statusMessage = GUICtrlCreateLabel("", 16, 24, 264, 52)
GUICtrlCreateGroup("", -99, -99, 1, 1)
GUISetState(@SW_SHOW)

#cs
#
# Event listeners
#
#ce
GUISetOnEvent($GUI_EVENT_CLOSE, "close")
;GUISetOnEvent($GUI_EVENT_RESTORE, "checkOnFocus")
;GUISetOnEvent($GUI_EVENT_MAXIMIZE, "checkOnFocus")
;GUISetOnEvent($GUI_EVENT_RESIZED, "checkOnFocus")
GUICtrlSetOnEvent($buttonPrint, "startprint")
GUICtrlSetOnEvent($comboPrinters, "chooseprinter")
GUICtrlSetOnEvent($menusubNotepad, "setupNotepad")
GUICtrlSetOnEvent($menuAbout, "about")
HotKeySet("{ENTER}", "query")
GUIRegisterMsg(0x0007, "OnFocus")

#cs
#
# Init programme
#
#ce
status("Recherche de l'imprimante UBI EasyCoder...")
$printerList = _GetLocalPrinterList()
Local $total = UBound($printerList)
if $total > 0 Then
    for $w = 0 to $total - 1
        If $comboData <> "" Then $comboData &= "|"
        $comboData &= $printerList[$w][0]
    Next
    GUICtrlSetData($comboPrinters, "")
    GUICtrlSetData($comboPrinters, $comboData)
    _GUICtrlComboBox_SetCurSel($comboPrinters, _GUICtrlComboBox_GetTopIndex($comboPrinters)) ; Sélection de la 1ère imprimante
    chooseprinter() ; Affectation de l'imprimante
EndIf

status("Initialisation des paramètres généraux...")
_GUICtrlComboBox_SetCurSel($comboTotal, _GUICtrlComboBox_FindStringExact($comboTotal, "3"))

; Connexion mySql
status("Connexion à la base de données...")
_MySQL_InitLibrary()
If @error Then Exit MsgBox(0, '', "Connexion MySql échouée")
    $MysqlConn = _MySQL_Init()
$connected = _MySQL_Real_Connect($MysqlConn, "localhost", "root", "", "restinpeace")
If $connected = 0 Then Exit MsgBox(16, 'Erreur de connexion', _MySQL_Error($MysqlConn))

; Paramètres .ini
getParams()

status()

;checkOnFocus()

#cs
#
# Boucle event
#
#ce
While 1
    if WinActive($Refprinter) Then $test = 0
    Sleep(1000)
WEnd

Func OnFocus($hWnd, $Msg, $wParam, $lParam)
     If $test = 0 Then
        msgbox(0,"","ok" & $hWnd & @CRLF & $Msg  & @CRLF & $wParam & @CRLF & $lParam)
        $test = 1
        redrawWin($Refprinter, "", "", BitOR($RDW_INVALIDATE, $RDW_UPDATENOW))
    EndIf
    Return $GUI_RUNDEFMSG
EndFunc

Func redrawWin($hWnd, $tRect = 0, $hRegion = 0, $iFlags = 5)
    Local $pRect = 0
    If $tRect <> 0 Then $pRect = DllStructGetPtr($tRect)
    Local $aResult = DllCall("user32.dll", "bool", "RedrawWindow", "hwnd", $hWnd, "ptr", $pRect, "handle", $hRegion, "uint", $iFlags)
    If @error Then Return SetError(@error, @extended, False)
    Return $aResult[0]
EndFunc

; Callback lors de la prise de focus : Vérif du presse-papier
Func checkOnFocus()
    Local $clipBoard

    MsgBox(0, "", "checkOnFocus")
    $clipBoard = ClipGet()
    if StringRegExp($clipBoard, "^I?\d{2,4}\-\w{4,6}\-?[a-zA-Z0-9#]*$", 0) = 1 Then
        GUICtrlSetState($inputRef, $GUI_FOCUS)
        _GUICtrlEdit_SetText($inputRef, $clipBoard)
        query()
    EndIf
EndFunc

; Effectue les requêtes mySql
Func query()
    Local $query, $result, $count, $asRow

    $matchedDesignation = ""
    $query = "SELECT BA_description FROM rip_base WHERE BA_iris='" & _MySQL_Real_Escape_String($MysqlConn,GUICtrlRead($inputRef)) & "'"
    If _MySQL_Real_Query($MysqlConn, $query) = $MYSQL_ERROR Then
        MsgBox(0, 'Error', _MySQL_Error($MysqlConn))
    Else
        $result = _MySQL_Store_Result($MysqlConn)
        $count = _MySQL_Num_Rows($result)
        if $count = 1 Then
            $asRow = _MySQL_Fetch_Row_StringArray($result, $count)
            If @error Then Exit
            $matchedDesignation = $asRow[0]
        EndIf
        status("Réference trouvée :" & @CRLF & $matchedDesignation)
        _MySQL_Free_Result($result)
    EndIf
EndFunc

; Sélection de l'imprimante appropriée
Func chooseprinter()
    Local $printer = GUICtrlRead($comboPrinters)
    Local $total = UBound($printerList)
    if $total > 0 Then
        for $w = 0 to $total - 1
            if $printerList[$w][0] = $printer Then
                $paramPrinter = $printerList[$w][0]
                $paramDriver = $printerList[$w][1]
                $paramPort = $printerList[$w][2]
                ExitLoop
            EndIf
        Next
    EndIf
EndFunc

; Lancement d'une impression
Func startprint()
    Local $fileName, $file

    $fileName = "print.txt"
    If GUICtrlRead($inputRef) = "" Then
        MsgBox(0, "Error", "Veuillez renseigner le champ référence")
        Return
    EndIf
    $file = FileOpen($fileName, 2)
    If $file = -1 Then
        MsgBox(0, "Error", "impossible d'ouvrir le fichier " & $fileName)
        Return
    EndIf
    FileWriteLine($file, GUICtrlRead($inputRef) & @CRLF & $matchedDesignation)
    FileClose($file)
    Local $count = GUICtrlRead($comboTotal)
    for $w = 1 to $count
        Run(@SystemDir & '\notepad.exe /PT "' & $fileName & '" "' & $paramPrinter & '" "' & $paramDriver & '" "' & $paramPort & '"' ,'' ,@SW_HIDE)
    Next
EndFunc

; Return local printer list : filtrage sur le nom d'imprimante sur "UBI"
; column 1 = Printer Name
; column 2 = Driver
; column 3 = Port
Func _GetLocalPrinterList()
    Local $PrinterList[1][3], $PrinterCount
    Local $objWMIService = ObjGet("winmgmts:\\" & @ComputerName & "\root\CIMV2")
    Local $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_Printer WHERE DeviceID LIKE '%UBI%'")

    For $objItem In $colItems
        ReDim $PrinterList[$PrinterCount + 1][3]
        $PrinterList[$PrinterCount][0] = $objItem.DeviceID
        $PrinterList[$PrinterCount][1] = $objItem.DriverName
        $PrinterList[$PrinterCount][2] = $objItem.PortName
        $PrinterCount += 1
    Next
    Return $PrinterList
EndFunc

; Export du fichier de configuration .ini
Func saveParams()
    IniWrite($iniFile, "global", "count", GUICtrlRead($comboTotal))
    if @error Then
        status("Sauvegarde du fichier INI échouée ( count )")
    EndIf
    IniWrite($iniFile, "global", "printer", $paramPrinter)
    if @error Then
        status("Sauvegarde du fichier INI échouée ( printer )")
    EndIf
EndFunc

; Import du fichier de configuration .ini
Func getParams()
    Local $read

    $read = IniReadSection($iniFile, "global")
    if FileExists($read) = False Then Return ; Si le fichier n'a pas été créé = sortie
    if @error Then
        MsgBox(0, "Erreur", "Lecture du fichier .ini échouée")
        Return
    EndIf
    if UBound($read) = 0 Or $read[0][0] = 0 Then Return
    for $x = 1 to $read[0][0]
        Switch $read[$x][0]
            Case "count"
                ControlCommand("", "", $comboTotal, "SelectString", $read[$x][1])
            Case "printer"
                _GUICtrlComboBox_SetCurSel($comboPrinters, _GUICtrlComboBox_FindStringExact($comboPrinters, $read[$x][1]))
        EndSwitch
    Next
EndFunc

; Configure "Notepad" : Mise en page d'impression et police
Func setupNotepad()
    status("Configuration de Notepad...")
    Run("notepad.exe")
    WinWaitActive("[CLASS:Notepad]","",2)
    Send("!f")
    Sleep(500)
    Send("m")
    Sleep(500)
    Send("!e")
    Sleep(500)
    Send("{BS}")
    Sleep(500)
    Send("!p")
    Sleep(500)
    Send("{BS}")
    Sleep(500)
    Send("+{ENTER}")
    WinWaitActive("[CLASS:Notepad]","",2)
    Send("!o")
    Sleep(500)
    Send("p")
    Sleep(500)
    Send("!l")
    Sleep(500)
    Send("9")
    Sleep(500)
    Send("+{ENTER}")
    WinWaitActive("[CLASS:Notepad]","",2)
    Send("!{F4}")
    status("Configuration de Notepad terminée" & @CRLF & $messageDefault)
EndFunc

; Affichage des messages
Func status($mess = "")
    if $mess = "" Then
        $mess = $messageDefault
    EndIf
    ControlSetText("", "", $statusMessage, $mess)
EndFunc

; Infos soft
Func about()
    MsgBox(0, "R.I.Printer - A propos", "R.I.Printer v" & $version & @CRLF & $copyright & @CRLF & $mail)
EndFunc

; Fermeture du programme
Func close()
    saveParams()
    Exit
EndFunc
 
Je précise que la fonction que je souhaite appeler lors du "focus" est "checkOnFocus", elle n'est plus utilisée dans le code ci-dessus le temps d'arriver à un résultat cohérent.

En tout cas merci pour votre aide les gars, ça avance !

Edit :
J'avance encore un peu, ça fonctionne lorsque je n'affiche aucun contrôle dans le gui, à partir du moment ou il y a un bouton, un champs ou autre ça ne fonctionne plus... :?
Modifié en dernier par tyler911 le jeu. 02 févr. 2012 13:24, modifié 1 fois.
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [..] Focus sur la fenêtre principale

#7

Message par mikell »

La fonction _WinAPI_RedrawWindow fait partie de l'include WinApi.au3, donc si tu as cet include dans le script tu peux utiliser la fctn sans la redéclarer
Aussi, la msgbox que j'avais utilisée n'était là qu'à titre d'exemple, mais comme c'est une fctn bloquante vaut mieux la virer (voir le warning dans l'aide pour GUIRegisterMsg )
ça serait aussi une bonne idée de virer le Sleep(1000) bloqueur de script dans le While, pour économiser les ressources il suffit de mettre

Code : Tout sélectionner

If WinActive($gui) AND $test = 1 Then $test = 0
Modifié en dernier par mikell le jeu. 02 févr. 2012 13:26, modifié 1 fois.
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
tyler911
Niveau 1
Niveau 1
Messages : 7
Enregistré le : mer. 01 févr. 2012 13:11
Status : Hors ligne

Re: [..] Focus sur la fenêtre principale

#8

Message par tyler911 »

j'ai corrigé ce problème effectivement ( j'ai été un peu lent sur ce coup ), j'ai mis un edit à l'instant je ne sais pas si tu l'as vu :
J'avance encore un peu, ça fonctionne lorsque je n'affiche aucun contrôle dans le gui, à partir du moment ou il y a un bouton, un champs ou autre ça ne fonctionne plus...
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [..] Focus sur la fenêtre principale

#9

Message par mikell »

Ah hum hum oui les controles... :mrgreen:
Là vaut mieux changer de message Windows (et inverser qques variables dans le script)
► Afficher le texte
Tu devrais mettre des balises "spoiler" sur tes codes précédents, la modération va râler :wink:
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
tyler911
Niveau 1
Niveau 1
Messages : 7
Enregistré le : mer. 01 févr. 2012 13:11
Status : Hors ligne

[..] Focus sur la fenêtre principale

#10

Message par tyler911 »

Yes super Mikell ça fonctionne ! Merci beaucoup je n'aurai pas trouvé sans aide. Je passe le post en résolu.
Répondre