Combinaison de deux touches

Résolu
fredsor Messages postés 198 Date d'inscription lundi 24 avril 2006 Statut Membre Dernière intervention 3 avril 2008 - 26 juin 2007 à 17:58
fredsor Messages postés 198 Date d'inscription lundi 24 avril 2006 Statut Membre Dernière intervention 3 avril 2008 - 29 juin 2007 à 16:54
Bonjour,
A l'aide de divers exemples trouvé ça et là sur ce fabuleux site, je pensais que mon code allait fonctionner, malheureusement non...
Je m'explique : je programme en Win32 pour Pocket Pc sous EVC++ et lorsque j'appuie sur TAB, j'arrive bien à passer d'un composant à l'autre (en l'occurence : boutons, editbox et listbox)
Cependant je veux pouvoir faire une tabulation inverse si l'utilisateur actionne à la fois Shift+Tab

J'ai fait des hooks qui fonctionne tres bien pour la tabulation ( et également la tabulation inverse si j'utilise que Shift par exemple)
Voici mon code pour mes editbox par exemple, help SVP, celui-ci devrait fonctionner!
// Procédure de sous-classement de l'Edit:

LRESULT CALLBACK EditProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message) 
    {
        case WM_KEYDOWN:
        {
            if(//SHIFT+F12
            (0x8000 & GetAsyncKeyState(VK_SHIFT))
            &&
            (0x8000 & GetAsyncKeyState(VK_TAB))
            )
            {
                returnTab(); // ma fonction réalisant l'operation e tabulation arriere, et qui fonctionne si par exemple je fais : wParam=VK_SHIFT seul
            }
        break;
        }
    }
}


Je ne vois pas où peut se situer le probleme
Merci d'avance!

25 réponses

SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
26 juin 2007 à 20:45
Y'a toujours les accelerators:

#define MYACCEL 1200

LRESULT __stdcall WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    ...

    case WM_COMMAND:
       switch(LOWORD(wParam)) {
       case MYACCEL:
          // Les touches SHIFT+TAB sont enfoncées
            ...
           break;
       }
       break;

       ...
}

