utiliser un Hook dans un programme wxWidgets

utiliser un Hook dans un programme wxWidgets - C++ - Programmation

Marsh Posté le 18-07-2006 à 21:03:44    

Salut, voilà j'aimerais utiliser un hook sans dll dans mon programme en wxwidgets. Probleme c'est que je ne connais pas des masses le win32 :/
Je me suis inspiré de ce qu'avait fais Harko une fois, et que j'ai gardé sous le coude (depuis un an  [:chacal_one333] )
Je souhaite intercepter le clic droit sur la barre de titre pour pouvoir rajouter des item au menu systeme. Voila le code, mais le probleme c'est que ça plante grave chez moi, un message d'erreur de memoire read, et puis plus d'explorer et plus rien...

Code :
  1. #include <windows.h>
  2. static HHOOK m_HookCreatePopUp = NULL;
  3. static HHOOK m_HookOnClicMenu = NULL;
  4. static CWPSTRUCT cwp;
  5. static BOOL menuCreated = FALSE;
  6. static HWND clientHWND = NULL;
  7. enum
  8. {
  9.     ID_SUBMENU_BUREAU=5000,
  10.     ID_MENU_BUREAU1,
  11.     ID_MENU_BUREAU2,
  12.     ID_MENU_BUREAU3,
  13.     ID_MENU_BUREAU4
  14. };
  15. // CallBack interception et création de menu systeme
  16. __declspec(dllexport) LRESULT CALLBACK HookCreatePopUp(int nCode, WPARAM wParam, LPARAM lParam)
  17. {
  18. if (nCode == HC_ACTION)
  19. {
  20.  CWPSTRUCT *cwp = (CWPSTRUCT*)lParam;
  21.  clientHWND = cwp->hwnd;
  22.  if((cwp->message)==WM_INITMENUPOPUP)
  23.  {
  24.      if (HIWORD((HMENU)(cwp->lParam)) == 1)
  25.   {
  26.    if (!menuCreated)
  27.    {
  28.     HMENU menu = GetSystemMenu(cwp->hwnd, FALSE);
  29.     AppendMenu(menu, MF_STRING,ID_SUBMENU_BUREAU, "test" );
  30.     HMENU submenu = CreatePopupMenu();
  31.     AppendMenu(submenu,  MF_STRING, ID_MENU_BUREAU1, "Bureau 1" );
  32.     AppendMenu(submenu,  MF_STRING, ID_MENU_BUREAU2, "Bureau 2" );
  33.     AppendMenu(submenu,  MF_STRING, ID_MENU_BUREAU3, "Bureau 3" );
  34.     AppendMenu(submenu,  MF_STRING, ID_MENU_BUREAU4, "Bureau 4" );
  35.     AppendMenu(menu,MF_SEPARATOR,NULL,NULL);
  36.     AppendMenu(menu, MF_STRING|MF_POPUP,(UINT)submenu, "Déplacer vers" );
  37.     menuCreated=true;
  38.    }
  39.   }
  40.  }
  41. }
  42. return(CallNextHookEx(m_HookCreatePopUp, nCode, wParam, lParam));
  43. }
  44. // CallBack clic de menu systeme
  45. __declspec(dllexport) LRESULT CALLBACK HookOnClicMenu(int nCode, WPARAM wParam, LPARAM lParam)
  46. {
  47. if (nCode == HC_ACTION)
  48. {
  49.  MSG *msg = (MSG*)lParam;
  50.  if((msg->message)==WM_SYSCOMMAND)
  51.  {
  52.      if ((msg->wParam) == ID_MENU_BUREAU1)
  53.      {
  54.    MessageBox(NULL, "Déplacement vers le bureau 1!\n", "rafix message", MB_OK);
  55.   }
  56.   else if ((msg->wParam) == ID_MENU_BUREAU2)
  57.             {
  58.                 MessageBox(NULL, "Déplacement vers le bureau 2!\n", "rafix message", MB_OK);
  59.             }
  60.             else if ((msg->wParam) == ID_MENU_BUREAU3)
  61.   {
  62.    MessageBox(NULL, "Déplacement vers le bureau 3!\n", "rafix message", MB_OK);
  63.             }
  64.             else if ((msg->wParam) == ID_MENU_BUREAU4)
  65.   {
  66.    MessageBox(NULL, "Déplacement vers le bureau 4!\n", "rafix message", MB_OK);
  67.   }
  68.  }
  69. }
  70. return(CallNextHookEx(m_HookOnClicMenu, nCode, wParam, lParam));
  71. }
  72. bool Hook(HWND hwnd)
  73. {
  74. m_HookCreatePopUp = SetWindowsHookEx(WH_CALLWNDPROC, HookCreatePopUp,GetModuleHandle(NULL),NULL);
  75. m_HookOnClicMenu = SetWindowsHookEx(WH_GETMESSAGE, HookOnClicMenu,GetModuleHandle(NULL),NULL);
  76. if ((m_HookCreatePopUp != NULL )&&(m_HookOnClicMenu != NULL))
  77.  return true;
  78. return false;
  79. }
  80. void UnHook()
  81. {
  82. if (menuCreated)
  83. {
  84.  menuCreated = false;
  85.  GetSystemMenu(clientHWND, true);
  86. }
  87. UnhookWindowsHookEx(m_HookCreatePopUp);
  88. UnhookWindowsHookEx(m_HookOnClicMenu);
  89. }

