Проблеммы со скролом
От: sjman Россия  
Дата: 12.03.04 13:32
Оценка:
Исправлено форматирование текста. — SchweinDeBurg

На CView создаю дочернее окно с помощью CreateWindow. Класс окна CMyControl — наследник CWnd. Помещаю в

CMyControl объект CScrollBar, в CMyControl::OnCreate вызываю CScrollBar::Create.
Скроллбар создаётся. Сообщения от него обрабатываю в CMyControl::OnVScroll (т.к. только вертикальный

скроллбар), но чё то не получается. Т.е. окно скролится но не правильно: если скролить вниз, при первом

нажатии часть изображения снизу остается на месте остальное двигается, при повторных нажатиях история

повторяется с учетом сдвига окна. В итоге получается окно зарисовано многократно скопированной той самой

нижней частью изображения. Ничего не понимаю.

Вот код:

/*************************** MyControl.h*************************************/

#define    OTSTUP            5
#define    ICON_SIZE        16
#define    TITLE_SIZE        45
#define    INFO_SIZE        200
#define    IP_TABLE_WIDTH        375
#define    IP_TABLE_HEIGTH        166
#define    ROW_HEIGHT        32

LRESULT CALLBACK MyWndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);

class CMyControl : public CWnd
{
public:
    CMyControl();
    static BOOL RegisterWndClass(HINSTANCE hInstance);

    ...

private:
    bool IsOpen;    // Открыто ли окно
    CScrollBar scroll;
protected:
    //{{AFX_MSG(CMyControl)

    .....

    afx_msg void OnPaint();
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
};

/********************** MyControl.cpp **********************/

#include "stdafx.h"
#include "MyControl.h"

...

BEGIN_MESSAGE_MAP(CMyControl, CWnd)
    //{{AFX_MSG_MAP(CMyControl)

    ...
    // другие сообщения
    ...

    ON_WM_PAINT()
    ON_WM_CREATE()
    ON_WM_VSCROLL()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

...

void CMyControl::OnPaint() 
{
    CPaintDC dc(this); 

// Рисуем прямоугольник размером с окно

    CRect rect;
    GetClientRect(rect);

    HBRUSH hOldBr,hBrush=CreateSolidBrush(RGB(190,211,233));
    HPEN hOldPen,hPen=CreatePen(PS_SOLID,2,RGB(46,89,133));
    hOldBr=(HBRUSH)dc.SelectObject(hBrush);
    hOldPen=(HPEN)dc.SelectObject(hPen);

    dc.SetBkColor(RGB(190,211,233));
    dc.Rectangle(rect);

    if(IsOpen)    // Если открыта дополнительная часть окна (типа "Подробнее...")
    {        // то рисуем еще линию отделяющую заголовок от нее
        dc.MoveTo(0,44);
        dc.LineTo(rect.right,44);
    }

    ....


    if(IsOpen)
    {
        DrawIpHdr(dc,rect,CurY);    // Рисование в доп. части окна.
                    // там же будет прокрутка
    }
    
    dc.SelectObject(OldFont);
    font.DeleteObject();
    dc.SelectObject(hOldBr);
    DeleteObject(hBrush);
    dc.SelectObject(hOldPen);
    DeleteObject(hPen);
    // Do not call CWnd::OnPaint() for painting messages
}


void CMyControl::DrawIpHdr(CPaintDC &dc,CRect rect,int &CurY)
{
    // здесь что-то рисуем
}

int CMyControl::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
    if (CWnd::OnCreate(lpCreateStruct) == -1)
        return -1;
    
    // TODO: Add your specialized creation code here
    CRect rect(2,45,18,244);
    scroll.Create(SBS_VERT|WS_CHILD|WS_VISIBLE,rect,this,100);

    SCROLLINFO scrlInfo;
    scrlInfo.cbSize=sizeof(SCROLLINFO);
    scrlInfo.fMask=SIF_ALL;
    scrlInfo.nMin=0;
    scrlInfo.nMax=400;
    scrlInfo.nPage=50;
    scrlInfo.nPos=0;
    scrlInfo.nTrackPos = 2;

    scroll.SetScrollInfo(&scrlInfo);

    return 0;
}

void CMyControl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
    static pos=0;
    CRect Wndrect;

    GetClientRect(Wndrect);

    SCROLLINFO info;
    pScrollBar->GetScrollInfo(&info);

    switch(nSBCode)
    {

    .......

    case SB_LINEDOWN:
        if(pos<=info.nMax-10)
        {
            pos+=10;
            pScrollBar->SetScrollPos(pos);
            ScrollWindow(0,-10,CRect(18,TITLE_SIZE+10,Wndrect.right-2,TITLE_SIZE+198));
            // CRect(...) - область прокрутки
        }
        else
        {
            int ost=pos-info.nMax;
            pos=info.nMax;
            pScrollBar->SetScrollPos(pos);
            ScrollWindow(0,ost,CRect(18,TITLE_SIZE+10,Wndrect.right-2,TITLE_SIZE+198));
            // CRect(...) - область прокрутки
        }
        break;
    case SB_LINEUP:
        if(pos>=info.nMin+10)
        {
            pos-=10;
            pScrollBar->SetScrollPos(pos);
            ScrollWindow(0,10,CRect(18,TITLE_SIZE,Wndrect.right-2,TITLE_SIZE+188));
            // CRect(...) - область прокрутки
        }
        else
        {
            int ost=pos-info.nMin;
            pos=info.nMin;
            pScrollBar->SetScrollPos(pos);
            ScrollWindow(0,ost,CRect(18,TITLE_SIZE,Wndrect.right-2,TITLE_SIZE+188));
            // CRect(...) - область прокрутки
        }
        break;
    default:;
    }
    CWnd::OnVScroll(nSBCode, nPos, pScrollBar);
}

И ещё вопросик: Как изменить цвет ScrollBar'а если не устраивает стандартный серый?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.