Combinaison de deux touches [Résolu]

Signaler
Messages postés
198
Date d'inscription
lundi 24 avril 2006
Statut
Membre
Dernière intervention
3 avril 2008
-
Messages postés
198
Date d'inscription
lundi 24 avril 2006
Statut
Membre
Dernière intervention
3 avril 2008
-
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

Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
12
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++ (@++)<!--
Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
12
acc.fVirt = FSHIFT|FVIRTKEY;

C++ (@++)<!--
Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
12
Ç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++ (@++)<!--
Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
12
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++ (@++)<!--
Messages postés
198
Date d'inscription
lundi 24 avril 2006
Statut
Membre
Dernière intervention
3 avril 2008

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
Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
12
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++ (@++)<!--
Messages postés
198
Date d'inscription
lundi 24 avril 2006
Statut
Membre
Dernière intervention
3 avril 2008

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 ^^
Messages postés
198
Date d'inscription
lundi 24 avril 2006
Statut
Membre
Dernière intervention
3 avril 2008

Merci beaucoup je regarde ca des que possible et te tiens au courant ;)
Messages postés
198
Date d'inscription
lundi 24 avril 2006
Statut
Membre
Dernière intervention
3 avril 2008

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?
Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
12
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++ (@++)<!--
Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
12
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++ (@++)<!--
Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
12
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++ (@++)<!--
Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
12
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++ (@++)<!--
Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
12
Bon décidément.

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

    }

C++ (@++)<!--
Messages postés
198
Date d'inscription
lundi 24 avril 2006
Statut
Membre
Dernière intervention
3 avril 2008

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
Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
12
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++ (@++)<!--
Messages postés
198
Date d'inscription
lundi 24 avril 2006
Statut
Membre
Dernière intervention
3 avril 2008

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??
Messages postés
198
Date d'inscription
lundi 24 avril 2006
Statut
Membre
Dernière intervention
3 avril 2008

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à!!
Messages postés
198
Date d'inscription
vendredi 4 avril 2003
Statut
Membre
Dernière intervention
18 mars 2011
1
Le style WS_TABSTOP appliqué à tes contrôle ne suffit t'il pas ?
Messages postés
198
Date d'inscription
lundi 24 avril 2006
Statut
Membre
Dernière intervention
3 avril 2008

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