Si vous avez des suggestions pour m'aider je suis preneur  :jap:
 
EDIT: dans le callback HookOnClicMenu je peux utiliser un switch case mais j'avais la flemme, copié collé inside


Message édité par neg'gwada le 19-07-2006 à 21:07:37

---------------
--- WinSplit Revolution ---
Reply

Marsh Posté le 18-07-2006 à 21:03:44   

Reply

Marsh Posté le 19-07-2006 à 21:10:14    

up
personne n'a une idée?


---------------
--- WinSplit Revolution ---
Reply

Marsh Posté le 19-07-2006 à 21:48:16    

tu pourrais poster l'ensemble de ton code, histoire que je teste ? :whistle:
(big flemmard inside)


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 19-07-2006 à 23:33:38    

pas de probleme.... alors je pose le cadre vite fait :o
c'est un soft de bureaux virtuel que je souhaite réaliser, un peut à la linux le hook est là pour (finalité) déplacer les fenetres vers les bureaux désirés.
Le CODE SOURCE est un code réalisé sous code block, mais ça c'est un detail, mais surtout utilise wxWidgets. Je précise juste que l'installation du hook intervient lorsque je clic droit sur le tray et que je fais aller sur le bureaux n°1, la flemme de me mettre une fenetre avec un bouton me demandant si je veut installer le hook :o
désinstallation du hook, clic droit sur le systeme tray -> quitter l'application.
Merci d'avance harko si tu peux m'apporter une aide :jap:


Message édité par neg'gwada le 19-07-2006 à 23:34:14

---------------
--- WinSplit Revolution ---
Reply

Marsh Posté le 20-07-2006 à 09:43:39    

bon alors quelques soucis [:el g]
- t'as installé wxWidgets à partir du devpack, ou alors from scratch ?
- tu linkes avec quelle librairie de wxWidgets ?
 
désolé hein, mais je connais pas du tout wxWidgets [:el g]


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 20-07-2006 à 13:30:47    

je te up tout mon dossier de la librairie compilée à ma sauce, j'utilise uniquement les statics. Si tu utilises code blocks, les options de compilations sont configurée pour que le dossier wx263 se trouve dans c:\
wxWidgets est une librairie très simple tu vas très vite comprendre le mécanisme, surtout (il me semble) que tu connais MFC donc t'inquiete c'est 100 fois plus simple et mieux fichu.
Je rappel que je cherche à installer les hooks sans passer par des dll, j'ai troué quelques topic sur google qui expliquaient cela. Moi j'obtiens un magnifique plantage du systeme :/


---------------
--- WinSplit Revolution ---
Reply

Marsh Posté le 20-07-2006 à 13:55:58    

