Problem z kontrolką i przesłaniem wartości do edit control

0

VS 2005 (C++), MFC, dialog based app, ASCII

Czesc. Dodałem do dialogu 2 kontrolki (edit control oraz slider control) przyporządkowałem im zmienne tak jak w kodzie. Komentarzami w stylu //*** zaznaczyłem kod, który wprowadziłem ręcznie. Ten przykład ma za zadanie spowodować wysłanie wartości położenia slider'a do pola edit control, przy każdym przesunięciu suwaka.

Robiąc to w VC++6 działa, lecz w VS2005 projekt kompiluje się jedynie nie ma reakcji ze strony funkcji OnHScroll() (wg mnie).

Czy ktoś mógłby mi pomóc? Może nastąpiły jakieś zmiany v.6 - v.2005, przez które to wszystko.

Oto kod:

// ExoSliderDlg.cpp : implementation file
//

#include "stdafx.h"
#include "ExoSlider.h"
#include "ExoSliderDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// CExoSliderDlg dialog

CExoSliderDlg::CExoSliderDlg(CWnd* pParent /*=NULL*/)
    : CDialog(CExoSliderDlg::IDD, pParent)
    , m_SliderValue(_T(""))
{
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CExoSliderDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_SLIDER, m_Slider);
    DDX_Text(pDX, IDC_SLIDER_VALUE, m_SliderValue);
}

BEGIN_MESSAGE_MAP(CExoSliderDlg, CDialog)
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

// CExoSliderDlg message handlers

BOOL CExoSliderDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    // Set the icon for this dialog.  The framework does this automatically
    //  when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE);         // Set big icon
    SetIcon(m_hIcon, FALSE);        // Set small icon

    //**************************************************************** TUTAJ WPROWADZILEM KOD
m_Slider.SetRangeMin(1, false);
m_Slider.SetRangeMax(100, false);
m_SliderValue = "1";
UpdateData(FALSE);
//*********************************************************************** DOTAD
    return TRUE;  // return TRUE  unless you set the focus to a control
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CExoSliderDlg::OnPaint()
{
    if (IsIconic())
    {
        CPaintDC dc(this); // device context for painting

        SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

        // Center icon in client rectangle
        int cxIcon = GetSystemMetrics(SM_CXICON);
        int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(&rect);
        int x = (rect.Width() - cxIcon + 1) / 2;
        int y = (rect.Height() - cyIcon + 1) / 2;

        // Draw the icon
        dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
        CDialog::OnPaint();
    }
}

// The system calls this function to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CExoSliderDlg::OnQueryDragIcon()
{
    return static_cast<HCURSOR>(m_hIcon);
}

//******************************************************************************* NAPISALEM TA FUNKCJE
void CExoSliderDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
    // TODO: Add your message handler code here and/or call default

            if(nSBCode == SB_THUMBPOSITION) {
                m_SliderValue.Format("%ld", nPos);
            UpdateData(false);
            }

            else {
                CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
            }

            CDialog::OnHScroll(nSBCode, nPos, pScrollBar);

}

a to plik .h:

// ExoSliderDlg.h : header file
//

#pragma once
#include "afxcmn.h"

// CExoSliderDlg dialog
class CExoSliderDlg : public CDialog
{
// Construction
public:
    CExoSliderDlg(CWnd* pParent = NULL);    // standard constructor

// Dialog Data
    enum { IDD = IDD_EXOSLIDER_DIALOG };

    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

// Implementation
protected:
    HICON m_hIcon;

    // Generated message map functions
    virtual BOOL OnInitDialog();
    afx_msg void OnPaint();
    afx_msg HCURSOR OnQueryDragIcon();
    //***************************************************************** DODALEM TA LINIJKE
afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);

    DECLARE_MESSAGE_MAP()
public:
    CSliderCtrl m_Slider;
public:
    CString m_SliderValue;
};

w razie co zródła , tzn caly projekt jest tutaj. http://www.box.net/shared/eihgb1f15k

0

BEGIN_MESSAGE_MAP(CExoSliderDlg, CDialog)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
Dodaj swoje OnHScroll

0

Gdzie i co dokładnie mam dodać?. Próbowałem dodać samą deklarację, potem całą definicję, wcześniej jedynie onHScroll() .. wywala błędy składniowe w OnInitDialog...
tak proste ze az za trudne dla mnie:P

0

Nie widzisz analogii ? :/

BEGIN_MESSAGE_MAP(CExoSliderDlg, CDialog)
        ON_WM_PAINT()
        ON_WM_QUERYDRAGICON()
        ON_H_SCROLL()
        //}}AFX_MSG_MAP
END_MESSAGE_MAP()

Btw, tak zerknąłem do helpa i CDialog nie ma metody OnHScrol, jedynie CWnd i nie jest ona wirtualna więc dlatego trzeba dodać handler (jak wyżej), oraz zamiast CDialog::OnHScrol daj CWnd::OnHScrol.

0

analogie widzialem choc nie zastosowalem podkreslnikow <wstyd>

error C3861: 'ON_H_SCROLL': identifier not found
potem pojawiaja sie wykinające wg mnei błedy:
error C2143: syntax error : missing '}' before '{'
error C2065: 'GetThisMessageMap' : undeclared identifier
itp

ale spoko. popatrzyłem trochę po plikach (poszukalem referencji do onHScroll) i znazazłem
#define ON_WM_HSCROLL()
dodałem to zamiast tego co mi poleciłeś i DZIAŁA :) Dziękuję

