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