bon ayé, ça marche (ou plutot non, ça marche pas, ça plante effectivement d'un fort beau gabarit, et j'emmene meme l'explorer avec moi [:petrus75])
par contre, tu dis que  

Citation :


Je rappel que je cherche à installer les hooks sans passer par des dll, j'ai troué quelques topic sur google qui expliquaient cela.


ton but est bien de rajouter une entrée au menu système de n'importe quelle fenêtre pour la placer sur le bureau de ton choix ? si c'est le cas, alors tu devras obligatoirement passer par une dll étant donné que tu devras accéder à l'espace d'adressage de n'importe quelle application, ce que seule une dll permet. (un hook global passe obligatoirement par une dll)
je regarde ton code, mais n'espère pas faire autrement qu'en passant par une dll sauf si tu es amateur de violation d'accés mémoire en tout genre


Message édité par Harkonnen le 20-07-2006 à 13:58:22

---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 20-07-2006 à 14:04:24    

c'est effectivement ça que je souhaite faire :/
en revenche si tu me dis qu'il faut passer par une dll, je ne vois pas comment faire pour donner des instruction à mon programme wxWidgets à partir de la dll puisqu'il faut compiler séparement  [:pingouino]


---------------
--- WinSplit Revolution ---
Reply

Marsh Posté le 20-07-2006 à 14:22:09    

si si, ça je l'ai déja fait :D
regarde ce soft : http://harko.free.fr/soft/euroconv.zip, il utilise un hook global stocké dans une dll, et la fenêtre qui affiche la conversion est stockée dans la dll. c'est du MFC mais on s'en fout
je me souviens plus de ce que j'avais fait, je regarderais ce soir


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 22-07-2006 à 00:34:35    

tain j'ai essayé de créer la dll et tout mais le hook ne s'install pas, car à aucun moment je fais appel à DllMain où je pourrait récuperer le HINSTANCE :/  
donc lors de l'appel de SetWindowsHookEx mon HINSTANCE vaut NULL ce qui fait que le hok ne s'install pas.
si tu as une idée, car là c'est plutot un domaine où je ne mets pas les pied habituellement. J'ai refait le tout dans un workspace histoire que ce soit plus clair.


Message édité par neg'gwada le 22-07-2006 à 00:34:52

---------------
--- WinSplit Revolution ---
Reply

Marsh Posté le 22-07-2006 à 00:34:35   

Reply

Marsh Posté le 22-07-2006 à 00:35:33    

jme mets dessus ce wk end, avec la chaleur je vais me calfeutrer :D


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 22-07-2006 à 00:36:26    

lol pas de pro ;)
bon vais dodo ++


---------------
--- WinSplit Revolution ---
Reply

Marsh Posté le 23-07-2006 à 00:18:35    

j'ai trouvééééé  [:_astrid]  enfin presque :/
en fait pour qu'il rentre dans DllMain, il fallait que je le déclare comme ça:

Code :
  1. extern "C" bool APIENTRY DllMain(...)


donc là le hook s'install sans probleme. Il y a quant meme des p'tits soucis avec le hook, c'est que l'ors de la desinstallation du hook, mon nouveau menu reste encore avec le item menu "déplacer vers", et la le nouveaux menu ne se créé pa sur toutes les fenetres, il y a comme qui durait de l'alléatoire dans ça  [:pingouino]
Bref n'ayant plus l'esprit tres clair je vais aller dodo en esperant que demain je finisse pas trouver la solution.


---------------
--- WinSplit Revolution ---
Reply

Marsh Posté le 24-07-2006 à 08:58:06    

alors bon, j'ai fait quelques tests et ben.... ça fait comme toi [:pingouino]
le hook s'installe bien, mais ne se désinstalle pas du tout !
par contre, il se créé bien sur toutes les fenetres chez moi ! tu peux me poster ton projet actuel, j'ai quelques heures à tuer au taf aujourd'hui :D


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 24-07-2006 à 11:22:51    

j'ai up à nouveau le projet, en fait j'ai l'impression que le probleme de la desinstallation viendrai du fait qu'on ne restitut le menu le systemmenu qu'à la derniere fenetre mofiée (ie) clientHWND, mais ce qui est louche c'est que meme cette sur la derniere fenetre modifiée, je ne retrouve pas le menu reseté.

Code :
  1. DLL_EXPORT bool UnHook()
  2. {
  3. if (menuCreated)
  4. {
  5.  menuCreated = false;
  6.  GetSystemMenu(clientHWND, true);
  7. }
  8. if(UnhookWindowsHookEx(m_HookCreatePopUp)&&UnhookWindowsHookEx(m_HookOnClicMenu))
  9. {
  10.     return true;
  11. }
  12. return false;
  13. }

Deuxiemement, en fait mon nouveau popup menu se créé bien sur toute les fenetres, mais le probleme c'est que je dois clic deux fois droit sur la titlebar pour que mon nouveau menu apparaisse :/


---------------
--- WinSplit Revolution ---
Reply

Marsh Posté le 27-07-2006 à 08:42:02    