int __stdcall WinMain (...)
{
    HACCEL haccel;
    ACCEL accel;
    ...

    accel.fVirt = FSHIFT;
    accel.key = VK_TAB;
    accel.cmd = MYACCEL;

    haccel = CreateAcceleratorTable(&accel, 1);

    while (GetMessage(&msg, NULL, 0, 0))
    {
        if(!TranslateAccelerator(msg.hwnd, haccel, &msg)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    DestroyAcceleratorTable(haccel);
    ...
}

C++ (@++)<!--
3
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
27 juin 2007 à 15:13
acc.fVirt = FSHIFT|FVIRTKEY;

C++ (@++)<!--
3
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
26 juin 2007 à 19:05
Ça donne quoi avec les hotkey ?

int __stdcall WinMain (...)
{
    ...
    RegisterHotKey(hwnd, 1001, MOD_SHIFT, VK_TAB);
    ...

    while(GetMessage(&msg, ...)) {
       ...
       if(msg.message == WM_HOTKEY) {
          if(msg.wParam == 1001) {
             // SHIFT+TAB apuyé
          }
       }
    }
...
UnregisterHotKey(hwnd, 1001);
}

J'ai pas testé mais ça devrait être ça.

C++ (@++)<!--
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
26 juin 2007 à 19:41
Arfff, tu veux seulement récupérer le message à partir de ta fenêtre. Dans ce cas, oublie les hotkeys. Les hotkeys s'applique pour tout le système.
Désolé.

C++ (@++)<!--
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
fredsor Messages postés 198 Date d'inscription lundi 24 avril 2006 Statut Membre Dernière intervention 3 avril 2008
26 juin 2007 à 19:57
Aïe je me faisait une joie pour voir ça demain matin...
SI tu as une autre idée n'hésite pas. Ou quelqu'un d'autre...
Par contre , meme si c'est une solution "systeme" comme tu dis, en quoi c'est prejudiciable si je vois que tu mets "Unregister " a la fin?

Toutefois merci de ton attention
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
26 juin 2007 à 20:25
Quand je dis que les hotkeys s'applique à tout le système, je veux dire que ta fenêtre n'a pas à être en avant plan pour recevoir le message. Peut-importe où tu seras (Word, IE, FF etc.), si ton application est lancé et que tu fais la combinaison de touche, elle recevra le message WM_HOTKEY.

C++ (@++)<!--
0
fredsor Messages postés 198 Date d'inscription lundi 24 avril 2006 Statut Membre Dernière intervention 3 avril 2008
26 juin 2007 à 20:36
D'accord je comprends. J'essaierai tout de meme pour voir
Mais si je saisis bien, alors au contraire du TAB qui ne fonctionne pas lorsque par exemple je fais autre chose donc ( la fentre de mon programme est alors inactive et en effet je dois recliqué dessu), d'apres toi cela fonctionnera tout de meme... Dommage!

J'espere qu'on va resoudre ce probleme tout de meme ^^
0
fredsor Messages postés 198 Date d'inscription lundi 24 avril 2006 Statut Membre Dernière intervention 3 avril 2008
26 juin 2007 à 20:49
Merci beaucoup je regarde ca des que possible et te tiens au courant ;)
0
fredsor Messages postés 198 Date d'inscription lundi 24 avril 2006 Statut Membre Dernière intervention 3 avril 2008
27 juin 2007 à 11:09
Re SAKingdom!
Bon alors ca m'a l'air pas mal l'accelerator, cependant j'ai un souci... Il passe dans le MYACCEL meme si Shift n'est pas pressé... :s

Voici comment j'ai appliqu" ce que tu m'a montré :
int WINAPI WinMain(    HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow)
{
    HACCEL haccel;
    ACCEL accel;
    accel.fVirt = FSHIFT;
    accel.key = VK_TAB;
    accel.cmd = MYACCEL;
    haccel = CreateAcceleratorTable(&accel, 1);   
   
    MSG msg;
    hinst=hInstance;
    MyRegisterClass(hInstance, TEXT("szWindowClass"));
    hWnd = CreateWindow(TEXT("szWindowClass"),TEXT(""),WS_VISIBLE,CW_USEDEFAULT,CW_USEDEFAULT,
    CW_USEDEFAULT,CW_USEDEFAULT, NULL, NULL,hInstance, NULL);
    if (!hWnd)
    {   
        return FALSE;
    }
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
  /*  while (GetMessage(&msg, NULL, 0, 0) > 0)
    {
        if (IsDialogMessage(hWnd, &msg) == 0)
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    } */ // j'ai remplacer cette boucle par la suivante que tu m'a donné
    while (GetMessage(&msg, NULL, 0, 0))
    {
        if(!TranslateAccelerator(msg.hwnd, haccel, &msg)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
   DestroyAcceleratorTable(haccel);
    return msg.wParam;
}

et voici par exemple toujours pour mes editbox :
LRESULT CALLBACK EditProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
/*        case WM_KEYUP:
        {
            GererKeyUp(hwnd,message,wParam,lParam); //gestion du tab, retour chariot, des touches directionnelles entre autres...
            break;
        }*/
        default:
            break;
    }
    switch(LOWORD(wParam)) {  // comme tu me l'a montré
       case MYACCEL:
            returnTab(); // gestion de la tabulation ariere
           break;
       }
   // Appeler la procédure originale:
   return CallWindowProc(OldEditProc, hwnd, message, wParam, lParam);
}

J'ai egalement le souci (qui vint peut etre du fait que le shift n'a pas l'air pris en compte), qu'il me fait le tabulation arriere et tout de suite la tabulation normale, dûe au WM_KEYUP... Dois-je réorganiser mon hook? Mais ce n'es tpas le plus important, le souci est principalement dans le fait que le shift ne me semble pas pris en compte... ( le resultat est le meme si je fais TAB ou SHIFT +TAB, en mettant en commentaires le WM_KEYUP...

Cela vient peut etre sinon de mon WinMain?
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
27 juin 2007 à 15:17
Pour ton second problème, ça donne quoi comme ça ?

LRESULT CALLBACK EditProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    if(LOWORD(wParam) = =

MYACCEL

) returnTab(); // gestion de la tabulation ariere
    else if(wParam == WM_KEYUP)

GererKeyUp(hwnd,message,wParam,lParam); //gestion du tab, retour chariot, des touches directionnelles entre autres...


   // Appeler la procédure originale:
   return CallWindowProc(OldEditProc, hwnd, message, wParam, lParam);
}





C++ (@++)<!--
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
27 juin 2007 à 15:23
Oups:
LRESULT CALLBACK EditProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message) {
    case WM_COMMAND:
       if(LOWORD(wParam) == MYACCEL) returnTab();
       break;

    case WM_KEYUP:
      
GererKeyUp(hwnd,message,wParam,lParam);
       break;

    }

    return CallWindowProc(OldEditProc, hwnd, message, wParam, lParam);
}

