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