bon apres des p'tites modifications j'ai quant meme 2 bugs dans le code:
1 - Il faut que je clic ou moins deux fois droit su la titlebar avant qu'apparaisse le MenuSysteme modifié par le Hook.
2 - Je n'arrive pas à restaurer le MenuSystem à l'originale

Code :
  1. #include <windows.h>
  2. #ifdef BUILD_DLL
  3.     #define DLL_EXPORT __declspec(dllexport)
  4. #else
  5.     #define DLL_EXPORT
  6. #endif
  7. static HHOOK m_HookCreatePopUp = NULL;
  8. static HHOOK m_HookOnClicMenu = NULL;
  9. static CWPSTRUCT *cwp;
  10. static HINSTANCE m_hinst=NULL;
  11. enum
  12. {
  13.     ID_SUBMENU_BUREAU=5000,
  14.     ID_MENU_BUREAU1,
  15.     ID_MENU_BUREAU2,
  16.     ID_MENU_BUREAU3,
  17.     ID_MENU_BUREAU4
  18. };
  19. // CallBack interception et création de menu systeme
  20. LRESULT CALLBACK HookCreatePopUp(int nCode, WPARAM wParam, LPARAM lParam)
  21. {
  22. if (nCode == HC_ACTION)
  23. {
  24.  cwp=reinterpret_cast<CWPSTRUCT*>(lParam);
  25.  if((cwp->message)==WM_INITMENUPOPUP)
  26.  {
  27.      if (HIWORD((HMENU)(cwp->lParam)) == 1)
  28.   {
  29.        GetSystemMenu(cwp->hwnd,true);
  30.     HMENU menu = GetSystemMenu(cwp->hwnd,false);
  31.     HMENU submenu = CreatePopupMenu();
  32.     AppendMenu(submenu,MF_STRING,ID_MENU_BUREAU1,"Bureau 1" );
  33.     AppendMenu(submenu,MF_STRING,ID_MENU_BUREAU2,"Bureau 2" );
  34.     AppendMenu(submenu,MF_STRING,ID_MENU_BUREAU3,"Bureau 3" );
  35.     AppendMenu(submenu,MF_STRING,ID_MENU_BUREAU4,"Bureau 4" );
  36.     AppendMenu(menu,MF_SEPARATOR,0,0);
  37.     AppendMenu(menu, MF_STRING|MF_POPUP,(UINT)submenu, "Déplacer vers" );
  38.   }
  39.  }
  40. }
  41. return(CallNextHookEx(m_HookCreatePopUp, nCode, wParam, lParam));
  42. }
  43. // CallBack clic de menu systeme
  44. LRESULT CALLBACK HookOnClicMenu(int nCode, WPARAM wParam, LPARAM lParam)
  45. {
  46. if (nCode == HC_ACTION)
  47. {
  48.  MSG *msg = reinterpret_cast<MSG*>(lParam);
  49.  if((msg->message)==WM_SYSCOMMAND)
  50.  {
  51.      if ((msg->wParam) == ID_MENU_BUREAU1)
  52.      {
  53.    MessageBox(NULL, "Déplacement vers le bureau 1!", "message", MB_OK);
  54.   }
  55.   else if ((msg->wParam) == ID_MENU_BUREAU2)
  56.             {
  57.                 MessageBox(NULL, "Déplacement vers le bureau 2!", "message", MB_OK);
  58.             }
  59.             else if ((msg->wParam) == ID_MENU_BUREAU3)
  60.   {
  61.    MessageBox(NULL, "Déplacement vers le bureau 3!", "message", MB_OK);
  62.             }
  63.             else if ((msg->wParam) == ID_MENU_BUREAU4)
  64.   {
  65.    MessageBox(NULL, "Déplacement vers le bureau 4!", "message", MB_OK);
  66.   }
  67.  }
  68. }
  69. return(CallNextHookEx(m_HookOnClicMenu, nCode, wParam, lParam));
  70. }
  71. DLL_EXPORT bool Hook(HWND hwnd)
  72. {
  73.     if(m_hinst==NULL)
  74.     {
  75.      MessageBox(NULL,"m_hinst=NULL","",0);
  76.     }
  77. m_HookCreatePopUp = SetWindowsHookEx(WH_CALLWNDPROC,(HOOKPROC)HookCreatePopUp,m_hinst,0);
  78. m_HookOnClicMenu = SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)HookOnClicMenu,m_hinst,0);
  79. if ((m_HookCreatePopUp != NULL )&&(m_HookOnClicMenu != NULL))
  80.  return true;
  81. return false;
  82. }
  83. DLL_EXPORT bool UnHook()
  84. {
  85. if (cwp!=NULL)
  86. {
  87.  GetSystemMenu(cwp->hwnd, true);
  88. }
  89. if(UnhookWindowsHookEx(m_HookCreatePopUp)&&UnhookWindowsHookEx(m_HookOnClicMenu))
  90. {
  91.     return true;
  92. }
  93. return false;
  94. }
  95. DLL_EXPORT void VireMenu()
  96. {
  97.     //Resaurer le menu cwp->hwnd à l'originale
  98.     GetSystemMenu(cwp->hwnd,true);
  99. }
  100. extern "C" bool APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
  101. {
  102.     m_hinst=hinstDLL;
  103.     switch (fdwReason)
  104.     {
  105.         case DLL_PROCESS_ATTACH:
  106.             // return FALSE to fail DLL load
  107.             break;
  108.         case DLL_PROCESS_DETACH:
  109.             // detach from process
  110.             break;
  111.         case DLL_THREAD_ATTACH:
  112.             // attach to thread
  113.             break;
  114.         case DLL_THREAD_DETACH:
  115.             // detach from thread
  116.             break;
  117.     }
  118.     return true; // succesful
  119. }

