Tabulation dans les champs d'une fenetre

Résolu
billy5938 Messages postés 2 Date d'inscription jeudi 9 novembre 2006 Statut Membre Dernière intervention 12 août 2007 - 12 août 2007 à 00:01
billy5938 Messages postés 2 Date d'inscription jeudi 9 novembre 2006 Statut Membre Dernière intervention 12 août 2007 - 12 août 2007 à 19:36
Bonjour,

Je veux pouvoir parcourir les champs d'édition (ou même des checkBox) d'une fenetre. En utilisant la methode IsDialogMessage dans la boucle de gestion des message et en ajoutant le WS_TABSTOP sur les éléments, tout va bien si les éléments sont des fils direct de la fenetre principale.
Par commodité, je veux regrouper mes boutons et champs dans un GROUPBOX. Comme ça je fais la disposition d'un ensemble et je bouge le tout en ne changeant que les coordonnées du groupbox.  Dans ce cas la mes éléments ne sont plus fils direct de la fenetre principale mais du GROUPBOX. Et dans ce cas là la tabulation ne fonctionne plus.
Je ne vois pas quoi modifier pour faire marcher le tout. Si je vire le IsDialogMessage, j'obtiens bien le VK_TAB via un WM_COMMAND mais uniquement si je suis sur une zone de la fenetre principale. J'avais fait un subclass pour avoir ma methode de gestion de evenement sur les objets du GROUPBOX (j'avais un bouton pour ouvrir une fenetre de selection d'un fichier qui ne fonctionnait plus). Mais dans cette fonction je ne vois passer aucune WM_COMMAND avec le VK_TAB.
Si quelqu'un a une idée ou mieux directement la solution parce que ce serait un grand classique du winapi, je suis preneur

Ci-joint un code simplifier où il y a un groupbox et 4 edit, les deux 1er dans le groupbox (fils du) et les deux autres directement fils de la  fenetre principale.

Cordialement

Pour compiler sous gcc (j'utilise mingw32):
gcc -o simple.exe simple.c -mwindows

----------------------------------------------------------------------

#include <windows.h>

LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance,
                                                LPSTR lpCmdLine, int nCmdShow)
{
    HWND hwnd;
    MSG msg;
    WNDCLASS wc;

    wc.style = 0;
    wc.lpfnWndProc = MainWndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hinstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE);
    wc.lpszMenuName =  NULL;
    wc.lpszClassName = "MaWinClass";

    if(!RegisterClass(&wc)) return FALSE;

    hwnd = CreateWindow("MaWinClass", "Poblem TABSTOP", WS_DLGFRAME|WS_OVERLAPPEDWINDOW,
                                   CW_USEDEFAULT, CW_USEDEFAULT, 400, 300,
                                                   NULL, NULL, hinstance, NULL);
    if (!hwnd) return FALSE;

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    while (GetMessage(&msg, NULL, 0, 0))
    {
     if (!IsDialogMessage(hwnd, &msg))
     {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
     }
    }
    return msg.wParam;
}
/******************************************************************************/
static HWND hEdit1,hEdit2,hEdit3,hEdit4,gp1;
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        case WM_CREATE:
             gp1=CreateWindowEx(0,"BUTTON","GROUPBOX",WS_CHILD|WS_VISIBLE|BS_GROUPBOX,10,10,250,80,hwnd,NULL,0,NULL);
             hEdit1=CreateWindowEx(WS_EX_CLIENTEDGE,"EDIT",0,WS_CHILD|WS_VISIBLE|WS_GROUP|WS_TABSTOP,10,20,220,20,gp1,NULL,0,NULL);
             hEdit2=CreateWindowEx(WS_EX_CLIENTEDGE,"EDIT",0,WS_CHILD|WS_VISIBLE|WS_TABSTOP,10,50,220,20,gp1,0,0,0);
             hEdit3=CreateWindowEx(WS_EX_CLIENTEDGE,"EDIT",0,WS_CHILD|WS_VISIBLE|WS_GROUP|WS_TABSTOP,20,100,220,20,hwnd,NULL,0,NULL);
             hEdit4=CreateWindowEx(WS_EX_CLIENTEDGE,"EDIT",0,WS_CHILD|WS_VISIBLE|WS_TABSTOP,20,130,220,20,hwnd,0,0,0);

            return 0;

        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;

        default:
            return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
}
 

2 réponses

billy5938 Messages postés 2 Date d'inscription jeudi 9 novembre 2006 Statut Membre Dernière intervention 12 août 2007
12 août 2007 à 19:36
Salut,

Merci pour la proposition de gestion des fenêtres mais c'est un peu lourd à mon goût. Et puis j'ai fini par trouver la solution. Dans le GROUPBOX, à la création de cette fenêtre, il faut mettre WS_EX_CONTROLPARENT pour que le la gestion du WS_TABSTOP soit récursive dans les enfants de celle-ci.
Donc il faut changer le code précedent en:
             gp1=CreateWindowEx(WS_EX_CONTROLPARENT,"BUTTON","GROUPBOX",WS_CHILD|WS_VISIBLE|BS_GROUPBOX,10,10,250,80,hwnd,NULL,0,NULL);

et maintenant tout roule!

Merci
3
racpp Messages postés 1909 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 17
12 août 2007 à 16:57
Salut,
Normalement, les controles ayant le style WS_TABSTOP doivent avoir la même fenêtre mère. Si tu veux que certains controles se déplacent suivant ton groupbox, tu peux sous-classer ce dernier. Pendant le traitement de WM_MOVE (ou WM_WINDOWPOSCHANGED), tu repositionnes les controles que tu veux par rapport à la nouvelle position du groupbox.
0
Rejoignez-nous