Page 1 sur 1

AJOUT DANS UN MENU

Publié : sam. 31/déc./2005 10:49
par LOULOU25

Code : Tout sélectionner

#MF_STRING = $0
#MF_ENABLED = $0
 #IDM_MYMENUITEM = 2003
 #WM_SYSCOMMAND = $112
 #GWL_WNDPROC = -4

Declare.l AddToSystemMenu(  hWND.l)
Declare.l MymenuProc(hWnd.l,msg.l,wParam.l,lparam.l)

RunProgram ("calc")

Delay(1000)


  OpenLibrary(0, "user32.dll")
  hWnd.L = WindowID() 

AddToSystemMenu(hWnd)



End 


 
Procedure  AddToSystemMenu(  hWND)
DefType.l hSystemMenu
  ; hSystemMenu = GetSystemMenu_(hwnd, False)
hsystemMenu = CallFunction(0,"GetSystemMenu",hwnd,0) 
CallFunction(0,"AppendMenuA",hSystemMenu,#MF_STRING+#MF_ENABLED, #IDM_MYMENUITEM, "My Menu ITEM")
OriginalWindowproc = CallFunction(0,"SetWindowLongA",hWnd,#GWL_WNDPROC ,@MyMenuProc() )
 ;AppemdMenu_(hSystemMenu,#MF_StRING+#MF_ENABLED, #IDM_MYMENUITEM, "My Menu ITEM")
 ;OriginalWindowProc = SetWindowLong_(hWnd,#GWL_WNDPROC,@MyMenuProc())
 EndProcedure
 

 

 
 
Procedure.l MymenuProc(hWnd.l , msg.l,wParam.l,lparam.l)
 If msg = #WM_SYSCOMMAND And WParam = #IDM_MYMENUITEM
 MessageRequester("","New menu item clicked")
 Else
CallFunction(0,"CallWindowProcA", OriginalWindowproc,Hwnd,msg,wParam, lParam)
;MyMenuProc = CallWindowProc_(OriginalWindowproc,Hwnd,msg,wParam, lParam)
EndIf 
EndProcedure
Je n arrive pas a faire tourner ce code aui est cense ajouter un nouveau choix au menu systeme de la calculatrice. quelau un pourrait-il m aider
Merci par avance

Publié : sam. 31/déc./2005 13:18
par Anonyme2
Je viens de regarder ton code.

Il est possible de modifier le menu système de la calculatrice mais je pense que subclasser simplement la calculatrice avec l'API SetWindowLong_ n'est pas possible car la calculatrice appartient à un autre process

Microsoft dit ceci :
Subclassing is allowed only within a process. An application cannot subclass a window or class that belongs to another process.

l'article de MS est ici
http://msdn.microsoft.com/library/defau ... bclas3.asp

Je me trompe peut-être car je ne suis pas un spécialiste

Dans cet article, il est expliqué 3 manières de faire, 2 avec des dll (la 1ere en modifiant la base de registre et la 2eme en utilisant les Hook) et la 3eme avec la modif des adresses mémoire, cette 3eme étant déconseillée par MS

Sinon, dans ton code,

Code : Tout sélectionner

   OriginalWindowProc = SetWindowLong_(hWnd,#GWL_WNDPROC,@MyMenuProc())
OriginalWindowProc doit être une variable globale

False est une constante et doit commencer par # (GetSystemMenu_)

il n'est pas possible de récupérer le handle de la calculatrice avec WindowID() car aucune fenêtre n'est crée et la calculatrice est un exécutable propre

Pour récupérer le handle de la calculatrice, utilises ce code

Code : Tout sélectionner

   RunProgram ("calc")
    Delay(1000)
    hWnd.L = GetForegroundWindow_()
Mais il apparement pas possible de subclasser la calculatrice facilement, SetWindowLong_ échoue et l'erreur correspond à acces refusé (c'est l'accès mémoire)

En regardant avec le débugger, on voit que ton code se ferme alors que la calculatrice reste bien affichée. J'ai donc fait un essai avec une variable globale pour ne pas fermer ton code avant de m'apercevoir de ça

voici le code qui modifie le menu système de la calculatrice mais sans rien intercepter, il ne fonctionne pas

Code : Tout sélectionner

#MF_STRING = $0
#MF_ENABLED = $0
#IDM_MYMENUITEM = 2003
; #WM_SYSCOMMAND = $112
 #GWL_WNDPROC = -4


Global OriginalWindowproc.l, Quitter_Calculatrice

Procedure.l MymenuProc(hWnd.l , msg.l, wParam.l, lparam.l)
   MyMenuProc = SetWindowLong_(hWnd.l, #GWL_WNDPROC, OriginalWindowProc)
 
 If msg = #WM_SYSCOMMAND And WParam = #IDM_MYMENUITEM
    Debug WParam
    MessageRequester("","New menu item clicked",16)
    ProcedureReturn 0
 ElseIf msg = #WM_SYSCOMMAND And WParam = #SC_CLOSE
    Quitter_Calculatrice = 1
    Debug Quitter_Calculatrice
 Else
   ProcedureReturn MyMenuProc
  EndIf
EndProcedure

Procedure  AddToSystemMenu(hWND)
   hSystemMenu.l = GetSystemMenu_(hwnd, #False)
   AppendMenu_(hSystemMenu,#MF_STRING+#MF_ENABLED, #IDM_MYMENUITEM, "My Menu ITEM")
   OriginalWindowProc = SetWindowLong_(hWnd,#GWL_WNDPROC,@MyMenuProc())
 EndProcedure
 
    OpenWindow(100, x, y, LargeurInterne, HauteurInterne, #PB_Window_Invisible, "")
    ; on initialise Quitter_Calculatrice
    Quitter_Calculatrice = 0  ; à 0 la calculatrice tourne
                              ; à 1 la calculatrice a été fermée; mis à 1 dans la procedure MymenuProc

    RunProgram ("calc")

    Delay(1000)

    hWnd.L = GetForegroundWindow_() ; pour récupérer le bon Handle

    AddToSystemMenu(hWnd)

                                     ; n'est pas fermée
       Repeat
       Until Quitter_Calculatrice = 1  ; on ne ferme pas ton prog tant que la calculatrice

End

Publié : sam. 31/déc./2005 13:26
par Anonyme2
Im me semble que Nico a posté un code sur les hook pour intercepter les messages d'autre process

Publié : sam. 31/déc./2005 18:26
par LOULOU25
Merci Denis de tes explications.
Je ne sais pas comment faire carje n ais pas les competences pour aller si loin. Que me conseille-tu
Mom probleme est de rajouter a un menu utilisateur dans un programme un choix qui lui permettra de transferer en automatique un fichier sans avoir a lancer un autre process.

Publié : dim. 01/janv./2006 11:43
par Anonyme2
Je pense qu'avec les Hook ça doit être faisable mais je n'ai pas regardé

Peut-être que Nico pourrait plus facilement t'aider que moi (ou un autre codeur)

Publié : dim. 01/janv./2006 18:04
par nico
J'ai essayé d'intégrer le code dans un hook pour pouvoir subclasser la fenêtre mais du coup le menu de la calculatrice ne répond plus!

LOULOU25,

Il faudrait que tu donnes le code source que tu as récupéré pour y voir plus clair!

Publié : dim. 01/janv./2006 18:43
par nico
Il faudrait faire un hook WM_SYSMSGFILTER, je pense!

Publié : dim. 01/janv./2006 19:03
par Anonyme2
D'après ce que j'ai lu de la doc MS, il faut je crois une dll avec le hook

Publié : dim. 01/janv./2006 22:03
par nico
Je viens de faire un test que j'avais envie de faire depuis un petit moment avec un hook dans une Dll; j'ai pu facilement envoyer un mail en arrière plan en lançant simplement Outlook!

Publié : lun. 02/janv./2006 9:52
par LOULOU25
Voici l'adresse d'un site qui traite d'un cas similaire en visual basic
http://vbnet.mvps.org/code/subclass/systemabout.htm
Bonne réception

Publié : lun. 02/janv./2006 11:21
par nico
L'exemple que tu donnes est pour un même process!

Publié : lun. 02/janv./2006 11:29
par LOULOU25
Je suis incapable de te dire ce qu'il en est car celà depasse mes compétences. Je ne sais vraiment pas comment m'y prendre

Publié : lun. 02/janv./2006 14:04
par nico
En fait je viens de me rendre copte qu'il faut faire un hook WH_GETMESSAGE pour que ça marche!

Je posterais un code plus tard! :)

Publié : lun. 02/janv./2006 14:16
par LOULOU25
nico a écrit :En fait je viens de me rendre copte qu'il faut faire un hook WH_GETMESSAGE pour que ça marche!

Je posterais un code plus tard! :)
Merci Nico c'est sympha

Publié : lun. 02/janv./2006 21:08
par nico
J'ai posté un code dans Truc et Astuce. :)