C++ (@++)<!--
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
27 juin 2007 à 15:32
Ah non, ça fera la même chose. Orf décidément aujourd'hui, je suis vraiment trop fatigué pour programmer.

Je vais chercher un peu.

C++ (@++)<!--
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
27 juin 2007 à 15:38
Bon, il y aurait peut-être une solution:

int i = 0; // Variable globale

LRESULT CALLBACK EditProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message) {
    case WM_COMMAND:
       if(LOWORD(wParam) == MYACCEL) {
            
i = 1;

            returnTab();
       }
       break;

    case WM_KEYUP:
       if(!i)
GererKeyUp(hwnd,message,wParam,lParam);
       else i = 0;
       break;

    }

    return CallWindowProc(OldEditProc, hwnd, message, wParam, lParam);
}

C++ (@++)<!--
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
27 juin 2007 à 15:42
Bon décidément.

case WM_KEYUP:
       if(wParam == VK_TAB) if(!i)
GererKeyUp(hwnd,message,wParam,lParam); else i = 0;
       break;

    }

C++ (@++)<!--
0
fredsor Messages postés 198 Date d'inscription lundi 24 avril 2006 Statut Membre Dernière intervention 3 avril 2008
27 juin 2007 à 16:14
Oui désolé pour le deuxieme probleme, j'y ai pensé juste apres mon poste, et avait égaleement testé l'usage d'un booleen ( j'ai maintenant réutilisé ta methode qui fonctionne aussi)
Cependant pour le problème initial, maitenant il ne fe fait que des tabulations, avec sous sans Shift... Faudrait qu'on trouve le juste milieu
Pour résumer avec  :
acc.fVirt = FSHIFT|FVIRTKEY; -> ne fait que le tab...
acc.fVirt = FSHIFT; -> ne fait que le retour arriere, cest a dire l'accelerateur...

On est pas loin j'en suis sur
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
27 juin 2007 à 16:36
Ceci ne fonctionne pas ?

int i = 0; // Variable globale

LRESULT CALLBACK EditProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message) {
    case WM_COMMAND:
       if(LOWORD(wParam) == MYACCEL) {
            
i = 1;

            returnTab();
       }
       break;

    case WM_KEYUP:
       if(wParam == VK_TAB) {
            if(!i)
GererKeyUp(hwnd,message,wParam,lParam);
            else i = 0;
       }
       break;

    }

    return CallWindowProc(OldEditProc, hwnd, message, wParam, lParam);
}

C++ (@++)<!--
0
fredsor Messages postés 198 Date d'inscription lundi 24 avril 2006 Statut Membre Dernière intervention 3 avril 2008
27 juin 2007 à 16:38
A noter que si je mets comme parametres :
    accel.fVirt = FVIRTKEY|FSHIFT;
    accel.key = VK_CAPITAL;
    accel.cmd = MYACCEL;
Cela fonctionne ( si TAB -> tabulation ; si SHIFT+CAPSLOCK -> tabulation arriere )

Donc le probleme vient plus du VK_TAB maintenant, qui, meme avec SHIFT+TAB, me fait une tabulation avant...
Vous avez dis bizarre??
0
fredsor Messages postés 198 Date d'inscription lundi 24 avril 2006 Statut Membre Dernière intervention 3 avril 2008
27 juin 2007 à 17:15
Oui comme je te l'ai dis ca fonctionne ;-)
Je viens de voir autre chose : si j'ouvre le clavier interne a mon simulateur pocket pc, alors SHift +Tab fonctionne bien, et tab dans l'autre sens aussi ^^
Mais j'aimerais tout de meme que cela fonctionne sur mon clavier Pc egalement, l'application devant etre aussi utilisable via le simulateur...
Je pense qu'on chauffe là!!
0
cs_magma Messages postés 198 Date d'inscription vendredi 4 avril 2003 Statut Membre Dernière intervention 18 mars 2011 1
28 juin 2007 à 10:39
Le style WS_TABSTOP appliqué à tes contrôle ne suffit t'il pas ?
0
fredsor Messages postés 198 Date d'inscription lundi 24 avril 2006 Statut Membre Dernière intervention 3 avril 2008
28 juin 2007 à 10:45
Eh non magma, ce serait trop simple, meme si j'aurais preferé ;-)

Je suis obligé de tout géré "à la main" , (meme gerer l'etat
BM_SETSTATE à TRUE pour les boutons pour voir qu'ils ont le focus ^^)

WS_TABSTOP ne fait rien chez moi, je rappelle que je suis sous evc++ en C win32
0
Rejoignez-nous