Проблеммы со скролом
От: 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'а если не устраивает стандартный серый?
Re: Проблеммы со скролом
От: GDI Россия  
Дата: 12.03.04 16:44
Оценка:
Здравствуйте, sjman, Вы писали:
[]
S>И ещё вопросик: Как изменить цвет ScrollBar'а если не устраивает стандартный серый?

Я бы так сделал...

// Перерисовка
void CChildView::OnPaint() 
{
    CPaintDC dc(this); // device context for painting
    CRect rcClient;
    GetClientRect(&rcClient);

    CRect rect(50,50,400,400);
    dc.SetViewportOrg(0,-m_nVOffset);

    dc.FillSolidRect(&rect, 0x0000FF);
    
    dc.SetViewportOrg(0,0);
    dc.FillSolidRect(0,0,rcClient.right,20, 0xFAC0FF);
    dc.TextOut(20,1,"Ехал Грека через реку, цап за руку Греку рак! :-))");
    
}

int CChildView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CWnd::OnCreate(lpCreateStruct) == -1)
        return -1;

    // инициализация скролбара
    SCROLLINFO scrlInfo;
    scrlInfo.cbSize=sizeof(SCROLLINFO);
    scrlInfo.fMask=SIF_ALL;
    scrlInfo.nMin=0;
    scrlInfo.nMax=1000;
    scrlInfo.nPage=400;
    scrlInfo.nPos=0;
    scrlInfo.nTrackPos = 0;
    SetScrollInfo(SB_VERT, &scrlInfo);
    return 0;
}


// m_nVOffset - переменная-член класса CChildView
void CChildView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
    CRect rcClient;
    GetClientRect(&rcClient);
    rcClient.top+=20;

    // calc new y position
    int yOrig = GetScrollPos(SB_VERT);
    int nDelta=0;

    // ну тут получаем дельту
    switch (nSBCode)
    {
    case SB_TOP:
        nDelta = 0;
        break;
    case SB_BOTTOM:
        nDelta = INT_MAX;
        break;
    case SB_LINEUP:
        nDelta = -10;
        break;
    case SB_LINEDOWN:
        nDelta = 10;
        break;
    case SB_PAGEUP:
        nDelta = -100;
        break;
    case SB_PAGEDOWN:
        nDelta = 100;
        break;
    case SB_THUMBTRACK:
        nDelta = nPos-yOrig;
        break;
    }

    m_nVOffset+=nDelta;    // ставим оффсет
    SetScrollPos(SB_VERT, m_nVOffset);        // ЫуеЫскщддЗщы
    ScrollWindow(0, -nDelta, 0, &rcClient); // скрол

    CWnd::OnVScroll(nSBCode, nPos, pScrollBar);
}


А цвет я не знаю как поменять! Это вроде нельзя сделать. Можно соорудить свой скролбар... или через CScrollBar::OnPaint рисуй сам.
Re: Проблеммы со скролом
От: Zlobik Россия  
Дата: 28.02.07 17:23
Оценка:
S>И ещё вопросик: Как изменить цвет ScrollBar'а если не устраивает стандартный серый?

сколько я в своё время не возился с изменением цвета (да и вообще внешнего вида) ScrollBar'а — ничего не получилось пришлось сооружать свой...
С найбестевейшими вишезами,
Zlobik
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.