#cs ---------------------------------------------------------------------------- AutoIt Version: 3.3.14.5 Author: myName Script Function: Template AutoIt script. #ce ---------------------------------------------------------------------------- #include #include #include #include #include #include #include #include #include ; Durée des notifications MsgBox Global $MsgBox_Time = 3 ; Fichier Excel Local $vExcelFile = @ScriptDir & "\Test.xlsx" ; Créer la fenêtre GUI (avec option pour redimensionner et la détection) Global $hGui = GUICreate("Nice Excel", 620, 60, -1, 0, $WS_OVERLAPPEDWINDOW) ; Création des boutons permettant d'interagir avec Excel Global $id_Btn_Set_Feuil_1 = GUICtrlCreateButton("Feuil 1", 15, 5, 45, 20) Global $id_Btn_Set_Feuil_2 = GUICtrlCreateButton("Feuil 2", 60, 5, 45, 20) Global $id_Btn_Set_D2 = GUICtrlCreateButton("D2 > 25%", 105, 5, 65, 20) Global $id_Btn_Set_Feuil_3 = GUICtrlCreateButton("Feuil 3", 170, 5, 45, 20) Global $id_Btn_Get_E16 = GUICtrlCreateButton("Get E16", 215, 5, 55, 20) Global $id_Btn_Print_Preview = GUICtrlCreateButton("Aperçu avant impression", 270, 5, 130, 20) Global $id_Btn_Print = GUICtrlCreateButton("Imprimer", 400, 5, 50, 20) Global $id_Btn_Save = GUICtrlCreateButton("Sauvegarder", 450, 5, 70, 20) Global $id_Btn_Close_Preview = GUICtrlCreateButton("Fermer l'aperçu", 520, 5, 80, 20) Global $id_Input_Zoom = GUICtrlCreateInput("", 15, 30, 45, 20, $ES_NUMBER), $Zoom_Actuel Global $id_UpDown_Zoom = GUICtrlCreateUpdown($id_Input_Zoom) Global $id_Btn_Undo = GUICtrlCreateButton("Annuler (Ctrl+Z)", 65, 30, 100, 20) Global $id_Btn_Redo = GUICtrlCreateButton("Rétablir (Ctrl+Y)", 170, 30, 100, 20) GUICtrlSetLimit( $id_UpDown_Zoom, 400, 10) GUICtrlSetBkColor( $id_Btn_Print_Preview, 0xFF9999) GUICtrlSetBkColor( $id_Btn_Close_Preview, 0xFF9999) GUICtrlSetBkColor( $id_Btn_Undo, 0xFF9999) GUICtrlSetBkColor( $id_Btn_Redo, 0xFF9999) If Not _Gestion_d_un_crash_Excel_precedent( $vExcelFile) Then Exit GUISetState() ; Boucle principale gérant les événements de l'interface While 1 Local $Msg = GUIGetMsg() Select Case $Msg = $id_Btn_Set_Feuil_1 $oExcelApp.Sheets(1).Select Case $Msg = $id_Btn_Set_Feuil_2 $oExcelApp.Sheets(2).Select Case $Msg = $id_Btn_Set_D2 $oExcelApp.Sheets(2).Select $oExcelApp.ActiveSheet.Range("D2").Value = "25%" Case $Msg = $id_Btn_Set_Feuil_3 $oExcelApp.Sheets(3).Select Case $Msg = $id_Btn_Get_E16 Local $value = $oExcelApp.ActiveSheet.Range("E16").Value MsgBox(0, "Valeur de E16", $value, $MsgBox_Time) Case $Msg = $id_Btn_Print_Preview $oExcelApp.Visible = True WinActivate($hExcelWnd) $oExcelApp.ActiveSheet.PrintPreview Case $Msg = $id_Btn_Print $oExcelApp.ActiveSheet.PrintOut Case $Msg = $id_Btn_Save $oWorkbook.Save MsgBox(0, "Sauvegarde", "Document Excel sauvegardé", $MsgBox_Time) Case $Msg = $id_Btn_Close_Preview ConsoleWrite("Aperçu avant impression fermé." & @CRLF) Case $Msg = $id_Input_Zoom ; Gestion d'entrées du Zoom Local $Zoom_Actuel = GUICtrlRead($id_Input_Zoom) ; Vérification sécurité limites zoom (10% - 400%) If $Zoom_Actuel >= 10 And $Zoom_Actuel <= 400 Then $oExcelApp.ActiveWindow.Zoom = $Zoom_Actuel Else MsgBox(48, "Erreur", "Valeur du zoom invalide (doit être entre 10 et 400).") ; Réinitialiser à la dernière valeur correcte GUICtrlSetData($id_Input_Zoom, $oExcelApp.ActiveWindow.Zoom) EndIf Case $Msg = $id_Btn_Undo ; Annuler (Ctrl+Z) via COM ConsoleWrite("Annuler (Ctrl+Z) indisponible." & @CRLF) Case $Msg = $id_Btn_Redo ; Rétablir (Ctrl+Y) via COM ConsoleWrite("Rétablir (Ctrl+Y) indisponible." & @CRLF) Case $Msg = $GUI_EVENT_CLOSE _Gestion_d_un_crash_Excel_precedent( "", True) ExitLoop EndSelect _DetectAndResize($hGui, $hExcelWnd) Sleep(50) WEnd ; Fonction détection de la GUI puis Excel avec repositionnement d'Excel si GUI change de position et de taille ( A tester sur plusieur moniuteurs) Func _DetectAndResize($hGui, $hExcelWnd) If Not IsDeclared("bWasInsideGUI") Then Global $bWasInsideGUI = False If Not IsDeclared("bExcelVisible") Then Global $bExcelVisible = False ; Détection de la position de la souris et des fenêtres Local $aMousePos = MouseGetPos() Local $aGuiPos = WinGetPos($hGui) Local $aWinPosExcel = WinGetPos($hExcelWnd) Local $tRECT = _WinAPI_GetWorkArea() Local $WorkArea_H = DllStructGetData($tRECT, 'Bottom') - DllStructGetData($tRECT, 'Top') Local $bIsInsideGUI = ($aMousePos[0] >= $aGuiPos[0] And $aMousePos[0] <= $aGuiPos[0] + $aGuiPos[2] And _ $aMousePos[1] >= $aGuiPos[1] And $aMousePos[1] <= $aGuiPos[1] + $aGuiPos[3]) Local $bIsInsideExcel = ($aMousePos[0] >= $aWinPosExcel[0] And $aMousePos[0] <= $aWinPosExcel[0] + $aWinPosExcel[2] And _ $aMousePos[1] >= $aWinPosExcel[1] And $aMousePos[1] <= $aWinPosExcel[1] + $aWinPosExcel[3]) ; Ajuster la visibilité d'Excel If $bIsInsideGUI Then $oExcelApp.Visible = True $bExcelVisible = True WinSetOnTop($hGui, "", 1) WinSetOnTop($hExcelWnd, "", 1) ElseIf Not $bIsInsideGUI And Not $bIsInsideExcel Then $oExcelApp.Visible = False $bExcelVisible = False WinSetOnTop($hGui, "", 0) WinSetOnTop($hExcelWnd, "", 0) EndIf ; Mettre à jour la position d'Excel sous la GUI si elle est déplacée Local $iExcelY = $aGuiPos[1] + $aGuiPos[3] WinMove($hExcelWnd, "", $aGuiPos[0], $iExcelY, $aGuiPos[2], $WorkArea_H - $iExcelY - 5) $bWasInsideGUI = $bIsInsideGUI EndFunc ; Si Excel crash, on le récupère si c'est possible Func _Gestion_d_un_crash_Excel_precedent( $v_Dir = "", $bFermer = False) ; Définition du fichier de configuration If Not IsDeclared("sCrashFile") Then Global $sCrashFile = @ScriptDir & "\config.ini" If $bFermer Then If IsObj($oExcelApp) Then ; Désactiver les alertes et animations Excel With $oExcelApp .Visible = False .DisplayAlerts = False .ScreenUpdating = False .EnableEvents = False .AskToUpdateLinks = False .AlertBeforeOverwriting = False .DisplayFullScreen = False EndWith If IsObj($oWorkbook) Then ; -- Débloquer l’éventuelle cellule en cours d’édition -- WinActivate($hExcelWnd) Send("{ENTER}") Sleep(100) ; Vérifier si le document a été modifié avant de l’enregistrer If Not $oWorkbook.Saved Then $oWorkbook.Save EndIf $oWorkbook.Close(False) EndIf ConsoleWrite("Tentative de fermeture d'Excel..." & @CRLF) ; Vérifier si Excel est bloqué par une boîte de dialogue If WinExists("[CLASS:#32770]") Then ConsoleWrite("Une boîte de dialogue Excel bloque la fermeture. Tentative de fermeture forcée..." & @CRLF) Send("{ESC}") ; Ferme une éventuelle boîte de dialogue Sleep(1000) EndIf ; Exécuter la fermeture avec gestion d’erreur If Execute("$oExcelApp.Quit") = 0 Then ConsoleWrite("Échec de la fermeture normale. Forçage de fermeture..." & @CRLF) ProcessClose("EXCEL.EXE") Else ConsoleWrite("Excel fermé avec succès." & @CRLF) EndIf EndIf ; Supprimer l'entrée du handle Excel dans config.ini IniDelete($sCrashFile, "Excel", "Handle") Return True Else ; Vérification d'un crash précédent en lisant le handle Local $sHandle = IniRead($sCrashFile, "Excel", "Handle", "") If $sHandle <> "" And $sHandle <> "0x00000000" And WinExists($sHandle) Then MsgBox(48, "Alerte", "Une instance Excel précédemment ouverte a été détectée. Restauration en cours...") Global $hExcelWnd = $sHandle WinSetState($hExcelWnd, "", @SW_SHOW) WinActivate($hExcelWnd) $oExcelApp.Visible = True $oExcelApp.DisplayFullScreen = True Return True Else ; Suppression de l'ancien handle si invalide IniDelete($sCrashFile, "Excel", "Handle") EndIf ; Création d'une nouvelle instance Excel Global $oExcelApp = ObjCreate("Excel.Application") If Not IsObj($oExcelApp) Then MsgBox(16, "Erreur", "Impossible de créer une instance Excel.") Return False EndIf ; Désactiver certaines alertes Excel dès la création With $oExcelApp .Visible = False .DisplayAlerts = False .ScreenUpdating = True .EnableEvents = False .AskToUpdateLinks = False .AlertBeforeOverwriting = False EndWith ; Attendre qu'Excel soit complètement chargé avant de récupérer le handle Sleep(500) ; Vérification du fichier temporaire de crash (~$Test.xlsx) Local $sDrive = "", $sDir = "", $sFileName = "", $sExtension = "" Local $aPathSplit = _PathSplit( $v_Dir, $sDrive, $sDir, $sFileName, $sExtension) Local $v_Dir_Tmp = $aPathSplit[1]&$aPathSplit[2] & "~$" &$aPathSplit[3]&$aPathSplit[4] If FileExists($v_Dir_Tmp) Then ; On récupère la taille du fichier temporaire Local $iSize_Tmp = FileGetSize($v_Dir_Tmp) ; On suppose qu'en-dessous de 1 Ko, c'est juste un fichier lock If $iSize_Tmp > 1024 Then MsgBox(48, "Alerte", "Excel a détecté un crash. Tentative de récupération du fichier temporaire.") Global $oWorkbook = $oExcelApp.Workbooks.Open($v_Dir_Tmp) Else MsgBox(48, "Alerte", _ "~$Test.xlsx semble trop petit pour être un vrai fichier de récupération. " & _ "On l'ignore et on ouvre Test.xlsx.") FileDelete($v_Dir_Tmp) Global $oWorkbook = $oExcelApp.Workbooks.Open($v_Dir) EndIf Else ; (Code original conservé) Global $oWorkbook = $oExcelApp.Workbooks.Open($v_Dir) EndIf ; Récupération et stockage du handle Excel Global $hExcelWnd = WinGetHandle("[CLASS:XLMAIN]") WinSetTrans( $hExcelWnd, "", 240) ; Rend la barre invisible, un nombre compris entre 0 et 255 Local $iStyle = _WinAPI_GetWindowLong($hExcelWnd, $GWL_STYLE) _WinAPI_SetWindowLong($hExcelWnd, $GWL_STYLE, BitAND($iStyle, BitNOT(0x00C00000))) WinSetState($hExcelWnd, "", "") ; Forcer la mise à jour If $hExcelWnd = 0x00000000 Or $hExcelWnd = "" Then MsgBox(16, "Erreur", "Impossible d'obtenir le handle de la fenêtre Excel.") Return False EndIf IniWrite($sCrashFile, "Excel", "Handle", $hExcelWnd) Sleep(100) ; Forcer l'affichage d'Excel $oExcelApp.Visible = True $oExcelApp.DisplayFullScreen = True ; On place la GUI et Excel au-dessus de toutes les autres fenêtres WinSetOnTop($hGui, "", 1) WinSetOnTop($hExcelWnd, "", 1) Local $Zoom_Actuel = $oExcelApp.ActiveWindow.Zoom GUICtrlSetData($id_Input_Zoom, $Zoom_Actuel) If Not WinActive($hExcelWnd) Then WinActivate($hExcelWnd) Return True EndIf EndFunc