Pilotage d'une application externe (Ex: calculatrice MS)

Programmation d'applications complexes
PAPIPP
Messages : 534
Inscription : sam. 23/févr./2008 17:58

Pilotage d'une application externe (Ex: calculatrice MS)

Message par PAPIPP »

Bonjour à tous.

Pilotage d’une application externe. Exemple avec la calculatrice de Microsoft
Deux grandes méthodes.
La première consiste à simuler les touches de l’application
La deuxième consiste à envoyer des commandes connaissant le handle et Ctrl-id de la commande.
L’ inconvénient majeur de la première est de maintenir le focus de l’application externe au premier plan.
L’ inconvénient majeur de la deuxième est de connaitre les CTRL-ID de chaque commande.
Voici un exemple avec la deuxième méthode sans aucune simulation de touche.

Code : Tout sélectionner

EnableExplicit
;***************************** Modifier le chemin de la calculatrice que vous désirez utiliser ***********************************
Global NOM_EXE$="C:\WINDOWS\SYSTEM32\calc.exe"
; Global NOM_EXE$="E:\Program Files\Microsoft Calculatrice Plus\CalcPlus.exe" ;
;************************************************************************************************************************************
;{-Enumerations/DataSections
;{ Windows
Enumeration
  #Window_0
EndEnumeration
;}
;{ Gadgets
Enumeration
  #menu_1=1
  #menu_2
  #ComboBox_1
  #ListView_2
  #Button_3
  #CheckBox_1
  #TEXT_GAD1
  #TEXT_GAD2
  #ComboBox_7
  #ComboBox_8
  #Button_8
  #ListIcon_9
  #ListIcon_11
  #Help=79
EndEnumeration
;}
Define.l Event,EventWindow,EventGadget,EventType,EventMenu
;}
Global hMainWnd.l ; handle de la fenêtre parent de la calculatrice
Global NOM_WND$="" ; le nom de la fenêtre sera trouvé automatiquement à partir du prg
Global PID_CALC.l
Global Whnd_stat.l,FLAG_MOD_hWND.l=0
Global Nom_stat.s="Statistiques"
Global tempo=100
Global TEMP10=10
Global sbuffer.s=Space(256)
Declare PAUSE(tmp.l)
Define mhFoundWnd.l
; Define sBuffer.s
Define nLength.l
Dim t_vk.c(256)
;******************************************************************************************************
;********************************** DEBUT de recherche d'un module déjà en mémoire ********************
;******************************************************************************************************
Structure inf_wnd
  pid.l
  hwnd.l
  NOM_EXE.s{#MAX_PATH}
  nom_WND.s{#MAX_PATH}
  ind.w
EndStructure
NewMap info_wdn.inf_wnd()
Structure E_T_CM ; élément de la table Commande langage Microsoft
  E.s{1} ; permet de différencier Commande directe et langage Microsoft "M" pour Microsoft et "C" pour commande
  StructureUnion
    M.s{100}
    C.l
    M4.s{4}[24]
  EndStructureUnion
EndStructure
Structure CMD_ID_HELP
  L_PP.s{8}
  ID.s{4}
  BOUT.s{11}
  L_MS.s{8}
  INF.s{120}
EndStructure
Structure S_coll
  IND_s.s{8}
  ind.l
EndStructure
Dim T_CM.E_T_CM(100)
; Dim AIDE_h.s(50)
;****** CHARGEMENT DE LA MAP  ******
; ********* ATTENTION à partir du CTRL_ID=306 il y a une différence de +1 sur les CTRL_ID de la CALCULETTE_PLUS
NewMap Instr.l()
Global NewMap CMD_H.CMD_ID_HELP()
Global NewMap CMD_S.S_coll()
; Global Dim tab_ban.s{11}(120)
Global Dim tab_ban.s(120)
;********************************************TRI COLONNE d'un gadget Listicongadget  ********************************************************
;********************************************TRI COLONNE d'un gadget Listicongadget********************************************************
Structure PB_ListIconItem
	UserData.l
EndStructure

#LVM_SETEXTENDEDLISTVIEWSTYLE=#LVM_FIRST+54
#LVM_GETEXTENDEDLISTVIEWSTYLE=#LVM_FIRST+55
Global ListIconGadget.l,Buffer1.l,Buffer2.l,lvi.LV_ITEM,updown.l,lastcol.l
Buffer1=AllocateMemory(128)
Buffer2=AllocateMemory(128)

Procedure CompareFunc(*item1.PB_ListIconItem,*item2.PB_ListIconItem,lParamSort)
  Protected result,Seeker1,Seeker2,done,char1,char2
	result=0
	lvi\iSubItem=lParamSort
	lvi\pszText=Buffer1
	lvi\cchTextMax=512
	lvi\Mask=#LVIF_TEXT
	SendMessage_(ListIconGadget,#LVM_GETITEMTEXT,*item1\UserData,@lvi)
	lvi\pszText=Buffer2
	SendMessage_(ListIconGadget,#LVM_GETITEMTEXT,*item2\UserData,@lvi)
	Seeker1=Buffer1
	Seeker2=Buffer2
	done=0
	While done=0
		char1=Asc(UCase(Chr(PeekB(Seeker1))))
		char2=Asc(UCase(Chr(PeekB(Seeker2))))
		result=(char1-char2)*updown
		If result<>0 Or (Seeker1-Buffer1)>511
			done=1
		EndIf
		Seeker1+1
		Seeker2+1
	Wend
	ProcedureReturn result
EndProcedure

Procedure UpdatelParam()
	Protected i.l,lTmp.l,lRecs.l,lvi.LV_ITEM
	lRecs=SendMessage_(ListIconGadget,#LVM_GETITEMCOUNT,0,0)
	For i=0 To lRecs-1
		SetGadgetItemData(GetDlgCtrlID_(ListIconGadget),i,i)
	Next
EndProcedure

Procedure ColumnClickCallback(hwnd,uMsg,wParam,lParam)
  Protected result,*msg.NMHDR,*pnmv.NM_LISTVIEW,WindowWidth,WindowHeight
	result=#PB_ProcessPureBasicEvents
	Select uMsg
		Case #WM_NOTIFY
			*msg.NMHDR=lParam
			If *msg\hwndFrom=ListIconGadget And *msg\code=#LVN_COLUMNCLICK
				*pnmv.NM_LISTVIEW=lParam
				If lastcol<>*pnmv\iSubItem
					updown=1
				EndIf
				SendMessage_(ListIconGadget,#LVM_SORTITEMS,*pnmv\iSubItem,@CompareFunc())
				UpdatelParam()
				UpdateWindow_(ListIconGadget)
				lastcol=*pnmv\iSubItem
				updown=-updown
			EndIf
		Case #WM_SIZE
			If hwnd=WindowID(0) And IsIconic_(hwnd)=0
				WindowWidth=lParam & $FFFF
				WindowHeight=lParam>>16
				ResizeGadget(0,0,0,WindowWidth,WindowHeight)
				result=1
			EndIf
	EndSelect
  
	ProcedureReturn result
EndProcedure
;********************************************  FIN TRI COLONNE d'un gadget Listicongadget ********************************************************
;********************************************  FIN TRI COLONNE d'un gadget Listicongadget ********************************************************

; ******************* debut  des Procedures de création d'une map avec les principales caractéristiques de chaque fenêtre ********************
; ******************* debut  des Procedures de création d'une map avec les principales caractéristiques de chaque fenêtre ********************

ProcedureDLL GET_PID_NOM_WND(Name.s) 
  Protected recherche,CreateToolhelpSnapshot,ProcessFirst,ProcessNext,Process.PROCESSENTRY32,Snapshot,ProcessFound,Nom.s,Pid
  Name.s=UCase(Name.s)
  Recherche=0
  If OpenLibrary(0,"Kernel32.dll")
    CreateToolhelpSnapshot=GetFunction(0,"CreateToolhelp32Snapshot")
    ProcessFirst=GetFunction(0,"Process32First")
    ProcessNext=GetFunction(0,"Process32Next")
    If CreateToolhelpSnapshot And ProcessFirst And ProcessNext ; Ensure than all the functions are found
      Process.PROCESSENTRY32\dwSize=SizeOf(PROCESSENTRY32)
      Snapshot=CallFunctionFast(CreateToolhelpSnapshot,#TH32CS_SNAPPROCESS,0)
      If Snapshot
        ProcessFound=CallFunctionFast(ProcessFirst,Snapshot,Process)
        While ProcessFound
          Nom.s=UCase(PeekS(@Process\szExeFile))
          Nom=GetFilePart(Nom)
          If Nom=Name
            Recherche=1
            Pid=Process\th32ProcessID
          EndIf
          ProcessFound=CallFunctionFast(ProcessNext,Snapshot,Process)
        Wend
      EndIf
      CloseHandle_(Snapshot)
    EndIf
    CloseLibrary(0)
  EndIf
  ProcedureReturn Pid
EndProcedure

ProcedureDLL KILL_PROCESS(Pid) ; Kill a process by specifying it's Pid
  Protected phandle,Result
  phandle=OpenProcess_(#PROCESS_TERMINATE,#False,Pid)
  If phandle<>#Null
    If TerminateProcess_(phandle,1)
      Result=#True
    EndIf
    CloseHandle_(phandle)
  EndIf
  ProcedureReturn Result
EndProcedure

Procedure.s GET_PID_NOM_EXE(hWnd.l)
  Protected pid.l,hProcess.l, Name.s,*F
  pid.l=0
  GetWindowThreadProcessId_(hWnd,@pid)
  hProcess.l=OpenProcess_(#PROCESS_ALL_ACCESS,0,pid);
  Name.s=Space(256)
  
  If OpenLibrary(0,"PSAPI.DLL")
    *F=GetFunction(0,"GetModuleFileNameExA")
    If *F
      CallFunctionFast(*F,hProcess,0,@Name,#MAX_PATH)
    Else
      MessageRequester("Erreur PSAPI.DLL","Fonction GetModuleFileNameExA non trouvé",0)
      CloseLibrary(0)
      End
    EndIf
  Else
    MessageRequester("Erreur PSAPI.DLL","Library non ouverte",0)
    End
  EndIf
  ProcedureReturn Str(pid)+"@"+Name
EndProcedure


Procedure FIND_COLLISION(PID.l,hWnd.l,NOM_exe_path.s,NOM_WND.s,Map INFO_W.inf_wnd(),TYP.s="T")
  Protected indi.l,indi$,type_c.s,NOM_EXE.s,indiM.l
  ;code pour la cle dans map afin d'éviter les collisions
  ; "H"+str(ind)+str(hwnd)
  ; "P"+str(ind)+str(pid)
  ; "E'+str(ind)+Nom_EXE
  ; "W"+str(ind)+NOm_Wnd
  ;*************** Pas de  collision sur handle c'est impossible qu'il puisse y avoir 2 handles  identiques donc info_w()\ind=1
  ;*************** Sur PID j'ai 1 PID double sur Purebasic !!!!
  ;*************** NOM_exe et NOM_WND peuvent être présent en plusieurs occurrences.
  Macro _CHERC_COLL(_typ,_types)
    indi=0
    Repeat
      indi+1
      indi$=_typ+Str(indi)+" "+_types     ; Blanc ou space sépare le type et son occurrence du nom de la clé. On peut placer ici un autre caractère alpha ou rien
      ;     res_find=FindMapElement(info_w(),indi$)
    Until FindMapElement(info_w(),indi$)=0
    info_w(indi$)\hwnd=hwnd
    info_w()\pid=PID
    info_w()\nom_WND=NOM_WND
    info_w()\NOM_EXE=NOM_EXE_PATH
    info_w()\ind=indi
    If indi>1
      indiM.l=indi
      indi=1
      indi$=_typ+Str(indi)+" "+_types  ; Blanc ou space sépare le type et son occurrence du nom de la clé. On peut placer ici un autre caractère alpha ou rien
      info_w(indi$)\ind=indiM
    EndIf
  EndMacro
  ;code pour la clé dans map afin d'éviter les collisions
  ; "H"+str(ind)+str(hwnd)
  ; "P"+str(ind)+str(pid)
  ; "E'+str(ind)+Nom_EXE
  ; "W"+str(ind)+NOm_Wnd
  ; "T" toutes les clés précédentes
  
  NOM_EXE.s=GetFilePart(NOM_EXE_PATH)
  
  If typ="E" Or typ="T":type_c="E":_CHERC_COLL(type_c,NOM_EXE) :EndIf
  If typ="P" Or typ="T":type_c="P":_CHERC_COLL(type_c,Str(PID)) :EndIf
  If typ="H" Or typ="T":type_c="H":_CHERC_COLL(type_c,Str(hWnd)) :EndIf
  If typ="W" Or typ="T":type_c="W":_CHERC_COLL(type_c,Nom_Wnd) :EndIf
  
EndProcedure

Procedure FIND_WINDOWS_INFOS(Map INFO_W.inf_wnd(),TYP.s="T")
  Protected NOM_WND.s,hwndp.l,PID_NOM_EXE_PATH.s,PID,NOM_EXE_PATH.s,nom_exe.s
  Static hWnd.l
  ClearMap(info_w())
  ;code pour la cle dans map afin d'éviter les collisions sur PID , NOM_EXE et NOM_WND
  ; "H"+str(ind)+str(hwnd)
  ; "P"+str(ind)+str(pid)
  ; "E'+str(ind)+Nom_EXE
  ; "W"+str(ind)+NOm_Wnd
  ; "T" toutes les clés précédentes
  hWnd=FindWindow_(0,0)
  While hWnd<>0
    If GetWindowLong_(hWnd,#GWL_STYLE) & #WS_VISIBLE=#WS_VISIBLE
      If GetWindowLong_(hWnd,#GWL_EXSTYLE) & #WS_EX_TOOLWINDOW<>#WS_EX_TOOLWINDOW
        NOM_WND.s=Space(#MAX_PATH)
        GetWindowText_(hWnd,@NOM_WND,#MAX_PATH)
        hwndp.l=GetParent_(hWnd)
        If NOM_WND<>""
          PID_NOM_EXE_PATH.s=GET_PID_NOM_EXE(hWnd)
          PID=Val(StringField(PID_NOM_EXE_PATH,1,"@"))
          NOM_EXE_PATH.s=StringField(PID_NOM_EXE_PATH,2,"@")
          nom_exe.s=GetFilePart(NOM_EXE_PATH)
          ;************** recherche de collision ***************************
          FIND_COLLISION(PID,hWnd,nom_exe_path,NOM_WND,INFO_W(),typ)
        EndIf
      EndIf
    EndIf
    hWnd=GetWindow_(hWnd,#GW_HWNDNEXT)
  Wend
EndProcedure
; ******************* Fin des Procedures de création d'une map avec les principales caractéristiques de chaque fenêtre ********************
;******************************************************************************************************
;********************************** FIN  de recherche d'un module déjà en mémoire ********************
;******************************************************************************************************

;***************************************************************************************************************************
;********************************** Chargement des commandes de base  et analyse des commandes envoyées ********************
;***************************************************************************************************************************
Procedure FIND_COLL_H(L_PP.S,ID.S,BOUT.s,L_MS.s,Map CMD_S.S_coll())
  Protected indi.l,indi$,type_c.s,NOM_EXE.s,type_a.s,REST.l,M_L_PP.s,CARa$,type_b.s
  Macro _CHER_COLL_H(_types)
    indi=0
    Repeat
      indi+1
      indi$=Str(indi)+" "+_types     ; Blanc ou space sépare le type et son occurrence du nom de la clé. On peut placer ici un autre caractère alpha ou rien
      REST.l=FindMapElement(CMD_S(),indi$)
      If rest<>0
        If cmd_s()\IND_s=L_PP
          M_L_PP.s=L_PP
        Else
          M_L_PP.s=""
        EndIf
      EndIf
    Until REST=0
    If M_L_PP<>L_PP
      CMD_S(indi$)\IND_s=L_PP
      CMD_S(indi$)\ind=indi
      If indi>1
        indi$="1 "+_types  ; Blanc ou space sépare son occurrence du nom de la clé. On peut placer ici un autre caractère alpha ou rien
        CMD_S(indi$)\ind=indi
      EndIf
    EndIf
  EndMacro
  
  type_a.s=L_PP:_CHER_COLL_H(type_a)
  CARa$=Left(L_PP,1)
  If CARa$<>UCase(cara$)
    If UCase(L_PP)<>L_PP
      _CHER_COLL_H(UCase(L_PP)) 
    Else
      _CHER_COLL_H(LCase(L_PP)) 
    EndIf
  EndIf 
  If cara$<>type_a
    _CHER_COLL_H(UCase(cara$))
    _CHER_COLL_H(LCase(cara$))
  EndIf

  If type_a<>ID:type_b.s=ID:_CHER_COLL_H(type_b)
    CARa$=Left(ID,1)
    If CARa$<>UCase(cara$)
      If UCase(ID)<>ID
        _CHER_COLL_H(UCase(ID)) 
      Else
        _CHER_COLL_H(LCase(ID)) 
      EndIf
    EndIf
  EndIf 
  If cara$<>ID:_CHER_COLL_H(cara$):EndIf

  If type_a<>type_b And type_a<>L_MS And type_b<>L_MS :type_c=L_MS:_CHER_COLL_H(type_c)
        CARa$=Left(L_MS,1)
    If CARa$<>UCase(cara$)
      If UCase(ID)<>L_MS
        _CHER_COLL_H(UCase(L_MS)) 
      Else
        _CHER_COLL_H(LCase(L_MS)) 
      EndIf
    EndIf
  :EndIf
  If cara$<>L_MS:_CHER_COLL_H(cara$):EndIf

EndProcedure

Procedure.l ANALYSE_CM(TXT$,Array PT_CM.E_T_CM(1), Map Instr.l()) 
  Protected el,Pos1,Text1$,ltxt1.l,ltxt.l,Pos2,txt1$,ii,txt2$,ltxt2,Ptxt.l,ctxt.l
  ; *** analyse de langage de typr MMMMM [ID\ID\ID,] MMMMMMM [ID\ID] MMMMM [ID].....avec MMM.. pour langage Microsoft et [ID] pour Commande CTRL_ID
  el=-1
  Repeat
    Pos1=FindString(TXT$,"[",1)
    If pos1<>0
      Text1$=Mid(TXT$,1,Pos1-1) ; text1$ est du langage microsoft
      TXT$=Mid(TXT$,Pos1+1)
      ltxt1.l=Len(text1$)
      ltxt.l=Len(txt$)
    Else
      text1$=txt$:txt$=""
      ltxt1=Len(text1$):ltxt=0
    EndIf
    If ltxt1<>0
      el+1
      PT_CM(el)\E="M":PT_CM(el)\M=TEXT1$
    EndIf
    ;*** Analyse entre [] commandes séparées par des \ (anti slash)
    If ltxt<>0
      Pos2=FindString(TXT$,"]",1)
      txt1$=Mid(TXT$,1,pos2-1)
      TXT$=Mid(TXT$,Pos2+1)
      ii=1
      Repeat
        txt2$=StringField(TXT1$,ii,"\"); txt2$ est une ou plusieurs commandes CTRL_ID séparées par des \ (anti slash)
        ltxt2=Len(txt2$)
        If ltxt2>0
          ;**************** recheche du code CTRL_ID dand la table MAP
          Ptxt.l=FindMapElement(instr(),txt2$)
          If ptxt<>0
            ctxt.l=PeekL(ptxt)
            If ctxt<>0
              el+1
              PT_CM(el)\E="C":PT_CM(el)\C=ctxt:PT_CM(el)\M4[2]=txt2$
            Else
              MessageRequester("Erreur sur la Commande :",txt2$+" de l'instructruction :"+TXT1$+" indice \ "+Str(ii))
            EndIf
          Else
            MessageRequester("Erreur sur la Commande :",txt2$+" de l'instructruction :"+TXT1$+" indice \ "+Str(ii))
          EndIf
        EndIf
        ii+1
      Until ltxt2=0
    EndIf
  Until ltxt=0
  ProcedureReturn el
EndProcedure
;***************************************************************************************************************************
;*************************** FIN de chargement des commandes de base  et analyse des commandes envoyées ********************
;***************************************************************************************************************************

;*********************************************************************************************************************************
;***************************************   Pilotage de la calculatrice Windows    ************************************************
;*********************************************************************************************************************************
Procedure.l GET_HWND_FROM_NOM_WND(name_wnd.s); Cherche le Handle de la fenêtre à partir du nom de la fenêtre
  Protected Np,hWnd
  Static hMainWndM,tempo.l=110,FLAG0=0
  Np=0
  While hWnd=0 And Np<200
    hWnd=FindWindow_(0,name_wnd) ; Cherche le Handle de la fenêtre à partir du nom de la fenêtre
    Delay(1)
    Np+1
  Wend
  hMainWnd=hWnd
  If hMainWnd<>hMainWndM And hMainWndM<>0
    ;     MessageRequester("ATTENTION","Handle modifié  New hWnd="+Str(hMainWnd)+" Préc hWnd="+Str(hMainWndM))
    ;     TextGadget(#TEXT_GAD2,168,40,500,15,"ATTENTION"+"  Handle modifié  New hWnd="+Str(hMainWnd)+" Préc hWnd="+Str(hMainWndM))
    ;     SetGadgetColor(#TEXT_GAD2, #PB_Gadget_FrontColor     , RGB(255,0,0))
    ;     TextGadget(#TEXT_GAD1,770,40,60,15,"calc cachée")
    SetGadgetColor(#TEXT_GAD1,#PB_Gadget_FrontColor,RGB(255,0,0))
    
  Else
    ;     TextGadget(#TEXT_GAD2,168,40,500,15,"")
    SetGadgetColor(#TEXT_GAD1,#PB_Gadget_FrontColor,RGB(0,0,0))
    
  EndIf
  hMainWndM=hMainWnd
  ProcedureReturn hwnd
EndProcedure

Procedure.l CHERCHE_STAT() ; Cherche le handle de la fenêtre statistique
  ;*************** Fenêtre des Statistiques ********************** n'est pas encore utilisé dans le PRG
  Protected Wnd_stat
  Static Whnd_stat,tempo.l=110
  ;   d_t.l=ElapsedMilliseconds()
  Delay(tempo*3)
  Wnd_stat=FindWindow_(0,"Statistiques") ; Cherche le Handle de la fenêtre
  PID_calc=GET_PID_NOM_WND(NOM_EXE$) ; On cherche le numéro PID qui lui est attribué au handle
  ; phandle = OpenProcess_ (#PROCESS_TERMINATE, #False, Pid) ; retrouve le handle à partir du PID
  
  ;   Delay(tempo*3)
  If Wnd_stat=0
    MessageRequester("ERREUR !","****************  Fenêtre Stat non trouvée")
    End
  EndIf
  ProcedureReturn whnd_stat
EndProcedure

Procedure PAUSE(tmp.l)
  hmainWnd=GET_HWND_FROM_NOM_WND(NOM_WND$)
  Delay(TMP)
EndProcedure

Procedure.s WM_COMMANDE(hMainWnd,Num,lparam=0)
  Protected R_WM_COMMANDE,sbuffer.s
  R_WM_COMMANDE=SendMessage_(hMainWnd,#WM_COMMAND,num,lparam)
  If num=300 
    sbuffer.s=Space(256)
    ProcedureReturn GetClipboardText()
  EndIf
EndProcedure

Procedure.s EXE_WHND(whnd.l,entree$)
  entree$=Trim(entree$)
  SetClipboardText(entree$)
  WM_COMMANDE(whnd,301);   touche_ctrl(#VK_V) coller
  sbuffer.s=WM_COMMANDE(whnd,300);     touche_ctrl(#VK_C) copier
  If entree$=sbuffer
    SendMessage_(whnd,#WM_COMMAND,81,0)
    ProcedureReturn " erreur instruction (div/0 ou mauvaise instruction)"
  EndIf
  ProcedureReturn GetClipboardText()
EndProcedure


;*********************************************************************************************************************************
;***************************************   FIN Pilotage de la calculatrice Windows    ************************************************
;*********************************************************************************************************************************


; *******************************************     Ouverture de la fenetre et des gadgets *********************************************
Procedure OpenWindow_Window_0()
  Protected textegad2$
  If OpenWindow(#Window_0, 452, 208, 836, 600, "Pilote calculatrice", #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MinimizeGadget | #PB_Window_TitleBar)
    ComboBoxGadget(#ComboBox_1, 5, 10, 755, 20, #PB_ComboBox_Editable)
    ListIconGadget(#ListView_2, 5, 160, 820, 435, "       Formules     ", 540, #PB_ListIcon_FullRowSelect)
;     ListIconGadget(#ListView_2, 5, 145, 820, 435, "       Formules     ", 540, #PB_ListIcon_FullRowSelect)
    ButtonGadget(#Button_3, 770, 10, 60, 20, "OK")
    CheckBoxGadget(#CheckBox_1, 740, 40, 15, 15, "")
    TextGadget(#TEXT_GAD1, 765, 40, 60, 15, "calc cachée")
    ComboBoxGadget(#ComboBox_7, 5, 40, 100, 20)
    ComboBoxGadget(#ComboBox_8, 110, 40, 115, 20, #PB_ComboBox_Editable)
    ButtonGadget(#Button_8, 235, 40, 60, 20, "Help")
    
    
    textegad2$="Chercher le type puis sur le choix de la Cmd enfin sur Help pour recherchez les infos"
     textegad2$+" Les commandes sont sensibles à la Case donc ATTENTION minuscule majuscule"
    TextGadget(#TEXT_GAD2, 320, 35, 405, 30, textegad2$)
    AddGadgetColumn(#ListView_2,1,"   Résultats   ",260)   
    
    
    If CreateMenu(0,WindowID(#Window_0))
      MenuTitle("Aide")
      MenuItem(1,"Aide MS")
;       MenuItem(2,"Aide PP")
;       MenuItem(3,"Aide Gen")
     
    EndIf
    AddKeyboardShortcut(#Window_0,#PB_Shortcut_F1,#Help)
    If LoadFont(1,"Courier New",8)
      SetGadgetFont(#ComboBox_1,FontID(1))
    EndIf
    AddGadgetItem(#ComboBox_7,-1,"Option[xx]")
    AddGadgetItem(#ComboBox_7,-1,"Langage MS")
    AddGadgetItem(#ComboBox_7,-1,"Boutons")
    SetGadgetState(#ComboBox_7, 2) ; Sélectionne le troisième  élément (la numérotation commence à 0)
    
    ListIconGadget=ListIconGadget(#ListIcon_11, 5, 65, 820, 90,"[Xxx]",50,#PB_ListIcon_GridLines | #PB_ListIcon_FullRowSelect)
    AddGadgetColumn(#ListIcon_11,1,"MS  ",50)
    AddGadgetColumn(#ListIcon_11,2,"Bouton",75)
    AddGadgetColumn(#ListIcon_11,3," ID ",30)
    AddGadgetColumn(#ListIcon_11,4," Aide  ",610)
    SetGadgetItemColor(#ListIcon_11, -1, #PB_Gadget_BackColor , RGB(255, 255, 0)) ; [, Colonne])
;      Si Etat = 0, le gadget est activé. Si Etat = 1, le gadget est désactivé 
    DisableGadget(#ListIcon_11, 1)
    HideGadget(#ListIcon_11, 1)

    ListIconGadget(#ListIcon_9, 5, 65, 820, 90, "Aide Générale", 800,   #PB_ListIcon_FullRowSelect)
    DisableGadget(#ListIcon_9, 0)
    HideGadget(#ListIcon_9, 0)

    

  EndIf
EndProcedure

Procedure charge_combo()
  Protected Option$,Choix_Comb8$,i,j
  AddGadgetItem(#ComboBox_1,-1," $ ********************  Langage de microsoft normal ************************  ")
  AddGadgetItem(#ComboBox_1,-1,":c:q                           $ ici réinitialisation de la calculette   ")
  AddGadgetItem(#ComboBox_1,-1,":c:q 2024!=                    $ ***** Factorielle 2014")
  AddGadgetItem(#ComboBox_1,-1,":c:q 50000!=                   $ ***** Factorielle 50000 Calcul long avec message laissez ou tapez Continuer")
  AddGadgetItem(#ComboBox_1,-1,":c:q 20000!=                   $ ***** Factorielle 20000")
  AddGadgetItem(#ComboBox_1,-1,":c:q 1,1414!=                  $ ***** Fonction Gamma d'Euler pour nombre décimaux")
  
  AddGadgetItem(#ComboBox_1,-1,":c:q 24/8+4*25=                $ Donne 3+100=103") ;
  AddGadgetItem(#ComboBox_1,-1,":c:q 24/8+4=*25=               $ donne (3+4)*25=175 ") ;
  AddGadgetItem(#ComboBox_1,-1,":c:q (6-7)*(34-32)=            $   ")
  AddGadgetItem(#ComboBox_1,-1,":c:q((5-3)*(89-87))/4=         $ ")
  AddGadgetItem(#ComboBox_1,-1,":c:q 48/((5,45-3)*(89-87))=    $")
  AddGadgetItem(#ComboBox_1,-1,":c:q(24,89*2)/((5-3)*(89-87))= $**; initialisation avant opération avec :c et :q")
  AddGadgetItem(#ComboBox_1,-1,":m=0,004567e+10=               $ entrée format scientifique")   ; entrée format scientifique pas :c :q ???
  AddGadgetItem(#ComboBox_1,-1,":c:q i1n=                      $**** donne e=2,718...")       ; donne e=2,718... pas de :c:q ???
  AddGadgetItem(#ComboBox_1,-1,":c:q p=                        $**** donne Pi=3,14159...")       ; donne e=2,718...
  AddGadgetItem(#ComboBox_1,-1,":c:q(24*2)/((5-3)*(89-87))=    $ formule avec des parenthéses") ; Formule complexe
  AddGadgetItem(#ComboBox_1,-1,":c:q(52!)/(39!*13!)=           $ Combinaison de 52 par 13") ; Formule complexe
  AddGadgetItem(#ComboBox_1,-1,":c:q(52!)/(13!y4)=             $ Distribution de 52 cartes à 4 joueurs") ; Formule complexe
  AddGadgetItem(#ComboBox_1,-1,":c:q(52!)/(13!y4)=    $ Distribution de 52 cartes à 4 joueurs sans tenir compte de l'ordre des joueurs") ; Formule complexe
  AddGadgetItem(#ComboBox_1,-1,":c:q(52!)*4!/(13!y4)= $ Distribution de 52 cartes à 4 joueurs en tenant compte de l'ordre des joueurs") ; Formule complexe
  
  AddGadgetItem(#ComboBox_1,-1,":c:q                    ")
  AddGadgetItem(#ComboBox_1,-1,":c:q         $*******    LES COS SIN TANG    ***********")
  AddGadgetItem(#ComboBox_1,-1,":c:q 30o=                      $** Cosinus(30) ")  ; Formule cosinus
  AddGadgetItem(#ComboBox_1,-1,":c:q 30s=                      $** Sinus(30)")  ; Formule sinus
  AddGadgetItem(#ComboBox_1,-1,":c:q 30t=                      $** tangente(30)")  ; Formule tangente
  AddGadgetItem(#ComboBox_1,-1,":c:q 60o=                      $** cosinus(60)") ; Formule cosinus
  AddGadgetItem(#ComboBox_1,-1,":c:q 60s=                      $** sinus(60)")  ; Formule sinus
  AddGadgetItem(#ComboBox_1,-1,":c:q 60t=                      $** tangente(60)")  ; Formule tangente
  
  AddGadgetItem(#ComboBox_1,-1,":c:q                    ")
  AddGadgetItem(#ComboBox_1,-1,":c:q =       $******* LES ARCSIN ARCCOS ARCTANG  ***********")
  AddGadgetItem(#ComboBox_1,-1,":c:q i0,866 o=                 $** ArcCosinus(0,866) ")  ; Formule cosinus
  AddGadgetItem(#ComboBox_1,-1,":c:q i0,5s=                    $** ArcSinus(0,5)")  ; Formule sinus
  AddGadgetItem(#ComboBox_1,-1,":c:q i1,732t=                  $** Arctangente(1,732)")  ; Formule tangente
  AddGadgetItem(#ComboBox_1,-1,":c:q i0,5o=                    $** Arccosinus(0,5)") ; Formule cosinus
  
  AddGadgetItem(#ComboBox_1,-1,":c:q                     ")
  AddGadgetItem(#ComboBox_1,-1,":c:q =        $*******    LES COS SIN TANG Hyperboliques   ***********")
  AddGadgetItem(#ComboBox_1,-1,":c:q H 0,9 o=                   $** Cosinus hyper (0,9) ")  ; Formule cosinus
  AddGadgetItem(#ComboBox_1,-1,":c:q H 0,9 s=                   $** Sinus hyper(0,9)")  ; Formule sinus
  AddGadgetItem(#ComboBox_1,-1,":c:q H 0,9 t=                   $** tangente hyper(0,9)")  ; Formule tangente
  AddGadgetItem(#ComboBox_1,-1,":c:q H -0,9 o=                  $** cosinus hyper(-0,9)") ; Formule cosinus
  AddGadgetItem(#ComboBox_1,-1,":c:q H -0,9 s=                  $** sinus hyper(-0,9)")  ; Formule sinus
  AddGadgetItem(#ComboBox_1,-1,":c:q H -0,9 t=                  $** tangente hyper(-0,9)")  ; Formule tangente
  
  AddGadgetItem(#ComboBox_1,-1,":c:q                     ")
  AddGadgetItem(#ComboBox_1,-1,":c:q =        $*******    LES ARCCOS ARCSIN ARCTANG Hyperboliques   ***********")
  AddGadgetItem(#ComboBox_1,-1,":c:q H i1,9 o=                  $** ARCCosinus hyper (1,9) ")  ; Formule cosinus
  AddGadgetItem(#ComboBox_1,-1,":c:q H i0,9 s=                  $** ARCSinus hyper(0,9)")  ; Formule sinus
  AddGadgetItem(#ComboBox_1,-1,":c:q H i0,9 t=                  $** ARCtangente hyper(0,9)")  ; Formule tangente
  
  AddGadgetItem(#ComboBox_1,-1,":c:q                     ")
  AddGadgetItem(#ComboBox_1,-1,"16l=:m                         $  ; Log base10 de 16") ; Log base10 de 16
  AddGadgetItem(#ComboBox_1,-1,"i1nl=:m                        $  log base 10 de e") ; log base 10 de e
  AddGadgetItem(#ComboBox_1,-1,":c:q10@*p=                     $  surface d'un cercle 3,14*R*R") ;  surface d'un cercle 3,14*R*R
  AddGadgetItem(#ComboBox_1,-1,":c:q10@*p*4=                   $  surface d'une sphére 3,14*R*R*4") ;
  AddGadgetItem(#ComboBox_1,-1,":c:q10#*p*4/3=                 $  Volume d'une sphére 3,14*R*R*R*4/3") ;
  AddGadgetItem(#ComboBox_1,-1,":c:q13n/10n=                   $  Changement de base d'un log =Log10(13) à partir de Loge(13)");
  AddGadgetItem(#ComboBox_1,-1,":c:q13l=                       $  Résultat =Log10(13)");
  
  AddGadgetItem(#ComboBox_1,-1,":c:q     $ Initialisation                ")
  AddGadgetItem(#ComboBox_1,-1,":c:q =        $*******    Calcul sur plusieurs lignes   ***********")
  AddGadgetItem(#ComboBox_1,-1," :c:q(24*2)+3 =                $ Calcul sur 2 lignes ceci est la première ligne à exécuter avec ou sans =")
  AddGadgetItem(#ComboBox_1,-1,"/((5-3)*(89-87))=              $ Calcul sur 2 lignes ceci est la deuxième ligne à exécuter")
  AddGadgetItem(#ComboBox_1,-1,":c:q(24*2)+3/((5-3)*(89-87))=  $ Même calcul sur une seule ligne ")
  AddGadgetItem(#ComboBox_1,-1,":c:q                     ")
  AddGadgetItem(#ComboBox_1,-1," $ ********************  Commandes avec CTRL_ID  et Langage MIcrosoft  ************************  ")
  AddGadgetItem(#ComboBox_1,-1,":c:q[MST\P2\MSC]     $ Initialisation en mode scientifique avec temporisation de 2 secondes      ")
  AddGadgetItem(#ComboBox_1,-1,"[CAN\CE]i1n=                         $**** donne e=2,718...")       ; donne e=2,718... pas de :c:q ???
  AddGadgetItem(#ComboBox_1,-1,"[CAN\CE\Dec]120 :m [Hex]=            $*** Conversion  120 décimal en Hexadécimal= 78")       ;
  AddGadgetItem(#ComboBox_1,-1,"[CAN\CE\Dec\1\2\0\Hex]=              $*** Autre façon de Convertir 120 décimal en 78 Hexadécimal")       ;
  AddGadgetItem(#ComboBox_1,-1,"[CAN\CE\Dec]511 :m [Hex]=            $*** Conversion 511 décimal en Hexadécimal")       ;
  AddGadgetItem(#ComboBox_1,-1,"[CAN\CE\Dec\]4294967295 :m [Hex]=    $*** Conversion décimal en Hexadécimal")       ;
  AddGadgetItem(#ComboBox_1,-1,"[CAN\CE\Hex\]FFFFFFFF :m [Dec]=      $*** Conversion  Hexadécimal en décimal ")       ;
  AddGadgetItem(#ComboBox_1,-1,"[CAN\CE\Dec]=[I305]                  $*** passage en mode standard ")       ;
  AddGadgetItem(#ComboBox_1,-1,"[CAN\CE\Dec]=[I304]                  $*** passage en mode scientifique ")       ;
  AddGadgetItem(#ComboBox_1,-1,"[CAN\CE\Dec]120 :m [Hex]= [P10\Dec]= $*** Conversion  120 décimal en Hexadécimal= 78")
  
  ; **************************charge le combobax8 aà partir de l'option Option[xx] qui peut être changé
  ;    AddGadgetItem(#ComboBox_7,-1,"Option[xx]")
  ;     AddGadgetItem(#ComboBox_7,-1,"Langage MS")
  ;     AddGadgetItem(#ComboBox_7,-1,"Boutons")
  Option$=GetGadgetText(#ComboBox_7)
  i=0
  ForEach CMD_H()
    Select option$
      Case "Option[xx]"
        Choix_Comb8$=cmd_h()\L_PP
      Case "Langage MS"
        Choix_Comb8$=cmd_h()\L_MS
      Case "Boutons"
        Choix_Comb8$=cmd_h()\BOUT
      Default
        Choix_Comb8$=cmd_h()\BOUT
    EndSelect
;     AddGadgetItem(#ComboBox_8,-1,Choix_Comb8$)
    tab_ban(i)=Choix_Comb8$
    i+1
  Next
  ReDim tab_ban(i-1)
  SortArray(tab_ban(),#PB_Sort_Ascending | #PB_Sort_NoCase);,0,i-1)
;   SortArray(tab_ban(), #PB_Sort_NoCase );,0,i-1)

For j=0 To i-1
  If tab_ban(j)<>""
    AddGadgetItem(#ComboBox_8,-1,tab_ban(j))
  EndIf  
  Next

  
EndProcedure

;*************************************************Début du Prg Principal ****************************************************
Procedure Charge_gadget9()
  Protected i,AIDE$
  DisableGadget(#ListIcon_11,1)
  DisableGadget(#ListIcon_9,0)
  HideGadget(#ListIcon_11,1)
  HideGadget(#ListIcon_9,0)
  ClearGadgetItems(#ListIcon_9)
  Restore AIDE_GEN
  ;   If LoadFont(1,"Courier new",7,#PB_Font_Bold)
  ;     SetGadgetFont(#ListIcon_9,FontID(1))   ; la police par défaut est remplacée par celle chargée (Courier new 7.5)
  ;   EndIf
;   i=0
  Repeat
    Read.s AIDE$
    If aide$<>"FIN"
      AddGadgetItem(#ListIcon_9,-1,aide$)
      SetGadgetItemColor(#ListIcon_9,-1,#PB_Gadget_BackColor,RGB(255,255,90),0) ; [, Colonne])
;       i+1
    EndIf
  Until AIDE$="FIN"
  AddGadgetItem(#ListIcon_9,-1,"************************************************************************************************************************")
  SetGadgetItemColor(#ListIcon_9,-1,#PB_Gadget_BackColor,RGB(255,255,90),0) ; [, Colonne])
  AddGadgetItem(#ListIcon_9,-1,"**     Voici queques exemples à votre  disposition dans la fenêtre de commande de la calculatyrice    **")
  SetGadgetItemColor(#ListIcon_9,-1,#PB_Gadget_BackColor,RGB(255,255,90),0) ; [, Colonne])
  AddGadgetItem(#ListIcon_9,-1,"************************************************************************************************************************")
  SetGadgetItemColor(#ListIcon_9,-1,#PB_Gadget_BackColor,RGB(255,255,90),0) ; [, Colonne])
  
  For i=0 To CountGadgetItems(#ComboBox_1)
    AddGadgetItem(#ListIcon_9,-1, GetGadgetItemText(#ComboBox_1,i))
    SetGadgetItemColor(#ListIcon_9,-1,#PB_Gadget_BackColor,RGB(255,255,90),0) ; [, Colonne])
;   Debug GetGadgetItemText(#ComboBox_1,i)
Next
;   FreeFont(1)
EndProcedure

Procedure Charge_gadget11(Choix_AId$)
  Protected textex$,indi,indi$,res_f,ind_max.l,j,clef$,res_f2,texte$,texte2$
  DisableGadget(#ListIcon_9,1)
  DisableGadget(#ListIcon_11,0)
  HideGadget(#ListIcon_9, 1)
  HideGadget(#ListIcon_11, 0)
;   ClearGadgetItems(#ListIcon_9)
  ClearGadgetItems(#ListIcon_11)
  
  
  If  Choix_AId$="?" Or  Choix_AId$="??"
    ForEach CMD_H()
      textex$=CMD_H()\L_PP+Chr(10)+CMD_H()\L_MS+Chr(10)+CMD_H()\BOUT+Chr(10)+CMD_H()\ID+Chr(10)+CMD_H()\INF
      
      AddGadgetItem(#ListIcon_11,0,textex$)
      SetGadgetItemColor(#ListIcon_11, -1, #PB_Gadget_BackColor , RGB(245, 245, 220),0) ; [, Colonne])
      SetGadgetItemColor(#ListIcon_11, -1, #PB_Gadget_BackColor , RGB(255, 255, 190),1) ; [, Colonne])
      SetGadgetItemColor(#ListIcon_11, -1, #PB_Gadget_BackColor , RGB(255, 255, 90),2) ; [, Colonne])
      ;  SetGadgetItemColor(#ListIcon_11, -1, #PB_Gadget_BackColor , RGB(230, 230, 250),3) ; [, Colonne])
      SetGadgetItemColor(#ListIcon_11, -1, #PB_Gadget_BackColor , RGB(255, 217, 148),3) ; [, Colonne])
      
      SetGadgetItemColor(#ListIcon_11, -1, #PB_Gadget_BackColor , RGB(255, 255, 0),4) ; [, Colonne])
    Next  
  Else
    indi=1
    indi$=Str(indi)+" "+Choix_AId$    ; Blanc ou space sépare le type et son occurrence du nom de la clé. On peut placer ici un autre caractère alpha ou rien
    res_f=FindMapElement(CMD_S(),indi$)
    ;*******************************************************
    ;   Define el1.inf_wnd=info_wdn()
    If res_f<>0
    Else
;       Debug indi$+" pas touvée"
      Choix_AId$=Left(Choix_AId$,1)
      indi$=Str(indi)+" "+Choix_AId$   ; Blanc ou space sépare le type et son occurrence du nom de la clé. On peut placer ici un autre caractère alpha ou rien
      res_f=FindMapElement(CMD_S(),indi$)
      If res_f=0
        MessageRequester ("ERREUR de RECHERCH", indi$+" pas touvée",0)
      EndIf
    EndIf
    
    ind_max.l=CMD_S()\ind
    For j=1 To ind_max
      clef$=Str(j)+" "+Choix_AId$
      res_f2=FindMapElement(CMD_S(),clef$)
      FindMapElement(CMD_H(),CMD_S()\IND_s)
      texte$="cle_R="+clef$+" clé="+MapKey(CMD_S())+" IND_s="+CMD_S()\IND_s+" ind="+Str(CMD_S()\ind); +" NOM_EXE="+GetFilePart(info_wdn()\NOM_EXE)+" NOM_WND="+info_wdn()\NOM_WND+" Occurrence="+Str(info_wdn()\ind)
      ;       Debug texte$+"  res_f="+Str(res_f2)
      texte2$="cle_R="+clef$+"clé="+MapKey(CMD_H())+" L_PP="+CMD_H()\L_PP+" ID="+CMD_H()\ID+" Bouton="+CMD_H()\BOUT+" L_MS="+CMD_H()\L_MS+" "+CMD_H()\INF
      textex$=CMD_H()\L_PP+Chr(10)+CMD_H()\L_MS+Chr(10)+CMD_H()\BOUT+Chr(10)+CMD_H()\ID+Chr(10)+CMD_H()\INF
;       Debug TEXTE$
      AddGadgetItem(#ListIcon_11,0,textex$)
      SetGadgetItemColor(#ListIcon_11, -1, #PB_Gadget_BackColor , RGB(245, 245, 220),0) ; [, Colonne])
      SetGadgetItemColor(#ListIcon_11, -1, #PB_Gadget_BackColor , RGB(255, 255, 190),1) ; [, Colonne])
      SetGadgetItemColor(#ListIcon_11, -1, #PB_Gadget_BackColor , RGB(255, 255, 90),2) ; [, Colonne])
      ;  SetGadgetItemColor(#ListIcon_11, -1, #PB_Gadget_BackColor , RGB(230, 230, 250),3) ; [, Colonne])
      SetGadgetItemColor(#ListIcon_11, -1, #PB_Gadget_BackColor , RGB(255, 217, 148),3) ; [, Colonne])
      
      SetGadgetItemColor(#ListIcon_11, -1, #PB_Gadget_BackColor , RGB(255, 255, 0),4) ; [, Colonne])
      
    Next
    
  EndIf
  
EndProcedure
;***************************************** Détermine les caractéristiques de la calculatrice ********************************
Define ii,clef1$,Resultat1,clef2$,Resultat2,MESM$,MEsm2$,sort_run, L_PP.s, ID.s, BOUT.s,  L_MS.s, INF.s,i,j,a$

Repeat ; Permet de vérifier si une intance de Calc.exe ou de CalcPlus.exe est en mémoire
  ii+1
  FIND_WINDOWS_INFOS(info_wdn(),"E"); Demande de toutes les clés  des programmes EXEC en mémoire
  clef1$="E1 calc.exe"      ; respecter la case
  Resultat1=FindMapElement(info_wdn(),clef1$)
  If resultat1<>0
    Define el1.inf_wnd=info_wdn()
  EndIf
  clef2$="E1 CalcPlus.exe"  ; respecter la case
  Resultat2=FindMapElement(info_wdn(),clef2$)
  If resultat2<>0
    Define el2.inf_wnd=info_wdn()
  EndIf
  If el1\ind>0 And el2\ind>0
    MESM$=" calc.exe et CalcPlus.exe sont déjà en machine"
    MEsm2$="Choisissez l'un en effacant l'autre"
    NOM_EXE$=Trim(StringField(InputRequester(mesm$,mesm2$,"calc.exe / CalcPlus.exe"),1,"/"))
    If Len(NOM_EXE$)>8
      NOM_EXE$=el2\NOM_EXE
      NOM_WND$=el2\nom_WND
    Else
      NOM_EXE$=el1\NOM_EXE
      NOM_WND$=el1\nom_WND
    EndIf
  ElseIf el1\ind>0
    NOM_EXE$=el1\NOM_EXE
    NOM_WND$=el1\nom_WND
  ElseIf el2\ind>0
    NOM_EXE$=el2\NOM_EXE
    NOM_WND$=el2\nom_WND
  Else
    sort_run=RunProgram(NOM_EXE$,"","",#PB_Program_Hide) ; On lance le programme
    Delay(500) ; ***************************** valeur à ajuster en fonction de la machine ********************************
  EndIf
Until Len(NOM_WND$)>0 Or II>5
;***************************************** Fin de (Détermine les caractéristiques de la calculatrice) ********************************
;******************************** chargement des tables de commandes et d'instructions ***********************************
Repeat
  Read.s L_PP.s
  Read.s ID.s
  Read.s BOUT.s
  Read.s L_MS.s
  Read.s INF.s
  If L_PP<>"FIN"
    If Val(ID)<306 And Val(ID)>399
      instr(L_PP)=Val(ID)
      CMD_H(L_PP)\L_PP=L_PP:CMD_H(L_PP)\ID=ID
      ;     CMD_S(L_PP)\IND_s=L_PP
      FIND_COLL_H(L_PP,ID,BOUT,L_MS,CMD_S())
    Else
      If NOM_WND$="Calculatrice"
        instr(L_PP)=Val(ID)
        CMD_H(L_PP)\L_PP=L_PP:CMD_H(L_PP)\ID=ID
        ;       cmd_s(L_PP)\IND_s=L_PP
        FIND_COLL_H(L_PP,ID,BOUT,L_MS,CMD_S())
      Else
        instr(L_PP)=Val(ID)+1
        CMD_H(L_PP)\L_PP=L_PP:CMD_H(L_PP)\ID=Str(Val(ID)+1)
        ;       CMD_S(L_PP)\IND_s=L_PP
        FIND_COLL_H(L_PP,ID,BOUT,L_MS,CMD_S())
        If Val(ID)=306
          L_PP="MCO":ID="306"
          instr(L_PP)=Val(ID)
          CMD_H(L_PP)\L_PP=L_PP:CMD_H(L_PP)\ID=ID
          CMD_S(L_PP)\IND_s=L_PP
          FIND_COLL_H(L_PP,ID,BOUT,L_MS,CMD_S())
        EndIf
      EndIf
    EndIf
    CMD_H()\L_MS=L_MS:CMD_H()\BOUT=BOUT:CMD_H()\INF=INF
  EndIf
Until L_PP="FIN" And ID="FIN"
;************* POUR PROGRAMMER DES PAUSES de 1s jusqu'à 50 secondes
For j=1 To 50
  a$="P"+Str(J)
  instr(a$)=J
Next
;************* POUR PROGRAMMER Les instructions de I80 à I500 format [I80\I82...]
For I=80 To 500
  a$="I"+Str(I)
  instr(a$)=I
Next
;******************************** Fin de chargement des tables de commandes et d'instructions ***********************************
DisableExplicit

;********************************************************************************************************************************
;********************************************** Programme principal  et boucle des événements  **********************************
;********************************************************************************************************************************

OpenWindow_Window_0()

hmainWnd=GET_HWND_FROM_NOM_WND(NOM_WND$)
;***************************************** '# Activation du mode scientifique
WM_COMMANDE(hMainWnd,304);   SendMessage_(hMainWnd,#WM_COMMAND,304,0) Passage de la calculatrice en mode scientifique
; OpenWindow_Window_0()
charge_combo()
SetForegroundWindow_(WindowID(#Window_0))
SetActiveWindow(#Window_0)
PATH_help$=GetEnvironmentVariable("windir")+"\help\"
path_dirc$=GetCurrentDirectory()
; Debug _s(path_dirc$)+_s(path_help$)
;{- Event loop
;********************  POUR LE TRI PAR COLONNE ******************************
updown=1
lastcol=0
UpdatelParam()
SetWindowCallback(@ColumnClickCallback())
;********************* FIN POUR LE TRI **************************************

Repeat
  SetActiveWindow(#Window_0)
  SetForegroundWindow_(WindowID(#Window_0))
  Event=WaitWindowEvent()
  EventGadget=EventGadget()
  EventType=EventType()
  eventmenu=EventMenu()
  
  Select Event
    Case #PB_Event_Menu
      Select eventmenu
        Case #menu_1
          sort_Help=RunProgram(path_help$+"calc.chm","","") ; On lance le programme
        Case #menu_2
          ;           sort_Help=RunProgram(path_dirc$+"\AIDE_CALCULATRICE2.htm","","") ; On lance le programme
        Case #help
          sort_Help=RunProgram(path_help$+"calc.chm","","") ; On lance le programme
;           sort_Help=RunProgram(path_dirc$+"\Help_Commandes_Calc.htm","","") ; On lance le programme
          ; sort_Help=RunProgram(path_dirc$+"A_rap.html","","") ; On lance le programme
          
      EndSelect
      ; ///////////////////
    Case #PB_Event_Gadget
      EventGadget=EventGadget()
      EventType=EventType()
      Select EventGadget
        Case #TEXT_GAD1
        Case #TEXT_GAD2
        Case #ComboBox_7
          Option$=GetGadgetText(#ComboBox_7)
          ClearGadgetItems(#ComboBox_8)
          ;           Debug option$
          i=0
          ForEach CMD_H()
            Select option$
              Case "Option[xx]"
                Choix_Comb8$=cmd_h()\L_PP
              Case "Langage MS"
                Choix_Comb8$=cmd_h()\L_MS
              Case "Boutons"
                Choix_Comb8$=cmd_h()\BOUT
              Default
                Choix_Comb8$=cmd_h()\BOUT
            EndSelect
            tab_ban(i)=Choix_Comb8$
            i+1
          Next
          SortArray(tab_ban(),#PB_Sort_Ascending | #PB_Sort_NoCase)
          For j=0 To i-1
            If tab_ban(j)<>""
              AddGadgetItem(#ComboBox_8,-1,tab_ban(j))
            EndIf
          Next
        Case #ComboBox_8
        Case #ComboBox_1
          ;       Debug _n(event_gadget)+_n(event_type)
        Case #ListView_2
        Case #Button_8
          Choix_AId$=Trim(GetGadgetText(#ComboBox_8))
          If choix_Aid$="AIDE_Help" Or choix_Aid$=""
            Charge_gadget9()
          Else
            Charge_gadget11(Choix_AId$)
            
          EndIf
          
        Case #ListIcon_9
          
        Case #CheckBox_1
          GET_HWND_FROM_NOM_WND(NOM_WND$)
          ;********************    MINIMISE LA CLACULETTE   *****************************
          ;  SendMessage_(hmainWnd,#WM_SYSCOMMAND,#SC_MINIMIZE,0)
          ; ;Options numCommand:
          ; ; 0 = #SC_MINIMIZE
          ; ; 1 = #SC_MAXIMIZE
          ; ; 2 = #SC_RESTORE
          ; ; 3 = #SC_CLOSE
          If GetGadgetState(#CheckBox_1)=#PB_Checkbox_Checked
            SendMessage_(hmainWnd,#WM_SYSCOMMAND,#SC_MINIMIZE,0)
          Else
            SendMessage_(hmainWnd,#WM_SYSCOMMAND,#SC_RESTORE,0)
          EndIf
        Case #Button_3
          GET_HWND_FROM_NOM_WND(NOM_WND$)
          ;         Texte$=GetGadgetText(#ComboBox_1)
          ; ************ Analyse du texte pour différencier langage Microsoft des Commandes directes avec CTRL_id  (voir datasection)******
          Texte$=StringField(GetGadgetText(#ComboBox_1),1,"$")
          Max_el.l=ANALYSE_CM(Texte$,T_CM(),Instr())
          For i=0 To Max_el
            If T_CM(i)\E="M"
              sortie$=EXE_WHND(hMainWnd,T_CM(i)\M)
              ;             AddGadgetItem(#ListView_2,0,texte$+Chr(10)+sortie$)
              ;             pause(2000)
            ElseIf T_CM(i)\E="C"
              ;             pause(1000)
              Select t_cm(i)\c
                Case 84
                  CHERCHE_STAT()
                Case 304 To 305 ; MODE SCIENTIFIQUE STANDARD ET CONVERSION POUR la calculette microsoft Plus le Handle peut changer !!!!
                  SendMessage_(hmainWnd,#WM_SYSCOMMAND,#SC_RESTORE,0)
                  ; ;Options numCommand:
                  ; ; 0 = #SC_MINIMIZE
                  ; ; 1 = #SC_MAXIMIZE
                  ; ; 2 = #SC_RESTORE
                  ; ; 3 = #SC_CLOSE
                  GET_HWND_FROM_NOM_WND(NOM_WND$)
                  FLAG_MOD_hWND=1
                Case 306
                  If NOM_WND$="Calculatrice"
                  Else
                    SendMessage_(hmainWnd,#WM_SYSCOMMAND,#SC_RESTORE,0)
                    GET_HWND_FROM_NOM_WND(NOM_WND$)
                    FLAG_MOD_hWND=1
                  EndIf
                Case 112 ; touche entrée ou =   => demande de sortie
                  ;                 pause(temp10)
                  AddGadgetItem(#ListView_2,0,texte$+Chr(10)+sortie$)
                Default
              EndSelect
              Select t_cm(i)\c
                Case 80 To 500
                  WM_COMMANDE(hMainWnd,t_cm(i)\c)
                Case 1 To 79
                  ETAT_AV.l=GetGadgetState(#CheckBox_1)
                  SendMessage_(hmainWnd,#WM_SYSCOMMAND,#SC_RESTORE,0)
                  SetGadgetState(#CheckBox_1,#PB_Checkbox_Unchecked)
                  time.l=t_cm(i)\c
                  time*1000
                  Delay(time)
                  If ETAT_AV=#PB_Checkbox_Checked
                    SendMessage_(hmainWnd,#WM_SYSCOMMAND,#SC_MINIMIZE,0)
                    SetGadgetState(#CheckBox_1,#PB_Checkbox_Checked)
                  EndIf
              EndSelect
            EndIf
          Next
          AddGadgetItem(#ListView_2,0,texte$+Chr(10)+WM_COMMANDE(hMainWnd,300))
          If FLAG_MOD_hWND=1
            Delay(1000)
            SendMessage_(hmainWnd,#WM_SYSCOMMAND,#SC_MINIMIZE,0)
            FLAG_MOD_hWND=0
          EndIf
          ;         sortie$=EXE_WHND(hMainWnd,TEXTE$)
          ;         AddGadgetItem(#ListView_2,0,texte$+Chr(10)+sortie$)
      EndSelect  ;***************ici
      ; ////////////////////////
    Case #PB_Event_CloseWindow
      EventWindow=EventWindow()
      If EventWindow=#Window_0
        retour=PostMessage_(hMainWnd,#WM_CLOSE,0,0) ; ***************  Ferme la calculatrice calc.exe
        CloseWindow(#Window_0)
        End
      EndIf
  EndSelect
ForEver

DATASECTION dans le prochain post car >60000 Ko
Dernière modification par PAPIPP le mer. 12/oct./2011 9:50, modifié 1 fois.
Il est fort peu probable que les mêmes causes ne produisent pas les mêmes effets.(Einstein)
Et en logique positive cela donne.
Il est très fortement probable que les mêmes causes produisent les mêmes effets.
PAPIPP
Messages : 534
Inscription : sam. 23/févr./2008 17:58

Re: Pilotage d'une application externe (Ex: calculatrice MS)

Message par PAPIPP »

Voici la datasection du PRG précédent

Code : Tout sélectionner

DataSection
  Data.s "[OPT]"    ,"ID[Ixx]" ,"Bouton"     ,"Langage MS"    ,"Aide calculatrice"
  Data.s "+/-"      ,"80"     ,"+/-"        ,"F9"            ,"Change le signe du nombre affiché"
  Data.s "CAN"      ,"81"     ,"C"          ,"ÉCHAP"         ,"Efface le nombre affiché"
  Data.s "Esc"      ,"81"     ,"C"          ,"ÉCHAP"         ,"Efface le nombre affiché"
  Data.s "CE"       ,"82"     ,"CE"         ,":q"            ,"Efface le calcul en cours"
  Data.s "Ret"      ,"83"     ,"Ret arr"    ,"RET.ARR"       ,"Retour arrière Supprime le dernier chiffre du nb affiché"
  Data.s "Sta"      ,"84"     ,"Sta"        ,"CTRL_S"        ,"Affiche la boîte de dialogue Statistiques et active les boutons Ave, Sum, s et Dat"
  Data.s ","        ,"85"     ,","          ,","             ,"Virgule (ATTENTION) Insère un séparateur décimal"
  Data.s "And"      ,"86"     ,"And"        ,"&"             ,"Calcule le ET logique bit à bit"
  Data.s "Or"       ,"87"     ,"Or"         ,"|"             ,"calcule le OU logique bit à bit"
  Data.s "Xor"      ,"88"     ,"XOR"        ,"^"             ,"Calcule le OU exclusif logique bit à bit"
  Data.s "Lsh"      ,"89"     ,"Lsh"        ,"<"             ,"Décalage vers la gauche avec Inv décalage vers la droite"
  Data.s "/"        ,"90"     ,"/"          ,"/"             ,"Divise"
  Data.s "*"        ,"91"     ,"*"          ,"*"             ,"Multiplie"
  Data.s "+"        ,"92"     ,"+"          ,"+"             ,"Ajoute"
  Data.s "-"        ,"93"     ,"-"          ,"-"             ,"Soustrait"
  Data.s "%"        ,"94"     ,"Mod"        ,"%"              ,"Affiche le coefficient ou le restant de x/y"
  Data.s "x^y"      ,"95"     ,"x^y"        ,"y"              ,"Calcule x à la puissance y. Avec Inv+x^y calcule la racine n-ième de x"
  Data.s "Int"      ,"96"     ,"INT"        ,";"             ,"Affiche la partie entière d’un nombre décimal Inv+INT affiche sa partie décimale"
  Data.s "Not"      ,"97"     ,"NOT"        ,"~"              ,"Calcule le complément logique bit à bit"
  Data.s "sin"      ,"98"     ,"sin"        ,"s"              ,"sinus du nombre affiché et Inv+sin arc sinus. et Hyp+sin sinus hyperbolique et Inv+Hyp+sin arc sinus hyperbolique"
  Data.s "cos"      ,"99"     ,"cos"        ,"o"              ,"cosinus du nombre affiché et Inv+cos arc cosinus. et Hyp+cos cosinus hyperbolique et Inv+Hyp+cos arc cosinus hyperbol"
  Data.s "tan"      ,"100"    ,"tan"        ,"t"              ,"tangente du nombre affiché. Inv+tan arc tangente. Hyp+tan tangente hyperbolique. Inv+Hyp+tan arc tangente hyperbolique"
  Data.s "ln"       ,"101"    ,"ln"         ,"n"              ,"Logarithme népérien avec Inv e^ x = e puissace x"
  Data.s "log"      ,"102"    ,"log"        ,"l"              ,"Logarithme décimal Avec Inv 10^x = 10 puissance x"
  Data.s "Rac"      ,"103"    ,"sqt"        ,"@"              ,"Puissance x^2 Avec Inv+x^2 racine carrée Mode standard"
  Data.s "sqt"      ,"103"    ,"sqt"        ,"@"              ,"Puissance x^2 Avec Inv+x^2 racine carrée Mode standard"
  Data.s "x^2"      ,"104"    ,"x^2"        ,"@"              ,"Puissance x^2 Avec Inv+x^2 racine carrée Mode scientifique"
  Data.s "x^3"      ,"105"    ,"x^3"        ,"#"              ,"Puissance x^3 Avec Inv Racine cubique"
  Data.s "!"        ,"106"    ,"n!"         ,"!"              ,"Factorielle du nb affiché et Fonction Gamma d'Euler pour les Nb décimaux"
  Data.s "1/x"      ,"107"    ,"1/x"        ,"r"              ,"Inverse du nb affiché"
  Data.s "dms"      ,"108"    ,"dms"        ,"m"              ,"Converti nb en Degré Minute Seconde Inv dms Degré Minute Seconde =nb"
  Data.s "Pour"     ,"109"    ,"%"          ,""               ,"Pourcentage Mode standard seulement à ne pas confondre avec % Mod scientifique"
  Data.s "F-E"      ,"110"    ,"F-E"        ,"v"              ,"Active et désactive la notation scientifique. Les nombres > 10^32 sont affichés en scientifique"
  Data.s "pi"       ,"111"    ,"pi"         ,"p"              ,"Pi =3,1415.. et Inv 2* pi =6,28"
  Data.s "="        ,"112"    ,"="          ,"="              ,"Effectue toute opération. Cliquez de nouveau sur =. Pour répéter"
  Data.s "MC"       ,"113"    ,"MC"         ,":c"              ,"Efface tout nombre stocké en mémoire"
  Data.s "MR"       ,"114"    ,"MR"         ,":r"             ,"Rappelle le nombre stocké en mémoire"
  Data.s "MS"       ,"115"    ,"MS"         ,":m"             ,"Met en mémoire le nombre affiché"
  Data.s "M+"       ,"116"    ,"M+"         ,":p"             ,"Ajoute le nombre affiché à la mémoire, sans afficher la somme de ces nombres"
  Data.s "Exp"      ,"117"    ,"Exp"        ,"x"              ,"entrer les nombres en notation scientifique. L'exposant est limité à quatre chiffres"
  Data.s "Ave"      ,"118"    ,"Ave"        ,"CTRL+A"         ,"moyenne des valeurs Statistiques .Inv+Ave calcule la moyenne des carrés"
  Data.s "Sum"      ,"119"    ,"Sum"        ,"CTRL_T"         ,"somme des valeurs affichées en Sta Inv+Sum calcule la somme des carrés"
  Data.s "sig"      ,"120"    ,"s"          ,"CTRL_D"         ,"écart type rapporté à n-1, Inv+s calcule l'écart type rapporté à n"
  Data.s "Dat"      ,"121"    ,"Dat"        ," INS "          ,"Entrez les éléments Statistiques"
  Data.s "("        ,"122"    ,"("          ,"("              ,"Parenthèse ouvrante Max de niveau=25"
  Data.s ")"        ,"123"    ,")"          ,")"              ,"Parenthèse fermante Max de niveau=25"
  Data.s "0"        ,"124"    ,"0"          ,"0"              ,"Chiffre 0"
  Data.s "1"        ,"125"    ,"1"          ,"1"              ,"Chiffre 1"
  Data.s "2"        ,"126"    ,"2"          ,"2"              ,"Chiffre 2"
  Data.s "3"        ,"127"    ,"3"          ,"3"              ,"Chiffre 3"
  Data.s "4"        ,"128"    ,"4"          ,"4"              ,"Chiffre 4"
  Data.s "5"        ,"129"    ,"5"          ,"5"              ,"Chiffre 5"
  Data.s "6"        ,"130"    ,"6"          ,"6"              ,"Chiffre 6"
  Data.s "7"        ,"131"    ,"7"          ,"7"              ,"Chiffre 7"
  Data.s "8"        ,"132"    ,"8"          ,"8"              ,"Chiffre 8"
  Data.s "9"        ,"133"    ,"9"          ,"9"              ,"Chiffre 9"
  Data.s "A"        ,"134"    ,"A"          ,"A"              ,"Hex $A"
  Data.s "B"        ,"135"    ,"B"          ,"B"              ,"Hex $B"
  Data.s "C"        ,"136"    ,"C"          ,"C"              ,"Hex $C"
  Data.s "D"        ,"137"    ,"D"          ,"D"              ,"Hex $D"
  Data.s "E"        ,"138"    ,"E"          ,"E"              ,"Hex $E"
  Data.s "F"        ,"139"    ,"F"          ,"F"              ,"HEX $F"
  Data.s "Inv"      ,"140"    ,"Inv"        ,"i"              ,"Inverse sin, cos, tan, PI, x^y, x^2, x^3, ln, log, Ave, Sum et s. Ce mode est désactivé. Après utilisation"
  Data.s "Hyp"      ,"141"    ,"Hyp"        ,"H"              ,"mode hyperbolique pour sin, cos et tan. Ce mode est désactivé. Après utilisation"
  Data.s "Cop"      ,"300"    ,"CTRL+C"     ,""               ,"Copier permet de récupérer un résultat"
  Data.s "Col"      ,"301"    ,"CTRL+V"     ,""               ,"Coller permet d'introduire une formule ou un nombre"
  Data.s "?"        ,"302"    ,"A propos"   ,"?"              ,"Aide calculatrice"
  Data.s "Grp"      ,"303"    ,"Groupement" ,""               ,"Groupement de l’affichage pour faciliter la lecture"
  Data.s "MSC"      ,"304"    ,"Mode scient",""               ,"Mode scientifique"
  Data.s "MST"      ,"305"    ,"Mode Std"   ,""               ,"Mode standard"
  ;   ; ****Les CTRL_ID sont décalées de +1 pour la calculette Plus à cause du Mode Conversion  CTRL_ID 306 de CALC_PLUS
  Data.s "MCO"      ,"306"    ,"Mode Conv"  ,""               ,"Mode Conversion pour Calculatrice Plus"
  Data.s "Hex"      ,"306"    ,"Hex"        ,"F5"             ,"Mode Hexadécimal ID+1 pour CalcPlus"
  Data.s "Dec"      ,"307"    ,"Dec"        ,"F6"             ,"Mode décimal ID+1 pour CalcPlus"
  Data.s "Oct"      ,"308"    ,"Octal"      ,"F7"             ,"Mode Octal ID+1 pour CalcPlus"
  Data.s "Bin"      ,"309"    ,"Bin"        ,"F8"             ,"Mode Binaire ID+1 pour CalcPlus"
  Data.s "Qmo"      ,"310"    ,"Q-mot"      ,"F12"            ,"Sortie sur 16 octets ID+1 pour CalcPlus"
  Data.s "Dmo"      ,"311"    ,"D-Mot"      ,"F2"             ,"Sortie sur 8 octets ID+1 pour CalcPlus"
  Data.s "Mot"      ,"312"    ,"Mot"        ,"F3"             ,"Sortie sur 4 octets ID+1 pour CalcPlus"
  Data.s "Byt"      ,"313"    ,"Octet"      ,"F4"             ,"Sortie sur 1 octet ID+1 pour CalcPlus"
  Data.s "Deg"      ,"314"    ,"Degrs"      ,"F2"             ,"pas de conversion en Degré Indique seulement l’unité d’angle ID+1 pour CalcPlus"
  Data.s "Rad"      ,"315"    ,"Radians"    ,"F3"             ,"pas de conversion en Radian Indique seulement l’unité d’angle ID+1 pour CalcPlus"
  Data.s "Gra"      ,"316"    ,"Grades"     ,"F4"             ,"pas de conversion en Grade Indique seulement l’unité d’angle ID+1 pour CalcPlus"
  Data.s "Aid"      ,"317"    ,"?"          ,"F1"             ,"Aide ID+1 pour CalcPlus"
  Data.s "Aid"      ,"318"    ,"?"          ,"F1"             ,"Aide"
  Data.s "Gdev"     ,"319"    ,"Gest devises",""              ,"Gestion devises ID+1 pour CalcPlus"
  Data.s "NST"      ,"320"    ,"Mode Std"   ,""               ,"Mode standard Mode non standard seulement pour Calc plus ID+1 pour CalcPlus"
  Data.s "STD"      ,"320"    ,"Mode non std",""              ,"Mode Non standard calcplus en bleu en bascule avec mode standard pour CalcPlus"
  ;   ; ****Les CTRL_ID sont à nouveau identiques pour les 2 calculatrices calc et CALC_PLUS
  Data.s "Edit"     ,"403"    ,"Zone_édition",""              ,"Edition de l'affichage de la calculatrice vers le PRG"
  Data.s "Ixxx"     ,"xxx"    ,""           ,""               ,"Ixxx Ordre direct en CTRL_ID=xxxt EX: [I303]"
  Data.s "Pxx"      ,""       ,""           ,""               ,"Pause en secondes EX: [P3] Pause de 3 secondes"
  ;   Data.s "Ret"   ,"411"   ,"Stat retour"   ," "              ,""
  ;   Data.s "LOAD"  ,"410"   ,"Stat load"     ,""               ,""
  ;   Data.s "CD"    ,"494"   ,"stat"          ,""               ,""
  ;   Data.s "CAD"   ,"405"   ,"qtat"          ,""               ,""
  Data.s "FIN","FIN","FIN","FIN","FIN"
  AIDE_GEN:
  Data.s "                  ELEMENTS DU LANGAGE MS DE LA CALCULATRICE ET LES OPTIONS POSSIBLES"
  Data.s " "
  Data.s "Si vous utilisez le langage MS vous pouvez placer les commandes les une après les autres"
  Data.s " l’ordre d’exécution est réalisé de gauche à droite en tenant compte des priorités liées aux opérateurs"
  Data.s ""
  Data.s "Avant d’exécuter toute nouvelle commande n’oubliez pas d’initialiser la calculatrice avec LES commandes:q:c"
  Data.s "Si vous ne le faite pas, le calcul se poursuit sur la calculatrice en fonction des résultats précédemment obtenus."
  Data.s "  Ceci permet de réaliser des opérations en plusieurs passages. Vous pouvez effacer seulement le nombre affiché"
  Data.s "  soit effacer le calcul en cours mais en gardant le nombre affiché"
  Data.s "Exemple:"
  Data.s ""
  Data.s "ATTENTION ::c:q n’efface pas la mémoire pour effacer la mémoire utiliser la commande[MC]"
  Data.s "Ex :c:q[MC]1:p2:p 3:p4:p5:p:r=donne 15 mais si vous répétez la commande sans:c"
  Data.s "Ex ::q1:p2:p 3:p4:p5:p:r= Vous allez ajouter à chaque fois 15"
  Data.s ""
  Data.s "Autre remarque : les Commandes sont sensibles à la case donc ATTENTION à la case (minuscule majuscule)"
  Data.s ""
  Data.s "Enfin pour obtenir un résultat sur la calculatrice n’oubliez pas la commande =qui permet d’afficher les calculs"
  Data.s ""
  Data.s "Exemples ::"
  Data.s " :q12+4*5=donne 32 c’est à dir(5*4)+12=32 et non 80 pour obtenir 80 voici la commande:"
  Data.s " :q(12+4)*5=donne 80 Vous pouvez utiliser 25 niveaux de parenthèse."
  Data.s "Ou encore mieux en demandant le résultat intermédiaire avec la commande ="
  Data.s " :q :c12+4=*5=donne aussi 80"
  Data.s ""
  Data.s " :c Efface le calcul en cours."
  Data.s " :e Vous permet de taper sous forme décimale des nombres en notation scientifique."
  Data.s " :m Met en mémoire le nombre affiché."
  Data.s " :p Ajoute le nombre affiché au nombre en mémoire."
  Data.s " :q Efface nombre affiché."
  Data.s " :r Affiche le nombre stocké en mémoire."
  Data.s " \Fonctionne exactement comme Dat. Cliquez sur Sta avant d'utiliser cette touche."
  Data.s ""
  Data.s "Le tableau fournit une liste des boutons de la Calculatrice et de leurs équivalents claviers,."
  Data.s "ainsi que les options du langage MS touche par touche. Lorsque vous utilisez la Calculatrice,"
  Data.s "vous pouvez voir l'équivalent clavier d'un bouton:à cet effet, cliquez avec le bouton droit de la souris"
  Data.s "sur le bouton de la Calculatrice souhaité, puis cliquez sur Qu'est-ce que c'est ?"
  Data.s "Lorsqu’il n’existe pas de commande dans le langage MS vous pouvez utiliser les options entre crochets [xxx\yyy]"
  Data.s "ou utiliser le CTRL_ID directement par exemple pour changer le signe du nombre affiché deux options:"
  Data.s " -1	[+/-] commande option Format[cmd1\cmd2\cmd3...]voir l’aide pour les commandes"
  Data.s " -2 ou[I80]envoi directe du CTR_ID ici 80"
  Data.s "Vous trouverez de multiple exemples de l’utilisation du langage MS+options en déroulant la ComboBoxGadget du programme."
  Data.s "Pour vérifier des calculs intermédiaires vous pouvez demander une pause en seconde de cette façon[P12]"
  Data.s "pause de 12 secondes pour vérifier la valeur affichée sur la calculette."
  Data.s "********* SI VOUS UTILISEZ UNE DEMANDE D'AIDE DE TYPE ? VOUS POUVEZ TRIER UNE COLONNE DE VOTRE CHOIX ***************"
  Data.s "FIN","FIN","FIN","FIN","FIN"
  
EndDataSection


Il est fort peu probable que les mêmes causes ne produisent pas les mêmes effets.(Einstein)
Et en logique positive cela donne.
Il est très fortement probable que les mêmes causes produisent les mêmes effets.
PAPIPP
Messages : 534
Inscription : sam. 23/févr./2008 17:58

Re: Pilotage d'une application externe (Ex: calculatrice MS)

Message par PAPIPP »

Bonjour à tous
Voici une explication rapide pour déterminer les Ctrl_Id

J'avais besoin d'une plus grande précision dans la notation scientifique mais je voulais rester en PB
c'est pour cela que j'ai recherché diverses méthodes.

Pilotage d’une application externe. Exemple avec la calculatrice de Microsoft
Deux grandes méthodes:
La première consiste à simuler les touches de l’application;
Le deuxième consiste à envoyer des commandes connaissant le handle et Ctrl-id de la commande;
L’ inconvénient majeur de la première est de maintenir le focus de l’application externe au premier plan;
L’ inconvénient majeur de la deuxième est de connaitre les CTRL-ID de chaque commande.

Le Prg précédent ne fonctionne pour l'instant qu'en mode scientifique et standard

Pour obtenir la calculatrice plus de Microsoft (free)
http://www.microsoft.com/downloads/fr- ... 7f157c091

Pour obtenir les logiciels qui retrouvent le CTRL_ID (free)
Winspector : http://www.softpedia.com/get/Security/ ... tor.shtml
Winexplorer : http://en.kioskea.net/download/download ... inexplorer

Petit logiciel de Netmaestro :

Code : Tout sélectionner

;==============================================================
; Program:         Digger
; Author:          Lloyd Gallant (netmaestro)
; Date:            December 20, 2007
; Target OS:       Microsoft Windows All
; Target Compiler: PureBasic 4.0 and later
; License:         Free, unrestricted, use at your own risk
;==============================================================

OpenWindow(0,0,0,440,64,"",#PB_Window_BorderLess|#WS_BORDER|#PB_Window_Invisible)
StickyWindow(0,1)
wclight =  RGB(255,255,223)
wcdark  =  RGB(235,235,203)
SetWindowColor(0,wclight)
ExamineDesktops()
screenw = DesktopWidth(0)
screenh = DesktopHeight(0)
CreateGadgetList(WindowID(0))
TextGadget(0,0,0,100,16,"")
TextGadget(1,60,0,80,16,"Hwnd")
TextGadget(2,140,0,100,16,"Caption")
TextGadget(3,240,0,60,16,"Ctrl ID")
TextGadget(4,300,0,140,16,"Classname")
TextGadget(5,0,16,60,10,"")
TextGadget(6,0,26,60,16,"Window:")
TextGadget(7,0,42,60,22,"   Parent:")
TextGadget(8,60,26,80,16,"")
TextGadget(9,140,26,100,16,"")
TextGadget(10,240,26,60,16,"")
TextGadget(11,300,26,140,16,"")
TextGadget(12,60,42,80,16,"")
TextGadget(13,140,42,100,16,"")
TextGadget(14,240,42,60,16,"")
TextGadget(15,300,42,140,16,"")
For i=0 To 7
  SetGadgetColor(i,#PB_Gadget_BackColor,wcdark)
Next
For i=8 To 15
  SetGadgetColor(i,#PB_Gadget_BackColor,wclight)
Next
HideWindow(0,0)

Repeat
  Delay(1)
  ev=WindowEvent()
  x=DesktopMouseX():y=DesktopMouseY()
  If x > screenw-WindowWidth(0)
    wx = x-WindowWidth(0)
  Else
    wx = x+10
  EndIf
  If y >= screenh-WindowHeight(0)+20
    wy = y-WindowHeight(0)-10
  Else
    wy = y+20
  EndIf
  ResizeWindow(0, wx, wy, #PB_Ignore, #PB_Ignore)
  hwnd = WindowFromPoint_(x|y<<32)
  If hwnd<>oldhwnd Or ev=#PB_Event_Repaint
    hwnd$ = Hex(hwnd)
    caption$ = Space(100)
    GetWindowText_(hwnd, @caption$, 99)
    ctrlid$ = Str(GetWindowLong_(hwnd, #GWL_ID))
    class$ = Space(140)
    GetClassName_(hwnd, @class$, 139)
    SetGadgetText(8, hwnd$)
    SetGadgetText(9, caption$)
    SetGadgetText(10, ctrlid$)
    SetGadgetText(11, class$)
    parent = GetParent_(hwnd)
    parent$ = Hex(parent)
    caption$ = Space(100)
    GetWindowText_(parent, @caption$, 99)
    ctrlid$ = Str(GetWindowLong_(parent, #GWL_ID))
    class$ = Space(140)
    GetClassName_(parent, @class$, 139)
    SetGadgetText(12, parent$)
    SetGadgetText(13, caption$)
    SetGadgetText(14, ctrlid$)
    SetGadgetText(15, class$)
    oldhwnd = hwnd   
    RedrawWindow_(WindowID(0),0,0,#RDW_UPDATENOW)
  EndIf
Until GetAsyncKeyState_(#VK_RBUTTON) & 32768
Le code suivant de PATRIK88 avec une modif permet de connaitre les CTRL_ID

Code : Tout sélectionner

; CODE PATRIK88 mise à jour du code le 17/02/09 MODIFIE PAR PAPIPP
;
; -executer le code suivant,
; -dans la liste déroulante choisir une application qui s'exécute.
; -cliquer executer.
;
; par défaut l'application crée un source purebasic de la "fenetre capturée"
; dans le dossier de compilation.
;
; cette application est limitée au gadget combo, text, string et button.
; et elle ne prend pas en compte le style de la fenetre capturée.
;
; vous pourrez l'étendre à loisirs aux autres type de gadgets
;
; attention, cette appli ne "capture" pas le code de l'application, elle ne fait que recréer l'Interface avec des commandes purebasic.
;
; comme d'hab (snif) il subsiste un loup, le frame3dgadget et interprété comme un "button" ...
;
; pat
; Plier/DéplierCode originalCopierOuvrirCompiler
; programme : captureGadget
; objet : génére le code purebasic de "dessin" d'une fenetre windows en cours d'éxecution

Enumeration
  #FEN_0
  #G_TEXT_FEN_A_CAPTURER:#G_COMBO_FEN_A_CAPTURER
  #G_TEXT_NOM_FICHIER:#G_STRING_NOM_FICHIER:#G_BUTTON_PARCOURIR
  #G_BUTTON_EXECUTER:#G_BUTTON_QUITTER
	
EndEnumeration

#Fichier=0

Structure STRU_INFO_GADGET
  win.l
  className$
  ctrl_id$
EndStructure

EnableExplicit

Global FEN_X.w,FEN_Y.w,FEN_WIDTH.w,FEN_HEIGHT.w, numero_gadget.w, hauteur_barreTitre.w

Procedure.l EnumChildWindowProc(hwnd.l, *cg.STRU_INFO_GADGET)
  Protected classe$, chaine$, rc.RECT, style.l
  Protected GDT_X.w,GDT_Y.w,GDT_WIDTH.w,GDT_HEIGHT.w
  Protected chaine_sortie.s,chaine_coords.s,ctrlid$
   
  If GetParent_(hWnd) = *cg\win
    classe$=Space(100)
    chaine$=Space(255)
    GetClassName_(hwnd, @classe$, 100)
    GetWindowText_(hwnd,@chaine$,255)
    GetWindowRect_(hwnd,@rc)
    style=GetWindowLong_(hwnd,#GWL_EXSTYLE)
    ctrlid$=Str(GetWindowLong_(hwnd,#GWL_ID))
		
    GDT_X = rc\left-FEN_X-2*GetSystemMetrics_(#SM_CYBORDER) : GDT_Y = rc\top-FEN_Y-hauteur_barreTitre : GDT_WIDTH = rc\right-rc\left : GDT_HEIGHT = rc\bottom-rc\top
    chaine_coords = Str(GDT_X)+","+Str(GDT_Y)+","+Str(GDT_WIDTH)+","+Str(GDT_HEIGHT)
   
    Debug classe$
   
    If classe$ = "ComboBox"
      classe$ = "ComboBoxGadget"
      chaine_sortie = classe$+"("+Str(numero_gadget)+","+chaine_coords+")"
      ;;,"+ Chr(34) +chaine$+ Chr(34)
    EndIf
    If classe$ = "Static"
      classe$ = "textgadget"
      chaine_sortie = classe$+"("+Str(numero_gadget)+","+chaine_coords+","+ Chr(34) +chaine$+ Chr(34) +")"
    EndIf
    If classe$ = "Edit"
      classe$ = "stringgadget"
      chaine_sortie = classe$+"("+Str(numero_gadget)+","+chaine_coords+","+ Chr(34) +chaine$+ Chr(34) +")"
    EndIf
    If classe$ = "Button"
      classe$ = "buttongadget"
      chaine_sortie = classe$+"("+Str(numero_gadget)+","+chaine_coords+","+ Chr(34) +chaine$+ Chr(34) +")"
    EndIf
			chaine_sortie+" ; CTRL_ID="+ctrlid$
    WriteStringN(#Fichier, chaine_sortie)
   
    numero_gadget+1
  EndIf
  ProcedureReturn 1
EndProcedure

Procedure FEN0_ExecuteCapture(Fichier_Sortie.s)
  Protected winhWnd.l,gadgethWnd.l=0,shctl.l,chaine.s{256}="",style.l,classe.s{256}
  Protected chaine_sortie.s,chaine_coords.s,ctrlid$
	
  Protected window_border.w,WindowRect.RECT,ClientRect.RECT
	
  Protected buffer$
  Protected cg.STRU_INFO_GADGET
	
  If CreateFile(#Fichier,Fichier_Sortie)
		
    winhWnd=Val(StringField(GetGadgetText(#G_COMBO_FEN_A_CAPTURER),1," "))
		
    GetWindowRect_(winhWnd,@WindowRect)   ; encombrement totale de la fenetre
    GetClientRect_(winhWnd,@ClientRect)   ; surface utilisable de la fenetre
		
    window_border=GetSystemMetrics_(#SM_CYBORDER) ; la petite bordure autour de la fentre
		
    hauteur_barreTitre=WindowRect\bottom-WindowRect\top-ClientRect\bottom-2*window_border
		
    FEN_X=WindowRect\left:FEN_Y=WindowRect\top
    FEN_WIDTH=ClientRect\right-ClientRect\left:FEN_HEIGHT=ClientRect\bottom-ClientRect\top
		
    chaine_coords=Str(FEN_X)+","+Str(FEN_Y)+","+Str(FEN_WIDTH)+","+Str(FEN_HEIGHT)
    chaine_sortie="openwindow(0"+","+chaine_coords
    chaine_sortie=chaine_sortie+","+Chr(34)+LTrim(StringField(GetGadgetText(#G_COMBO_FEN_A_CAPTURER),2,"= "))+Chr(34)+",#PB_Window_SystemMenu|#PB_Window_SizeGadget)"
    WriteStringN(#Fichier,chaine_sortie)
		
    numero_gadget=0
		
    gadgethWnd=GetNextDlgTabItem_(winhWnd,winhWnd,#False)
    buffer$=Space(100)
    GetClassName_(gadgethWnd,@buffer$,100)
    ctrlid$=Str(GetWindowLong_(winhwnd,#GWL_ID))
    cg\win=winhWnd
    cg\className$=buffer$
    cg\ctrl_id$=ctrlid$
    EnumChildWindows_(winhWnd, @EnumChildWindowProc(),@cg)
   
    chaine_sortie="Repeat"
    WriteStringN(#Fichier, chaine_sortie)
    chaine_sortie = "Until WaitWindowEvent()=#PB_Event_CloseWindow"
    WriteStringN(#Fichier, chaine_sortie)
     
    CloseFile(#fichier)
  EndIf 
EndProcedure

Procedure.l FEN0_INIT()
  Protected col.w=5, lig.w=5
  #fen_larg = 410 : #fen_haut = 100
  #text_larg = #fen_larg/3-10 : #text_haut = 16
  #combo_larg = #fen_larg-#text_larg-10 : #combo_haut = 20
 
  If OpenWindow(#FEN_0,0,0,#fen_larg,#fen_haut,"Capture Gadget v1.0",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
     TextGadget(#G_TEXT_FEN_A_CAPTURER,col,lig+2,#text_larg,#text_haut,"Choisir la fenêtre : ",#PB_Text_Right)
    ComboBoxGadget(#G_COMBO_FEN_A_CAPTURER,col+#text_larg,lig,#combo_larg,#combo_haut)
    lig+30
    TextGadget(#G_TEXT_NOM_FICHIER,col,lig+2,#text_larg,#text_haut,"Nom du fichier purebasic : ",#PB_Text_Right)
    StringGadget(#G_STRING_NOM_FICHIER,col+#text_larg,lig,#combo_larg-20,#combo_haut,"sans_nom.pb")
     ButtonGadget(#G_BUTTON_PARCOURIR,col+#text_larg+GadgetWidth(#G_STRING_NOM_FICHIER),lig,20,#combo_haut,"...")
     lig+40
     col = #fen_larg-#text_larg/1.5
    ButtonGadget(#G_BUTTON_QUITTER,col,lig,#text_larg/1.5-5,#combo_haut,"Quitter")
    col = GadgetX(#G_BUTTON_QUITTER)- #text_larg/1.5
    ButtonGadget(#G_BUTTON_EXECUTER,col,lig,#text_larg/1.5-5,#combo_haut,"Executer") 
  EndIf

  ProcedureReturn WindowID(#FEN_0)
EndProcedure

Procedure FEN0_EXEC()
  Protected event.l, evgad.l , quit.b = 0, nom_fichier.s = ""
  Protected hwnd.l, chaine.s = Space(256)
 
  ;{ auteur : dlolo
  ;; purebasic forum french : http://www.purebasic.fr/french/viewtopic.php?t=3622&start=0&postdays=0&postorder=asc&highlight=list+process
  hWnd = FindWindow_( 0, 0 )

  While hWnd <> 0
    If GetWindowLong_(hWnd, #GWL_STYLE) & #WS_VISIBLE = #WS_VISIBLE
      If GetWindowLong_(hWnd, #GWL_EXSTYLE) & #WS_EX_TOOLWINDOW <> #WS_EX_TOOLWINDOW
        GetWindowText_(hWnd,@chaine,256)       
        If chaine <> ""
          AddGadgetItem(#G_COMBO_FEN_A_CAPTURER,-1,Str(hwnd)+" = "+chaine)
        EndIf
      EndIf
    EndIf
    hWnd = GetWindow_(hWnd, #GW_HWNDNEXT)
  Wend
  ;} fin
   
  nom_fichier = GetGadgetText(#G_STRING_NOM_FICHIER)
  Repeat
    event = WaitWindowEvent()
   
    Select event
      Case #PB_Event_Gadget
        evgad = EventGadget()
        Select evgad
          Case #G_COMBO_FEN_A_CAPTURER
         
          Case #G_STRING_NOM_FICHIER
            nom_fichier = GetGadgetText(evgad)
           
          Case #G_BUTTON_PARCOURIR
            nom_fichier = SaveFileRequester("Fichier PureBasic à générer","sans_nom.pb","Texte (*.txt)|*.txt|PureBasic (*.pb)|*.pb",1)
            SetGadgetText(#G_STRING_NOM_FICHIER,nom_fichier)
           
          Case #G_BUTTON_EXECUTER
            FEN0_ExecuteCapture(nom_fichier)
           
          Case #G_BUTTON_QUITTER
            quit = 2
           
        EndSelect
   
      Case #PB_Event_CloseWindow
        quit = 1
       
    EndSelect
   
  Until quit>0
EndProcedure

If FEN0_INIT()>0
  FEN0_EXEC()
EndIf
End
Voici le PRG pilote de la calculatrice avec simulation des touches seulement

Code : Tout sélectionner

;***************************************   Pilotage de la calculatrice Windows    ************************************************
Debug "******************************** simulation touche alt **********"
;;;*************************************** Pour la calcuoatrice classique de Microsoft ******************************************************************************************
; Global NomFenetre$="Calculatrice" ; Ici tu entres le nom de la fenetre
; global nomexe$="calc.exe"         ; et le nom du PRG
;;;********************************** pour la calculatrice PLUS de Microsoft ******************************
Global NomFenetre$="Calculatrice Plus" ; Ici tu entres le nom de la fenetre
Global nomexe$="calcplus.exe"           ; et le nom du PRG

; Global PIDduPROG.l
Global hMainWnd.l
Declare PAUSE(tmp.l)
Define mhFoundWnd.l
Define sBuffer.s
Define nLength.l
Dim t_vk.c(256)
 tempo=250
; tempol=1000
Procedure Touche(Option.l)
  TEMP0=5
  pause(temp0)
  keybd_event_(Option,0,0,0) ; Simule l'appui sur la touche "?"
  pause(temp0)
  keybd_event_(Option,0,#KEYEVENTF_KEYUP,0) ; simule le relachement d'une touche "?"
  pause(temp0)
EndProcedure
Procedure Touche_ctrl(Option.l)
  TEMP0=5
  keybd_event_(#VK_CONTROL,0,0,0) ; Simule l'appui sur la touche ctrl"
  pause(temp0)
  keybd_event_(Option,0,0,0) ; Simule l'appui sur la touche "?"
  pause(temp0)
  keybd_event_(Option,0,#KEYEVENTF_KEYUP,0) ; simule le relachement d'une touche ?
  pause(temp0)
  keybd_event_(#VK_CONTROL,0,#KEYEVENTF_KEYUP,0) ; simule le relachement d'une touche CTRL
  pause(temp0)
EndProcedure
Procedure Touch_ALT(Option1.l,option2.l=0,option3=0)
  keybd_event_(#VK_LMENU,0,0,0) ; Simule l'appui sur la touche alt"
  keybd_event_(Option1,0,0,0) ; Simule l'appui sur la touche "?"
  If option2<>0
    keybd_event_(Option2,0,0,0) ; Simule l'appui sur la touche "?"
    keybd_event_(Option2,0,#KEYEVENTF_KEYUP,0) ; simule le relachement d'une touche ?
    If option3<>0
      keybd_event_(Option3,0,0,0) ; Simule l'appui sur la touche "?"
      keybd_event_(Option3,0,#KEYEVENTF_KEYUP,0) ; simule le relachement d'une touche ?
    EndIf
  EndIf
  keybd_event_(Option1,0,#KEYEVENTF_KEYUP,0) ; simule le relachement d'une touche ?
  keybd_event_(#VK_LMENU,0,#KEYEVENTF_KEYUP,0) ; simule le relachement d'une touche ALT
EndProcedure
Procedure.l cherche_whnd(NOMFENETRE$)
  Static hMainWndM,tempo.l=100
  hMainWnd=FindWindow_(0,NOMFENETRE$) ; Cherche le Handle de la fenêtre
  ; PIDduPROG=GetPidProcess(nomEXE$) ; On cherche le numéro PID qui lui est attribué au handle
  ; phandle = OpenProcess_ (#PROCESS_TERMINATE, #False, Pid) ; retrouve le handle à partir du PID
  Delay(tempo*3)
  If hMainWnd=0
    Debug "****************  Fenêtre non trouvée"
    End
  EndIf
  If hMainWnd<>hMainWndM
    Debug "Handle modifié "+_n(hMainWnd)+_n(hMainWndM)
  EndIf
  hMainWndM=hMainWnd
  ProcedureReturn hMainWnd
EndProcedure
Procedure WM_COMMANDE(hMainWnd,Num)
  R_WM_COMMANDE=SendMessage_(hMainWnd,#WM_COMMAND,num,0)
  Debug "Num commande="+Str(num)+" "+_n(hMainWnd)+_n(R_WM_COMMANDE)
EndProcedure
Procedure.s execWhnd(whnd.l,entree$)
  Static RESULT_PRECED.s
  temp0=15
  d_t.l=ElapsedMilliseconds()
;   SetForegroundWindow_(whnd)
;   SetActiveWindow_(whnd)
  SetForegroundWindow_(whnd)
  SetActiveWindow_(whnd)
  SetClipboardText("0:m")
  touche_ctrl(#VK_V)
  Delay(temp0)
  SetClipboardText(entree$)
  touche_ctrl(#VK_V)
  i=0
  Repeat
    sbuffer.s=Space(256)
    SetForegroundWindow_(whnd)
    SetActiveWindow_(whnd)
    touche_ctrl(#VK_C)
    sbuffer=Trim(GetClipboardText())
    lbuf.l=Len(sbuffer)
    i+1
  Until ((entree$<>sbuffer) And lbuf<>0)
  Debug _n(i)
  ;   Debug "*******  "+sbuffer+_n(Len(sbuffer))+_s(entree$)
  ;   touche(#VK_CONTROL); ************  toujours terminer par cette instruction car ctrl est considéreé comme enfoncée
  ProcedureReturn GetClipboardText()
EndProcedure
Procedure PAUSE(tmp.l)
  hmainWnd=cherche_whnd(NomFenetre$)
  Delay(TMP)
  SetForegroundWindow_(hmainWnd)
  SetActiveWindow_(hmainWnd)
EndProcedure
sort_run=RunProgram("C:\windows\system32\"+NomExe$,"","",#PB_Program_Hide) ; On lance le programme
Delay(tempo)
hmainWnd=cherche_whnd(NomFenetre$)
Debug " *************************  passage en mode scientifique méthode ALT *****"
touch_ALT(#VK_A,#VK_S)
; touche_ALT(#VK_A,#VK_C); passage en mode conversion sur calcplus
;  touch_ALT(#VK_A,#VK_T)  ;*passage en mode standard méthode ALT *
hMainWnd=cherche_whnd(NomFenetre$) ; Cherche le Handle de la fenêtre
; *************************
For i=0 To 10000 Step 5000
  Debug _n(i)+"!="+execWhnd(hMainWnd,":c:q"+Trim(Str(i))+"!"); +_n(hMainWnd)
Next
Debug "20000!="+execWhnd(hMainWnd,"20000!")
Debug "50000!="+execWhnd(hMainWnd,"50000!")

entre$=InputRequester("Donnez une instruction ","exemple 200 ! ","200 ! ")
hMainWnd=cherche_whnd(NOMFENETRE$)
If SetActiveWindow_(hMainWnd)
  Debug "erreur setactivewindow"
EndIf
Debug entre$+"="+execWhnd(hMainWnd,entre$)
Debug " ******************************passage en mode standard méthode ALT *****"
touch_ALT(#VK_A,#VK_T)
hMainWnd=cherche_whnd(NOMFENETRE$)
pause(3000) 
Debug " *************************  passage en mode scientifique méthode ALT *****"
; touche_ALT(#VK_A,#VK_C); passage en mode conversion sur calcplus
touch_ALT(#VK_A,#VK_S)

; entre$=InputRequester("Donnez une instruction ","exemple 200 ! ","0 ")
hMainWnd=cherche_whnd(NOMFENETRE$)
Delay(3000)
hMainWnd=cherche_whnd(NOMFENETRE$)
retour=PostMessage_(hMainWnd,#WM_CLOSE,0,0) ; ***************  Ferme la calculatrice calc.exe
If retour<>0:Debug "c'est OK":EndIf
A+
Il est fort peu probable que les mêmes causes ne produisent pas les mêmes effets.(Einstein)
Et en logique positive cela donne.
Il est très fortement probable que les mêmes causes produisent les mêmes effets.
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Pilotage d'une application externe (Ex: calculatrice MS)

Message par djes »

Ca c'est bon ! Merci :)
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: Pilotage d'une application externe (Ex: calculatrice MS)

Message par Kwai chang caine »

Super code que celui de Patrick88, super idée 8O
Splendide code PAPIPP
Merci à vous deux 8)
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Avatar de l’utilisateur
flaith
Messages : 1487
Inscription : jeu. 07/avr./2005 1:06
Localisation : Rennes
Contact :

Re: Pilotage d'une application externe (Ex: calculatrice MS)

Message par flaith »

PAPIPP a écrit : Voici le PRG pilote de la calculatrice avec simulation des touches seulement
...
A+
Salut PAPIPP, ce code ne fonctionne pas car il manque les (tableaux ?) '_n' et '_s' :?
PAPIPP
Messages : 534
Inscription : sam. 23/févr./2008 17:58

Re: Pilotage d'une application externe (Ex: calculatrice MS)

Message par PAPIPP »

Salut Flaith
Salut PAPIPP, ce code ne fonctionne pas car il manque les (tableaux ?) '_n' et '_s'
En effet voici les quelques macros qui manquent.

Code : Tout sélectionner

Macro _q_t_
  "
EndMacro

Macro _n(__n)
  _q_t_#__n#=_q_t_+Str(__n)+" "
EndMacro

Macro _s(__S)
  _q_t_#__S#=_q_t_+__S+" "
EndMacro
; ;   #PB_Byte   : La valeur est un octet (8 bits) allant de 0 à 255
; ;   #PB_Ascii  : La valeur est un octet (8 bits) allant de 0 à 255
; ;   #PB_Word   : La valeur est un word (16 bits) allant de 0 à 65536
; ;   #PB_Unicode: La valeur est un word (16 bits) allant de 0 à 65536
; ;   #PB_Long   : La valeur est un long (32 bits) allant de 0 à 4294967296
; ;   #PB_Quad   : La valeur est un quad (64 bits) allant de 0 à 18446744073709551615
Macro _f(__F,__nv=8)
  _q_t_#__F#=_q_t_+StrF(__f,__nv)+" "
EndMacro

Macro _d(__D,__nv=8)
  _q_t_#__D#=_q_t_+StrD(__D,__nv)+" "
EndMacro

Macro _Q(__Q)
  _q_t_#__Q#=_q_t_+Str(__Q)+" "
EndMacro

Macro _H(__H,__nv=#PB_Quad,_pr="$")
  _q_t_#__H#=_q_t_+_pr+Hex(__H,__nv)+" "
EndMacro

Macro _B(__B,_pr="%")
  _q_t_#__B#=_q_t_+_pr+Bin(__B)+" "
EndMacro

Macro _U(__U)
  _q_t_#__U#=_q_t_+StrU(__U)+" "
EndMacro
Il est fort peu probable que les mêmes causes ne produisent pas les mêmes effets.(Einstein)
Et en logique positive cela donne.
Il est très fortement probable que les mêmes causes produisent les mêmes effets.
Avatar de l’utilisateur
flaith
Messages : 1487
Inscription : jeu. 07/avr./2005 1:06
Localisation : Rennes
Contact :

Re: Pilotage d'une application externe (Ex: calculatrice MS)

Message par flaith »

Merci beaucoup :D
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: Pilotage d'une application externe (Ex: calculatrice MS)

Message par Kwai chang caine »

Trop cool le pilotage 8)
Sauf que je suis sous VISTA et apparement pas de "calcplus.exe".
Mais j'ai pris la bonne vieille "Calc.exe" et ça marche aussi :D

Sauf pour le passage au mode scientifique, ou il me semble qu'il y a un "MIASME" :roll:
Mais le code continue...

Merci PAPPIP 8)
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Mesa
Messages : 1126
Inscription : mer. 14/sept./2011 16:59

Re: Pilotage d'une application externe (Ex: calculatrice MS)

Message par Mesa »

Pour info, il existe un language de programmation dédié au pilotage d'application, c'est autoit.

C'est une sorte de basic et il est gratuit.

L'important c'est qu'il est livré avec une application 32b et 64b qui permet de rapatrier toutes les infos d"une fenêtre.

Par exemple, j'ai lancé un explorateur windows et l'application en question qui s'appelle "AutoIt Window Info.exe", m'indique ceci en survolalnt le listview de droite de l'explorateur :
>>>> Window <<<<
Title: Poste de travail
Class: ExploreWClass
Position: 0, 0
Size: 1024, 768
Style: 0x16CF0000
ExStyle: 0x00000100
Handle: 0x000603B0

>>>> Control <<<<
Class: SysListView32
Instance: 1
ClassnameNN: SysListView321
Name:
Advanced (Class): [CLASS:SysListView32; INSTANCE:1]
ID: 1
Text: FolderView
Position: 391, 59
Size: 625, 653
ControlClick Coords: 178, 254
Style: 0x56000348
ExStyle: 0x00000000
Handle: 0x000A0396

>>>> Mouse <<<<
Position: 573, 341
Cursor ID: 0
Color: 0xFFFFFF

>>>> StatusBar <<<<
1:
2:
3:

>>>> ToolsBar <<<<

>>>> Visible Text <<<<
10 objet(s)
FolderView


>>>> Hidden Text <<<<
On peut avoir accès aux infos de chacun des "gadget" (toolbar, ...) tout aussi simplement. Il fait la différence entre plusieurs instances d'un même application.

C'est toujours bon à prendre.

Mesa.
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: Pilotage d'une application externe (Ex: calculatrice MS)

Message par Kwai chang caine »

De temps en temps j'en entend parler de ce logiciel, je savais qu'il pilotait quelquechose, mais je pensais que c'etait qu'en mémorisant les déplacements et evenements de souris et claviers.
Un style de MACRO d'evenement comme dans EXCEL :roll:

Je ne pensais pas qu'il allait si loin 8O
Voila donc pourquoi, enfin je suppose, on parle d'un WRAPPER de sa DLL sur le US 8)
http://www.purebasic.fr/english/viewtop ... lit=autoit
Enfin....si comme dab, j'ai pas compris de travers :oops:
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Mesa
Messages : 1126
Inscription : mer. 14/sept./2011 16:59

Re: Pilotage d'une application externe (Ex: calculatrice MS)

Message par Mesa »

Oui, autoit crée un exécutable.

Un jour, j'ai créé un exe avec autoit qui prend une image préalablement mis dans le presse papier, ouvre mon logiciel de photo, crée une page blanche aux dimensions de l'image, colle l'image et ajoute un filtre pour éclaircir l'image.
Tout est automatique. :D

C'est assez marrant, on dirait qu'une souris fantôme agit toute seule, les menus s'ouvrent et se ferment tout seul, etc. 8O

Le wrapper est une bonne nouvelle.

Mesa.
Avatar de l’utilisateur
Ar-S
Messages : 9539
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Pilotage d'une application externe (Ex: calculatrice MS)

Message par Ar-S »

J'ai jamais accroché à Autoit, je m'y étais intéressé pour scripter des trucs pour WOW mais je suis resté septique et un peu dèçu par l'ergonomie de la chose.
Pour info (au cas ou tu ne le saches pas), pas de rapport avec autoit, tu peux créer un droplet sous photoshop ;) pour faire du traitement par lot sous photoshop : voir ici pour un petit tuto
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Répondre