mógłbyś mi przybliżyć co zrobić aby pasek przesyłał wartość nie tylko gdy dokładnie na niego nacisnę i przesunę ale także gdy nacisnę obok niego, na sliderze czyli poziomym pasku (tak jakbym chciał przesunąć o pewien zakres ) bo slider skacze co pewien zakres wtedy. mam nadzieje, że wiesz o co mi chodzi.
Interesuje mnie jeszcze rakcja na klawisze strzałek... to samo. Wartość w polu edit się nie zmienia. Coś polecisz?

działa także bez zmiany na CWnd::OnHScroll. lecz jak mowisz metody cdialog takiej nie ma wiec zostawie CWnd
a tak poza tym to zdziwiłem się, że jakiś moder wy__słał do kosza mój post i ciekawe jak on powrócił? dzięki Twojej odpowiedzi?

0

No tak, zjadło mi się WM :p
Co do pytania - na razie korzystasz z wariantu SB_THUMBPOSITION:

if(nSBCode == SB_THUMBPOSITION)
Wywal ten warunek to śledzona będzie każda zmiana. Niestety przy pozostałych wariantach parametr nPos nie wskaże ci pozycji paska. Sprawdź jego pozycję metodą GetScrollPos.
Poczytaj też http://msdn.microsoft.com/en-us/library/e14hhbe6.aspx

0
//te problemy, któe niżej opisałem i w kodzie chyba rozwiązałem, ale jak amsz jakieś uwagi to chętnie. chciałbym abyś odniósł się do treści ostatniego kodu i pytania pod nim

warianty SB_THUMBPOSITION: oraz SB_THUMBTRACK rozumiem reszty niestety nie bardzo.
Czy SB_LINELEFT i LINERIGHT to reakcja na naciśnięcie strzałek? powiedzmy, że coś zadziałało jednak przy puszczeniu przycisku do okienka wpisywana jest wartość "0".

CWnd::GetScrollPos(SB_VERT) zwraca mi ciągle 0 (sprawdziłem to warunkiem). Slider zmieniłem na vertical bo tak będzie pracował w wynikowej app.
Więc po jakiejkolwiek akcji na sliderze wyrzuca 0 (chociaż gdy przytrzymuje i przesuwam to pokazuje wartości pośrednie (czyli THUMBTRACK sam w sobie działa)) 0 pojawia się w okienku gdy puszczam suwak.
Rozumiem, że GetScrollPos mogę zapisać do zmiennej, którą potem prześlę do edit tak jak do tej pory:
m_SliderValue.Format("%ld", nazwa_zmiennej);
UpdateData(false);

moja funkcja:

void CExoSliderDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
    // TODO: Add your message handler code here and/or call default

    UpdateData();
    int CurPos = m_Slider.GetScrollPos(SB_VERT);

    // Determine the new position of scroll box.
    switch (nSBCode)
    {
    case SB_LEFT:      // Scroll to far left.
        CurPos = 200;
        break;

    case SB_RIGHT:      // Scroll to far right.
        CurPos = 550;
        break;

    case SB_ENDSCROLL:   // End scroll.
        break;

    case SB_LINELEFT:      // Scroll left.
        if (CurPos > 200)
            CurPos--;
        break;

    case SB_LINERIGHT:   // Scroll right.
        if (CurPos < 550)
            CurPos++;
        break;

    case SB_PAGELEFT:    // Scroll one page left.
        {
            // Get the page size. 
            SCROLLINFO   info;
            m_Slider.GetScrollInfo(SB_VERT, &info, SIF_ALL);

            if (CurPos > 200)
                CurPos = max(200, CurPos - (int) info.nPage);
        }
        break;

    case SB_PAGERIGHT:      // Scroll one page right
        {
            // Get the page size. 
            SCROLLINFO   info;
            m_Slider.GetScrollInfo(SB_VERT, &info, SIF_ALL);

            if (CurPos < 550)
                CurPos = min(550, CurPos + (int) info.nPage);
        }
        break;

    case SB_THUMBPOSITION: // Scroll to absolute position. nPos is the position
        CurPos = nPos;      // of the scroll box at the end of the drag operation.
        break;

    case SB_THUMBTRACK:   // Drag scroll box to specified position. nPos is the
        CurPos = nPos;     // position that the scroll box has been dragged to.
        break;
    }

    // Set the new position of the thumb (scroll box).
    m_Slider.SetScrollPos(SB_VERT, CurPos);

    //CString szPosition;

    //szPosition.Format("%d", CurPos);
    //SetDlgItemText(IDC_POSITION, szPosition);

    m_SliderValue.Format("%ld", CurPos);
    UpdateData(FALSE);

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

}

troche tracę siły : )

ale jednak coś dałem radę......

void CExoSliderDlg::OnVScroll(UINT nSBCode, UINT nPos, 
                  CScrollBar* pScrollBar) 
{

    int CurPos = m_Slider.GetPos() -1 ;  //-1 jest nie wazny

    if(nSBCode == SB_THUMBTRACK) 
    {
             //pusto
    }
    else
    {

m_SliderValue.Format("%ld", CurPos);

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

    UpdateData(FALSE);

        }

}

Teraz jedynie chciałbym umiżliwić tej funkcji skok do określonego miejsca automatycznie a nie o jakąś wartość. To znaczy gdy naciskam poza suwakiem, ale na linii Slidera to powinien od razu suwak przestawić się w te miejsce a nie skokowo, powoli. Coś zasugerujesz?
ps. Get ScrollPos działa super chyba ze ScrollBarem a ze Sliderem GetPos. Ale mogę się mylić.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0