s'il y a des idées  :jap:


---------------
--- WinSplit Revolution ---
Reply

Marsh Posté le 07-08-2006 à 14:48:15    

UP


---------------
--- WinSplit Revolution ---
Reply

Marsh Posté le 07-08-2006 à 14:49:15    

merde, je croyais que c'était soldé ce topic :D


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 07-08-2006 à 14:51:27    

ben j'étais parti à Dublin une semaine donc j'ai pas touché au probleme, mais ils sont toujours là ie:
1 - Il faut que je clic ou moins deux fois droit su la titlebar avant qu'apparaisse le MenuSysteme modifié par le Hook.
2 - Je n'arrive pas à restaurer le MenuSystem à l'originale (GetSystemMenu avec true)
je vois vraiment pas d'où ça vient :/


Message édité par neg'gwada le 07-08-2006 à 14:51:51

---------------
--- WinSplit Revolution ---
Reply

Marsh Posté le 07-08-2006 à 17:37:44    

question, lorsque je fais  
menu = GetSystemMenu(cwp->hwnd,false);
est ce que je récupere un nouveau SystemMenu ou bien c'est a chaque fois la meme antité?


---------------
--- WinSplit Revolution ---
Reply

Marsh Posté le 08-08-2006 à 23:54:55    

Bon j'ai un piti peu avancé, pour le reset du menu system ça merde car je ne sais pour quelle raison cwp->hwnd change 2 fois :/ en gros à chaque clic droit sur une titlebar il rentre deux fois dans HookCreatePopUp et me donne 2 hwnd differents. Bref en faisant un p'ti test à l'arrache j'ai pu voir qu'en ayant le bon hwnd la fonction viremenu marche bien, et me restaure mon menu à l'origine. Par la suite ce sera un faux probleme car lorsque je vais quitter le programme je vais boucler sur toute les fenetres existantes et je vais faire un GetSystemMenu(hwnd,true) pour reseter tout les menus.
 
Par contre pour le premier probleme je ne vois vraiment pas comment le regler  :sweat:


---------------
--- WinSplit Revolution ---
Reply

Marsh Posté le 09-08-2006 à 13:47:48    

Le premier probleme, il existe dans d'autres softs (un truc pour mettre les fenetres toujours devant que j'utilise). Par contre il me semble que le soft de gestion de bureau virtuels cité il y a eu dans blabla ( http://virt-dimension.sourceforge.net/ ) n'a pas le problème (ou alors j'ai pas fait gaffe...). Vu qu'il est open source, tu pourrais mater comment ils font  :)

Reply

Marsh Posté le 11-08-2006 à 12:13:46    

merci pour le lien  :jap:  
j'ai effectivement matter ce qu'ils font, mais c'est pas présenté de la meme maniere. j'ai testé le binaire et et ça marche du premier coup eux :/ je vais encore chercher comment faire pour moi ça marche directement mais je commence à perdre espoire  :sweat:


---------------
--- WinSplit Revolution ---
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed