Scroll qui ne fonctionne pas entierement

Signaler
Messages postés
361
Date d'inscription
mardi 31 décembre 2002
Statut
Membre
Dernière intervention
19 mars 2015
-
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
-
Bonjour


J'ai une fenetre mère (hWndMainFrame), qui contient une fenetre fille (hWndScroll) avec un objet scroll à coté (hscr).

Tout se passe bien, tant que la fenetre mère ne change pas de taille (via WM_SIZE) et que je ne touche pas au scroll


j'ai un cas particulier, qui ne fait pas ce que je voudrais :

1) affichage de la fenetre principale et des fenetres filles

2) reduction de la taille de la fenetre principale

3) je met le curseur du scroll tout en bas

jusqu'ici l'affichage est correct (du moins il semble correct)


4) agrandissement de la fenetre principale par le haut de la fenetre,
jusqu'au depassement de la taille de la fenetre fille (ici 600)

et là, la fenetre fille n'est pas entierement affichée

d'ailleurs pendant l'agrandissement, le scroll semble bizarre ...


Merci de me dire, ce que j'ai oublié ou mal codé


ci-dessous la partie du code gérant le scroll:


=====================

void Update_Scroll(HWND m_hWnd, HWND hscr)

{

    // taille zone cliente

    RECT rcClient;

    GetClientRect(m_hWnd, &rcClient);

    int cyClient = rcClient.bottom - rcClient.top;

   

    int Taille_objet_y = 600;


    // si la taille de la fenetre est superieure à celle à scroller

    if(cyClient >= Taille_objet_y)

        cyClient = Taille_objet_y;


   

    //--------------------------------------------------------------------------

    // infos pour les
scrollbars                                               


    SCROLLINFO info;

    info.cbSize = sizeof(SCROLLINFO);


    // scrollbar vertical

    info.nMin    = 0;

    info.nMax    = Taille_objet_y - 2;

    info.nPage    = cyClient-1;

    info.fMask    = SIF_RANGE | SIF_PAGE;// | SIF_DISABLENOSCROLL;

    SetScrollInfo(hscr, SB_CTL, &info, TRUE);

}


void On_VScroll (HWND hWndScroll, HWND hscr, WPARAM wParam)

{

    // récupération infos sur le scrollbar

    SCROLLINFO info;

    info.cbSize = sizeof(SCROLLINFO);

    info.fMask = SIF_ALL;

    GetScrollInfo(hscr, SB_CTL, &info);

    int y = info.nPos;


    // en fonction de l'action à effectuer

    int nSBCode = LOWORD(wParam);

    switch(nSBCode)

    {

        case
SB_LINEDOWN        :
y++;           
        break;

        case SB_LINEUP   
        : y--;   
           
    break;

        case
SB_PAGEDOWN        : y +=
info.nPage;        break;

        case SB_PAGEUP   
        : y -=
info.nPage;        break;

        case
SB_THUMBTRACK        : y =
info.nTrackPos;    break;

        case
SB_THUMBPOSITION    : y = info.nPos;   
    break;

    }


    // vérif bornes

    if(y > info.nMax)

        y = info.nMax;

    if(y < info.nMin)

        y = info.nMin;


    // affectation nouvelle position, on scrolle la vue

    SetScrollPos(hscr, SB_CTL, y, TRUE);


    ScrollWindow(hWndScroll, 0, (info.nPos - GetScrollPos(hscr, SB_CTL)), NULL, NULL);

}


case WM_CREATE:

                Update_Scroll(hscr, hWndScroll);

                break;


case WM_SIZE:

                GetClientRect(hWndMainFrame, &rctMainWnd);


               
// redimensionnement de la fenetre à scroller en fonction de la taille
de la fenetre mere

       
        SetWindowPos(hWndScroll,
HWND_TOP, 5,50, rctMainWnd.right-30, rctMainWnd.bottom-60,
SWP_NOACTIVATE | SWP_NOOWNERZORDER);

                UpdateWindow(hWndScroll);


                // maj du scroll

                Update_Scroll(hscr, hWndScroll);

                On_VScroll (hWndScroll, hscr, wParam);

                break;


           case WM_VSCROLL:

               
On_VScroll (hWndScroll, hscr, wParam);

                break;

=================================

3 réponses

Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
3
Salut,

J'ai pas de réponse précise a ton problème, mais quelques commentaires:

Je pense que tu ne devrais pas utiliser ScrollWindow()
systematiquement. Dans certains cas il est utile (SB_LINEDOWN,
SB_LINEUP..) mais pas dans d'autres. De plus si tu te plante dans le
calcul de la valeur à scroller, ca affichera vraiment n'importe quoi.
Tant que tu debug ton code, je pense qu'il vaut mieux que tu utilises
InvalidateRect() pour redessiner toute la fenetre, et ainsi voir si
tout est positionné correctement. Ensuite quand ca fonctionnera, tu
pourra remettre ScrollWindow().

Le calcul de la position maximum ne me semble pas bon. Il faut prendre
en compte la valeur de nPage lors de ce calcul. C'est plutot:

nPos = nMax - (nPage - 1)
Messages postés
361
Date d'inscription
mardi 31 décembre 2002
Statut
Membre
Dernière intervention
19 mars 2015

c'est bien la fonction ScrollWindow qui me pose problème, car en la
commentant et en mettant InvalidateRect, le scrollbar se comporte
correctement et l'affichage aussi...


"Le calcul de la position maximum ne me semble pas bon. Il faut prendre
en compte la valeur de nPage lors de ce calcul. C'est plutot:

nPos = nMax - (nPage - 1)"

--> nPos, c'est la position du curseur du scroll, pas la position maximum ?!
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
3
Salut,
Dans la formule que j'ai donné, nPos c'est la position maximale de ta scrollbar.

Pour le scroll,  tu devrais plutot utiliser ScrollWindowEx(), et
commencer par traiter les cas les plus simples (SB_LINEDOWN/SB_LINEUP).


Je ferais un truc de ce genre:

- tu déclare une variable int scrollvalue = 0;

- dans le switch, pour SB_LINEDOWN tu met scrollvalue à 1, pour SB_LINEUP  à -1.

- a la fin, si scrollvalue est != 0,  tu scroll en utilisant scrollvalue, sinon tu invalidate tout.