/* REMAPPING TOUCHES POUR ACTIVEGS + Extras (script AutoHotkey) v0.92 (13.01.2013) Auteur : Arnaud C. (pour WWW.CTRL-POMME-RESET.FR) Testé avec : AUTOHOTKEY v1.1.09.02 WINDOWS XP SP3 Clavier AZERTY Logitech G11 ActiveGS v3.5.903 beta notes (codes AutoHotkey): + : SHIFT ^ : CTRL ! : ALT <^>! : ALTR Gr # : Win SC : Scan Code VK : Virtual Key Fonctionnalités du script : =========================== - remapping des touches clavier AZERTY avec ActiveGS (plugin et standalone Windows) et GSPort. - support du multi-sessions d'ActiveGS standalone Windows pour les fonctionnalités suivantes : - ouverture automatique au lancement de la fenêtre des Options d'ActiveGS standalone (version Windows). - mode "magnétique" pour la fenêtre des Options (ActiveGS standalone Windows). - déplacement de la fenêtre des Option autour de la fenêtre principale par CTRL+HOME (ActiveGS standalone Windows). - suppression ponctuelle par CTRL+END du logo d'accès disque lorsque ActiveGS standalone Windows est en pause (cela permet la prise de screenshot sans élement disgracieux). - ajout lors de la mise en pause d'ActiveGS standalone Windows d'un message dans la barre de titre de la fenêtre en question pour signaler l'état. Hotkeys ajoutées : ================== - touche "Right Windows" (clavier PC) qui peut faire office de ALT Gr (si problème pour obtenir certains caractères sous GS/OS et CDA). - CTRL+SHIFT+ESC = fermeture du script. - F12 = fonction COLLER clipboard vers ActiveGS (pendant le processus, ESC permet de le terminer et ESPACE le met en pause). - Insert = ouverture de GS/BUG (si installé). Problèmes et/ou limitations connus : ==================================== - exécution d'un seul processus de COLLER à la fois même en cas de multi-sessions d'ActiveGS. - lors du processus de COLLER, changer de fenêtre et revenir sur la fenêtre ActiveGS entraîne la perte d'un (ou deux) caractère(s). solution : => utiliser la fonction PAUSE avant de changer de fenêtre. Historique : ============ - 0.92 : fonction COLLER : a) ajout d'une fonction PAUSE (Espace) pendant le processus avec ouverture d'une MsgBox. b) plus de tempo pour les textes courts (<257 car.) - 0.91 : amélioration de la fonction COLLER. - 0.90 (*) : première version avec gestion du "coller VERS ActiveGS" depuis le presse-papier (texte). - 0.80 : première version avec gestion multi-sessions d'ActiveGS. - 0.56 : HotKey (INS) pour activer GS/BUG facilement enfin totalement opérationnelle ! - 0.55 : RightWin = touche alternative à ALT Gr (qui pose des problèmes de reconnaissance sous GS/OS et avec certains CDA). - 0.54 (*) : HotKey "Insert" pour activer facilement GS/BUG (beta). - 0.53 : prise en compte de la modification "underscore" (voir www.ctrl-pomme-reset.fr) de ActiveGS standalone PC. - 0.52 (*) : ajout Hotkey (F7) pour activer facilement GS/BUG (alpha) -> touche INS à partir de 0.54+. - 0.51 (*) : corrections bugs divers. - 0.50 : ajout Hotkey pour cacher/afficher le symbole d'accès disque quand l'émulateur est en pause par F5. : ajout texte (paused) dans la barre de titre pour la version standalone d'ActiveGS si l'émulateur en pause par F5. - 0.49 (*) : amélioration de l'ouverture automatique de la fenêtre options. - 0.48 : ajout du remapping avec le plugin IE et Firefox pour les sites FTA et Virtual Apple uniquement. - 0.47 (*) : fenêtre options "magnétique" déplaçable par ctrl+Tab (version standalone ActiveGS uniquement) -> CTRL+HOME à partir de 0.5x. - 0.46 (*) : fenêtre options type "magnétique" + Plugin Chrome correctement remappé (sans interférences avec les autres onglets). - 0.45 (*) : amélioration du déplacement de la fenêtre options après ouverture + correction de petits bugs. - 0.44 (*) : ajout (alpha) du support d'ActiveGS version Plugin (Chrome/IE/Firefox) et de GSport. - 0.43 : limitation de l'utilisation du Numpad. - 0.42 : première version "stable" diffusée. - 0.xx (*) : versions alpha de développement. (*) : version de travail, non released */ ; =========================================================================== ; PART 0 : déclaration variables et paramètres pour le script #SingleInstance force ; une seule version de ce script active en même temps #Persistent ; maintient le script running TitlePause = (** paused **) ; apparence titre fenêtre si en pause par F5 SetTitleMatchMode 1 ; mode de détection du texte des fenêtres GroupAdd, ActiveGS_Group, ActiveGS ahk_class AfxFrameOrView90s ; ajout de ActiveGS Standalone Windows GroupAdd, ActiveGS_Group, %TitlePause% ahk_class AfxFrameOrView90s ; + version "paused" GroupAdd, ActiveGS_Group, ahk_class gsport ; ajout de GSport (v0.2a) GroupAdd, ActiveGS_Group, ahk_class Chrome_WidgetWin_1, activegs ; ajout de ActiveGS Plugin Chrome (Chrome OK) ; pour IE et Firefox, ajout par "sites" GroupAdd, ActiveGS_Group, Apple`, 2GS`, GS`, Emulator ; ajout du site http://www.freetoolsassociation.com/ GroupAdd, ActiveGS_Group, Virtual Apple ; ajout du site http://www.virtualapple.org/ ; GroupAdd, Standalone_Group, ActiveGS ahk_class AfxFrameOrView90s ; ajout version standalone + paused only GroupAdd, Standalone_Group, %TitlePause% ahk_class AfxFrameOrView90s ; pour déplacement options + show/hide voyant nbWindows =0 ; aucune fenêtre pour le moment counterWindows =1 ; ; PART I : OUVERTURE + DEPLACEMENT FENETRE OPTIONS d'ACTIVEGS SetTimer, CheckActiveGS, 100 ; set timer 100ms return CheckActiveGS: WinGet, winarray, list, ahk_group Standalone_Group ; // on récupère le nombre de fenêtres d'ActiveGS ouvertes if (winarray = 0) ; remise à zero si plus de fenêtre { nbWindows := 0 counterWindows :=1 return } else if (winarray > nbWindows) ; si nouvelle fenêtre ActiveGS détectée { OpenDialogBox() ; on ouvre la boite de dialogue return } else if (winarray < nbWindows) { nbWindows := winarray } GetKeyState, state, LBUTTON if state = D { tempID := WinExist("A") tempInd := GetIndex(tempID) if (tempInd <> 0) { WinGetPos, X_ActiveGS,Y_ActiveGS,Width_ActiveGS,Height_ActiveGS, ahk_id %tempID% if (X_ActiveGS !=X_Old%tempInd% || Y_ActiveGS !=Y_Old%tempInd% || Height_ActiveGS !=H_Old%tempInd% || Width_ActiveGS != W_Old%tempInd%) { MoveDialogBox(tempInd) } } } return ; ========================================================================================================== OpenDialogBox() { global local xclick, yclick, tempid, temppid WinActivate, ahk_group Standalone_Group ; on active la fenêtre principale ActiveGS varid%counterWindows% := WinExist("A") ; on récupère l'ID de la fenêtre active tempid :=varid%counterWindows% Winget, varpid%counterWindows%, PID, ahk_id %tempid% ; on récupère le Process ID de la fenêtre courante temppid := varpid%counterWindows% WinGetPos, X_Old%counterWindows%,Y_Old%counterWindows%,W_Old%counterWindows%,H_Old%counterWindows%, ahk_id %tempid% ; on détecte la première position WinGetTitle, ActiveText%counterWindows%, ahk_id %tempid% ; on en profite pour récupérer le titre de la fenêtre WinActivate, ahk_id %tempid% ; on active la fenêtre principale xclick :=W_Old%counterWindows%/2 yclick :=H_Old%counterWindows%/2 Click right %xclick%,%yclick% ; on simule clic droit WinActivate, ahk_id %tempid% ; on réactive la fenêtre principale Pos_options%counterWindows% := 1 ; position 1 par défaut bHide%counterWindows% :=0 ; icon disk non caché par défaut bPaused%counterWindows% :=0 ; non en pause par défaut IfWinNotExist, ahk_pid %temppid% ahk_class #32770 ; est-ce que la boite de dialogue option est déjà ouverte ? { ; si non : return } nbWindows := winarray ; on récupère le nb d'ActiveGS ouvert MoveDialogBox(counterWindows) ; on déplace la dialogBox counterWindows := ++counterWindows ; on incrémente le nb d'ActiveGS max pour l'éventuel prochaine session return } MoveDialogBox(countWindows) { global local temppid, w_options, h_options,X, Y temppid :=varpid%countWindows% WinGetPos, X_Old%countWindows%,Y_Old%countWindows%,W_Old%countWindows%,H_Old%countWindows%, ahk_pid %temppid% ahk_class AfxFrameOrView90s WinGetPos,,,w_options,h_options, ahk_pid %temppid% ahk_class #32770 ; récupère dimension boite dialogue if (Pos_options%countWindows% =0) { X := X_Old%countWindows% + W_Old%countWindows% -1 Y := Y_Old%countWindows% + (H_Old%countWindows%-h_options)/2 } else if (Pos_options%countWindows% =1) { X := X_Old%countWindows% + (W_Old%countWindows%-w_options)/2 Y := Y_Old%countWindows% + H_Old%countWindows% -1 } else if (Pos_options%countWindows% =2) { X := X_Old%countWindows% - w_options + 1 Y := Y_Old%countWindows% + (H_Old%countWindows%-h_options)/2 } else if (Pos_options%countWindows% =3) { X := X_Old%countWindows% + (W_Old%countWindows%-w_options)/2 Y := Y_Old%countWindows% - h_options + 2 } WinMove, ahk_pid %temppid% ahk_class #32770,, X,Y ; on déplace la fenêtre en X,Y return } GetIndex(tempid) { global Loop, %counterWindows% { if (varid%A_Index% = tempid) { return A_Index } } return 0 } ; ========================================================================================================== ; PART II : Hotkeys du Script ^+Esc:: ExitApp ; CTRL+SHIFT+ESC = fin du script return ^Home:: ; CTRL+HOME = déplacement fenêtre options "magnétique" autour de la fenêtre d'ActiveGS temp1 := WinExist("A") ; on récupère l'ID de la fenêtre active temp2 := GetIndex(temp1) ; on calcule l'index associé ; calcul nouvelle position boite de dialogue Pos_options%temp2% := ++Pos_options%temp2% ; sens aiguilles d'une montre... if Pos_options%temp2% = 4 Pos_options%temp2% =0 MoveDialogBox(temp2) ; et déplacement/affichage return ^End:: ; CTRL+END = cache/affiche le logo d'accès disque quand l'émulateur est en pause par F5 temp1 := WinExist("A") ; on récupère l'ID de la fenêtre active temp2 := GetIndex(temp1) ; on calcule l'index associé if (bHide%temp2% = 0) { Control, Hide,,#327702,ahk_id %temp1% bHide%temp2% = 1 } else { Control, Show,,#327702,ahk_id %temp1% bHide%temp2% = 0 } return /* Pause:: ; fonction pause alternative (désactivée par defaut) SendMessage, 0x1330, 1,, SysTabControl321, ahk_class #32770 ; ; active Onglet "Runtine Info" ControlClick, Button1,,Pause/Resume,LEFT ; clic bouton Pause/Resume return */ ; PART III : REMAPPING DES TOUCHES #IfWinActive ahk_group Standalone_Group ; pour ActiveGS standalone (en pause ou pas) actif uniquement ! ; ne pas modifier - ne concerne pas le mapping des touches ! F5:: ; interception touche F5 "Pause" pour fonction Hide/Show symbole accès disque + title fenêtre temp1 := WinExist("A") ; on récupère l'ID de la fenêtre active temp2 := GetIndex(temp1) ; on calcule l'index associé bHide%temp2% = 0 ; mode show par défaut if (bPaused%temp2% = 0) ; pas en pause { WinSetTitle, ahk_id %temp1% ahk_class AfxFrameOrView90s,, %TitlePause% bPaused%temp2% = 1 ; pause boléan } else ; si on est en pause { Affichetitle := ActiveText%temp2% WinSetTitle, ahk_id %temp1% ahk_class AfxFrameOrView90s,, %AfficheTitle% bPaused%temp2% = 0 } SendInput {F5} ; pause/resume return ; fin de non modification #IfWinActive ahk_group ActiveGS_Group ; pour ActiveGS (standalone et plugin) et GSport actif uniquement ! ; touches "haut du clavier" +&::SendInput & ; 1 &::SendInput +è ; & RWIN & é::SendInput +ù ; ~ (bis) <^>!é::SendInput +ù ; ~ +é::SendInput é ; 2 é::SendInput +) ; é RWIN & "::SendInput +{VK33} ; # (bis) <^>!"::SendInput +{VK33} ; # +"::SendInput {VK33} ; 3 "::SendInput +² ; " RWIN & '::SendInput +) ; { (bis) <^>!'::SendInput +) ; { +'::SendInput ' ; 4 '::SendInput ² ; ' RWIN & (::SendInput ) ; [ (bis) <^>!(::SendInput ) ; [ +(::SendInput ( ; 5 (::SendInput +ç ; ( RWIN & -::SendInput +µ ; | (bis) <^>!-::SendInput +µ ; | +-::SendInput - ; 6 -::SendInput {NumpadSub} ; - RWIN & è::SendInput {VKC0} ; ` (bis) <^>!è::SendInput {VKC0} ; ` +è::SendInput è ; 7 è::SendInput +¨ ; è RWin & _::SendInput * ; \ (bis) <^>!_::SendInput * ; \ +_::SendInput _ ; 8 (si modification "underscore") _::SendInput +_ ; _ (si modification "underscore") RWIN & ç::SendInput +- ; ^ (bis) <^>!ç::SendInput +- ; ^ +ç::SendInput ç ; 9 ç::SendInput * ; ç RWIN & à::SendInput +é ; @ (bis) <^>!à::SendInput +é ; @ +à::SendInput à ; 0 à::SendInput +é ; à RWIN & )::SendInput {VKDD} ; ] (bis) <^>!)::SendInput {VKDD} ; ] +)::SendInput ) ; ° )::SendInput +à ; ) RWIN & =::SendInput +¨ ; } (bis) <^>!=::SendInput +¨ ; } ; autres touches +<::SendInput +; ; > <::SendInput +? ; < +,::SendInput +: ; ? ; +VKDD::SendInput +- ; ¨ (tréma non géré ?) VKDD::SendInput +- ; ^ (accent circonflexe) +$::SendInput +" ; £ $::SendInput +' ; $ *::SendInput {NumpadMult} ; * +ù::SendInput +( ; % ù::SendInput +* ; ù +VKBE::SendInput {VKBE} ; . VKBE::SendInput $ ; ; +VKBF::SendInput {VKBF} ; / :::SendInput +$ ; : +!::SendInput {VKDD} ; § !::SendInput +& ; ! ; divers Ins:: ; GS/BUG CTRL+OPEN-APPLE+OPTION+ESC (CTRL+ALT+WIN+ESC sur PC) SendInput {LALT down}{LCTRL down}{LWIN down}{ESC down}{ESC up}{LWIN up}{LCTRL up}{LALT up} return ; =========================================================================================== F12:: ; PASTE CLIPBOARD vers ACTIVEGS ident := WinExist("A") ; on récupère l'ID de la fenêtre ActiveGS active index = 1 StringSplit, data, clipboard length := data0 ; longueur if (length>256) SetKeyDelay,35 ; délai d'attente (ms) ! while (index<=length) { ifWinActive,ahk_id %ident% { if (GetKeyState("Esc","P") = 1) break if (GetKeyState("space","P") = 1) { Send {space} ; astuce pour éviter le bug de l'espace "fou" Send {backspace} ; MsgBox, 52, L'opération COLLER est en pause,Voulez-vous poursuivre ? ifMsgBox, No ; si non on stoppe la boucle et on sort break ifMsgBox, Yes ; si oui on réactive la fenêtre ActiveGS et on continue le process { WinActivate, ahk_id %ident% } } if (data%index% = "1") { Send & } else if (data%index% = "2") { Send é } else if (data%index% = "3") { Send {VK33} } else if (data%index% = "4") { Send ' } else if (data%index% = "5") { Send ( } else if (data%index% = "6") { Send - } else if (data%index% = "7") { Send è } else if (data%index% = "8") { Send _ } else if (data%index% = "9") { Send ç } else if (data%index% = "0") { Send à } else if (data%index% = "(") { Send +ç } else if (data%index% = ")") { Send +à } else if (data%index% = "^") { Send +- } else if (data%index% = "-") { Send {NumpadSub} } else if (data%index% = "+") { Send {NumpadAdd} } else if (data%index% = "*") { Send {NumpadMult} } else if (data%index% = "/") { Send {VKBF} } else if (data%index% = ".") { Send {VKBE} } else if (data%index% = ";") { Send $ } else if (data%index% = "%") ; % { Send +( } else if (data%index% = ":") { Send +$ } else if (data%index% = "!") { Send +& } else if (data%index% = "$") { Send +' } else if (asc(data%index%) = 34) ; " { Send +² } else if (data%index% = "[") { Send ) } else if (data%index% = "]") { Send {VKDD} } else if (data%index% = "&") { Send +è } else if (data%index% = "?") { Send +: } else if (data%index% = ">") { Send +; } else if (data%index% = "<") { Send +? } else if (data%index% = "{") { Send +) } else if (data%index% = "}") { Send +¨ } else if (data%index% = "#") { Send +{VK33} } else if (data%index% = "'") { Send ² } else if (data%index% = "|") { Send +µ } else if (data%index% = "@") { Send +é } else if (data%index% = "é") { Send +) } else if (data%index% = "è") { Send +¨ } else if (data%index% = "ç") { Send * } else if (data%index% = "à") { Send +é } else if (data%index% = "ù") { Send +* } else if (data%index% = "°") { Send ) } else if (data%index% = "§") { Send {VKDD} } else if (data%index% = "£") { Send +" } else if (data%index% = "_") { Send +_ } else if (asc(data%index%) = 0x0D) { Send {return} } else if (asc(data%index%) = 0x0A) { ; on ne fait rien (shunte 0x0A) } else Send % data%index% ; % (ne pas tenir compte du commentaire !) index++ } } SetKeyDelay, -1 ; retour à la normale return