Click to See Complete Forum and Search --> : mouse button down
Mr Gung-Fu
March 13th, 2003, 06:30 AM
In my dialog based MFC app i want a slider to be in the middle, moved by a mouse drag like it does normally, but then return to the middle when the mouse button is released.
Ive had a go at a few things but my C++ aint good enuf to iron out the problems.
PaulWendt
March 13th, 2003, 06:43 AM
First of all, this is the Non Visual C++ forum. Did you know that
MFC is only developed with Visual C++? Thus, this message does
not belong here.
However, I will indulge [until it's moved]. You know the position
of the slider before it's moved, right? After it's moved, just set
its position back to what it was before. I have no idea why you'd
want to do this, though; you're basically making the control NOT
a slider by allowing it to be set to only one value.
--Paul
Mr Gung-Fu
March 13th, 2003, 07:24 AM
Ill describe what i want it to do. I am creating an analogue rewind/fastforward slider. The user holds the mouse down on the slider and drags it left/right. The further in that direction the user drags, the faster speed of rewind/fastforward. Im gonna start with it just 1 speed for rewind, 1 for fastforward.
All i am really asking is how do i set up a function that is called when the mouse button is pressed and another function that is called when the mouse button is released. Is question still in the wrong place? The MFC stuff i mentioned was just to add a bit of context to the problem.
PaulWendt
March 13th, 2003, 07:40 AM
Of course it's in the wrong place :) Each class hierarchy for GUI
components will have different methods of taking care of mouse
input. Having said that, with WIN32, every window receives a
message when an event happens. When the left mouse button
is pressed down, your window receives the WM_LBUTTONDOWN
message; when it's released, your window receives the
WM_LBUTTONUP message. With MFC, you typically use a
message map to map these messages to function calls. You
need to read the documentation to figure out how to do this.
Do a search on MSDN for WM_LBUTTONUP and "message map"
and you will probably figure it out.
--Paul
Philip Nicoletti
March 13th, 2003, 07:41 AM
Actually I had a client that wanted something similar. In my
case, basically simulating a thumbwheel with a slider control.
Here is how I did it (there are probably better ways -
my MFC use is minimal and knowledge limitted). Maybe
you can adapt it to do what you want. (at any rate, with
you move the slider windows sends WM_H_SCROLL message (or
WM_V_SCROLL if vertical). Look up OnHScroll for more info.
associate a CSliderCtrl variable with your slider control.
(in sample code below I named it : m_xTranslation_slider)
process WM_H_SCROLL for the dialog (if a horizontal slider)
add additional member variables to the dialog :
int m_xTranslation_old_position; // saved position of slider control
int m_xTranslation; // current value of variable you are tracking
Initialize everything in dialog's OnInitDialog()
int minRange = 0;
int maxRange = 100;
int avgRange = (minRange+maxRange)/2;
m_xTranslation_slider.SetRange(minRange,maxRange);
m_xTranslation_slider.SetPos( avgRange );
m_xTranslation_old_position = avgRange;
m_xTranslation = 0;
process WM_H_SCROLL for the dialog (see where I have
the TRACE() for the updated value)
void CNozzleEditorDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
if (pScrollBar->GetSafeHwnd() == m_xTranslation_slider.GetSafeHwnd())
{
int minRange , maxRange , avgRange;
m_xTranslation_slider.GetRange(minRange,maxRange);
avgRange = (minRange + maxRange)/2;
int xTranslation_new_position = m_xTranslation_slider.GetPos();
if (xTranslation_new_position != avgRange)
{
if (xTranslation_new_position == m_xTranslation_old_position)
{
m_xTranslation_old_position = avgRange;
m_xTranslation_slider.SetPos(avgRange);
}
else
{
m_xTranslation += (xTranslation_new_position - m_xTranslation_old_position);
m_xTranslation_old_position = xTranslation_new_position;
TRACE("new value for xTranslation = %d\n",m_xTranslation);
}
}
}
CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}
Mr Gung-Fu
March 13th, 2003, 10:32 AM
Thanks Philp!
Do i have permission to use this for an application im making for a university project. Its not an integral function of the app but it will be a nice touch. Have a look at it if you want here (http://www.dcs.shef.ac.uk/~u9sr/SS_progress.htm) .
Mr Gung-Fu
March 13th, 2003, 02:24 PM
1 more thing
The method that is called from the ON_HSCROLL message thingy works but when the slider is dragged to one side and held there i want a function to be called repeatedly whereas at the moment it can only be called once.
To repeatedly call the function i need to release the mouse and click and drag again OR drag mouse to another position and then back again.
Philip Nicoletti
March 13th, 2003, 03:45 PM
So basically, what you want to do is this:
As the user moves the slider, call some function
with the slider position as an argument. If the user
hold the slider at one particluar postion, you still
want to keep calling the function. Currently it does
not call the function, since WM_H_SCROLL message
is not sent when the slider is not moving/moved.
Here is one way around this. It is somehat messy, so
I imagine there is a better way to do this. Basically,
you are going to add a timer. Start the timer when the
user first moves the slider and stop the timer when
the slider goes back to the center position. In the
timer function you can call your function.
process the WM_TIMER message for the dialog
add member variable :
bool m_timerRunning; // true if timer has been started
initialize it in OnInitDialog()
m_timerRunning = false;
modify the OnHScroll() fucntion as follows:
void CDlgDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
if (pScrollBar->GetSafeHwnd() == m_xTranslation_slider.GetSafeHwnd())
{
int minRange , maxRange , avgRange;
m_xTranslation_slider.GetRange(minRange,maxRange);
avgRange = (minRange + maxRange)/2;
int xTranslation_new_position = m_xTranslation_slider.GetPos();
if (xTranslation_new_position != avgRange)
{
if (xTranslation_new_position == m_xTranslation_old_position)
{
if (m_timerRunning)
{
m_timerRunning = false;
KillTimer(1);
}
m_xTranslation_old_position = avgRange;
m_xTranslation_slider.SetPos(avgRange);
}
else
{
if (!m_timerRunning)
{
m_timerRunning = true;
SetTimer(1,250,NULL); // 250 = 0.25 seconds
}
m_xTranslation += (xTranslation_new_position - m_xTranslation_old_position);
m_xTranslation_old_position = xTranslation_new_position;
TRACE("new value for xTranslation = %d\n",m_xTranslation);
}
}
}
CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}
code for the WM_TIMER message
void CDlgDlg::OnTimer(UINT nIDEvent)
{
if (nIDEvent == 1) // 1 = first argument in the SetTimer() function
{
// do something based on m_xTranslation
}
CDialog::OnTimer(nIDEvent);
}
Mr Gung-Fu
March 13th, 2003, 04:07 PM
I already have one timer running. Can i start another? I dont want what ive programmed to do on a timer event to happen every time the rewind is pressed.
If it helps, when my rewind is pressed the other timer is always stopped (it pauses the animation).
Mr Gung-Fu
March 13th, 2003, 04:39 PM
I setup my OnTimer function so if the id is 1 it does what it did origionally did but if it is 2, the 1st number i used when i SetTimer it does what your suggesting.
And with a little fiddling of my code - it works!
Thanks.
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.