Code : Tout sélectionner
#cs ----------------------------------------------------------------------------
AutoIt Version: 3.3.14.5
Author: myName
Script Function:
Template AutoIt script.
#ce ----------------------------------------------------------------------------
#include <Array.au3>
#include <Excel.au3>
#include <File.au3>
#include <GuiConstants.au3>
#include <GUIConstantsEx.au3>
#include <TreeViewConstants.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <FileConstants.au3>
; 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