I can detect a cursor movement over my window by capturing the WM_MOUSEMOVE message. This message contains x and y coordinates but what I need to figure out it whether the user tried to move the mouse horizontally or vertically. I want to ignore the vertical movement if the x-coordinate changed more significantly than y. Do I need to use some other message? Thanks!
David is right that you will likely need to keep track of the state. However, there is a function, GetMouseMovePointsEx that will give you up to 64 previous coordinates of the mouse. You will still have to have a map (or some other data structure) for storing the coordinates yourself, but that function should do a lot of the legwork for you. Then again, I'm not sure how that method will compare to a more manual method as far as deciding where the mouse started so you know what to compare to. *(see edit below)
Once you have the previous coordinates, you can compare the starting position with the latest position. If the difference is greater than some arbitrary amount (that you decide on) then execute your code.
*EDIT: Just read this in the GetMouseMovePointsEx documentation I linked above
The GetMouseMovePointsEx function searches for the point in the mouse
coordinates history. If the function finds the point, it returns the
last nBufPoints prior to and including the supplied point.
If your application supplies a time stamp, the GetMouseMovePointsEx
function will use it to differentiate between two equal points that
were recorded at different times.
An application should call this function using the mouse coordinates
received from the WM_MOUSEMOVE message and convert them to screen
coordinates.
Related
Go to the answer of the question
I'm trying to get my mouse speed, but when I call the function SystemParametersInfoA with parameter SPI_GETMOUSE it sets the target array to {0,0,0} which I think its not supposed to happen.
Example code:
int IntArr[3];
SystemParametersInfoA(SPI_GETMOUSE, 0, &IntArr, 0);
I tried changing my mouse sensitivity (from the control panel) but that didn't work either.
Does this function is supposed to return those zeros or thats my fault?
The documentation says:
Retrieves the two mouse threshold values and the mouse acceleration.
At first I did tought that these two mouse threshold values were related to my mouse cursor sensitivty.
After a deeper search in the docs for mouse_event, I found out that in the remarks section it says:
The system applies two tests to the specified relative mouse motion when applying acceleration. If the specified distance along either the x or y axis is greater than the first mouse threshold value, and the mouse acceleration level is not zero, the operating system doubles the distance. If the specified distance along either the x- or y-axis is greater than the second mouse threshold value, and the mouse acceleration level is equal to two, the operating system doubles the distance that resulted from applying the first threshold test. It is thus possible for the operating system to multiply relatively-specified mouse motion along the x- or y-axis by up to four times.
Which basically means that these 3 values that I got in the destination array IntArr wasn't anything to do with sensitivity, but rather these 2 mouse threshold values and the "Enhance pointer precission" which was either 0 or 1 indicating it turned on or off, mine was disabled thats why I got all zeros.
In order to get the mouse sensitivity you have to use SystemParametersInfoA function with the SPI_GETMOUSESPEED parameter as uiAction instead.
I have some problems with the intersection functionality in SFML when I am resizing the window.
So I do fairly know how to detect intersections or if something is clicked and so on when the window is in the predefined size.
But when resizing the window, the golbal bounds of the shapes/sprites in sfml stay exactly the same while their presentation in the window changes.
So when I now click on something it may happen that the normal SFML contains method of an object tells me that the mouse pointer is not inside, even if it seems to be like that on the screen.
The only thing I have in mind is to have a variable (e.g sf::vector2f) that stores the current change of the window compared to the original size and then not use the mouse position relative to the current window but the (with the change multiplied) projected mouse position.
But this may not be the best solution, so I wonder if I am missing something and therefore I am asking for advice, what to do here?
You can use the sf::RenderWindow::mapPixelToCoords method to find out the correct position of the mouse.
From the SFML documentation:
Convert a point from target coordinates to world coordinates.
This function finds the 2D position that matches the given pixel of
the render target. In other words, it does the inverse of what the
graphics card does, to find the initial position of a rendered pixel.
Initially, both coordinate systems (world units and target pixels)
match perfectly. But if you define a custom view or resize your render
target, this assertion is not true anymore, i.e. a point located at
(10, 50) in your render target may map to the point (150, 75) in your
2D world – if the view is translated by (140, 25).
For render-windows, this function is typically used to find which
point (or object) is located below the mouse cursor.
This version uses a custom view for calculations, see the other
overload of the function if you want to use the current view of the
render target.
How can I determine(this isn't the right term to use I know) that, for every position of mouse in a window space, it gets converted to OGL space(-1, 1). In this case, the user moves the mouse very fast, that I assume all of its previous positions are converted into OGL coordinates. What I am trying to say is that...is a common CPU fast enough to do that (to track all previous events) even if my C++ OGL coordinates converter is very computational expensive? lets say I put very time consuming loops in there? or.. very fast method(). How can I assure that no OGL coordinates are skipped out if I move the mouse fast enough?
I'm not jumping to any conclusion here or assuming something else might you think.
Edit:
My program main loop is like this(pseudocode):
void Pollevents()
{
for everyt_obj in this
{
if Not Collide()
{
Move(x, y) //
}
}
}
void MousePos()
{
mouse.pos = To_OGL_Coord2f()
}
These are separate threads to be executed (But not actually a real thread)
Suppose mouse.pos = (0, 0) then I moved the mouse fast enough to make the new mouse.pos to (10, 10). In a single execution of a loop, the mouse position changed very far from where it was before. Now, how can I tell to my program, by implementing Bresenham's line algorithm as mentioned by Christian Rau, that those values generated by that algorithm(not being tracked) have been crossed by the mouse. Will I add another loop for that to step for all those positions?
How can I assure that no OGL coordinates are skipped out if I move the
mouse fast enough?
That's not possible, since there is no way to let the OS generate mouse events for each and every point a mouse move would have crossed when tracked with theoretically infinite precision.
The only way to ensure this is to fill the missing points between the two (possibly far away) mouse positions yourself. If you just want to draw a point for each position the mosue moved over (maybe using OpenGL), draw a line instead.
If you on the other hand need those intermediary mouse positions yourself for further computations, you won't get around computing them yourself using some common line rasterization algorithm (like the Bresenham Algorithm, the school book algorithm for line rasterization). What this basically does is compute each point on a discrete grid that a line from one point to another would have crossed (similar to what your graphics card does when converting a line into discrete pixels), so this will generate each discrete mouse position your virtual mouse path has crossed (ignoring any non-linear mouse movement between measurement points).
EDIT: If you don't need a discrete line with proper equal-width characteristics a much easier way than messing with line rasterization would also be to just work with floating point positions and do a simple linear interpolation of the end points, like datenwolf writes in his comment. This will also give you a better timing precision than discrete mouse positions. But it all depends on what you actually want to do with those mouse positions (and now would be a good way to tell us).
EDIT: From your updated question it looks like you need the mouse positions at a high granularity in order to compute the collision of the mouse with some objects. In this case you don't actually need the intermediary points at all. Just take the line from the current mouse position to the previous one (represented as just a pair of points, or whatever theoretical line representation) and compute the collision of the objects with that line instead of the individual points.
I'm trying to build a program using opencv library.
I intend to make a laser pointer mouse.
so far, the program can detect laser point and move the cursor location that location in realtime.
now i want to give the program an ability to perform click and if possible a double click.
the only idea I have, is to do this by playing with the coordinate value for certain frame and subtract current frame coordinate with last frame coordinate.
my problem is...I dont know how implement it in code
should I use array to store the coordinate?? or any other solution i could use??
thanks in advance..
A click could be represented by the laser pointer disappearing and appearing near the same spot, and only if this happens within 1 second.
You could store the coordinates of the last frames in a std::vector of CvPoint and do a simple search in this vector when the laser pointer appears again. The last 30 coordinates or so should be stored, so you will always have the coordinates of that last 1 second of recording (at 30fps).
The double click is a small enhancement of the single click. For simplicity purposes, the double click could seen as 2 single clicks being detected within 2 seconds.
os:: windows xp sp3
Qt:: 4.6
I am playing with some 3D stuff and need to implement mouse moving. I tried with Qt mouseMoveEvent but found that is not good because mouseMoveEvent does not handle with every pixel when mouse is moved. I need somethig that register EVERY pixel of movement.
Searching for solution I cheked Qt online documentation && found QCursor class && its member pos().
Questions:: Does QCursor::pos() register every pixel in movement? Have somebody better idea for precise handling of camera wiew in 3d (i am not using openGL , building my engine in painter(it is for fun && hoby) ) ?
No, mouse may move several pixels at once.
If you need the midway points for something then calculate them. Calculate all points on line between two positions of mouse. It is still unclear to me why you need the points, but that should help.
This most likely does not have much to do with Qt, but with your mouse polling rate. You might want to refer to this quite informative blog post on Coding Horror.
Some time ago I had similar issue (I didn't use QT). Your system does not have that precise information.
What I did, was computing mouse position change (dx, dy) and using that information to move the camera. In many frameworks you don't have to compute (dx,dy) as you get that information with the event (for example SDL).
Alternatively you could compute position change and then interpolate positions between current and previous mouse position - then you could use those positions to move your camera.
You would have the same problem if you wanted to draw mouse movement on the screen. You can then use Bresenham's algorithm http://en.wikipedia.org/wiki/Bresenham's_line_algorithm to generate pixels between two given points
No, QCursor does not prvide that information, as it has no signal giving you this. You have to explicitly query its position and doing that in the mouseMoveEvent limits the precision again. The underlying window system just does not deliver that precision. Like the others said, just work with arbitrary wide movements or compute the intermediary points yourself.