SystemParametersInfoA with SPI_GETMOUSE returns 0's - c++

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.

Related

Direct2D Drawing with DirectX11: Aligning rectangles on a display graph

I'm working on a graphical application in C++ using Direct2d (DirectX11). The application takes in sensor data and displays the input using rectangles that are placed side-by-side across the x-axis (which represents time). Each rectangle is filled with a linear gradient brush that represents multiple sensor readings at the discrete time interval displayed along the y-axis.
When a reading is acquired, the placement for the starting 'x' position of the next rectangle should be exactly where the last one finished i.e. rect1.right should be rect2.left. The start point for each rect is calculated using the pseudocode below:
//find the number of rectangles needed to represent the time scale (rects must be an integer, as we cannot display partial rectangles
int nNumXRects = fAxisLength/fTimeDivision;
//calculate the X-axis increment for each rectangle
float fXIncrement = fXAxisLineLength/(float)NumXRects;
//Get the next x position
rect2.left = rect1.right;
rect2.right = rect2.left + fXIncrement;
My problem is that the graph only appears correctly when the value of fXIncrement is exactly a whole number e.g. 3.0f. This obviously restricts the length of the X-Axis to figures that are multiples of the number of rectangles, times the length of each rectangle. This affects the area available to all the other elements of the application.
If the value of the increment is anything other that a whole number, small black lines appear between the rectangles which destroys the appearance and makes the data much harder to interpret. I realise why this is happening in principle - we cannot display a fraction of a pixel for instance, but how should this be done properly so that the rectangles will always match up exactly, regardless of the length of the axis? It would seem that Direct2D is perfect for this and should intrinsically cope with mapping fractional values to physical pixels exactly, but I don't know what the correct approach is beyond by current simplistic solution which is to keep the length of the x-axis fixed (meaning I cannot scale properly and other elements do not have enough space in the horizontal).
Any pointers in the right direction would be much appreciated!
Can't this be fixed by setting the appropriate anti alias mode when drawing the rectangles?
pRenderTarget->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);

Determine whether the mouse moved horizontally (C++)

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.

Windows mouse coordinates VS OpenGL mouse coordinates

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.

Tracking circular mouse movement in OpenGL

I am working on a simple mesh viewer implementation in C++ with basic functionality such as translation, rotation, scaling.
I'm stuck with with implementing the rotation of the object along z-axis using the mouse. What I want to implement is the following:
Click and drag the mouse vertically (almost vertical will do, as I use a simple threshold to filter slight deviations along the horizontal axis) to rotate the object along y-axis (this part is done).
Click and drag the mouse horizontally just as described above to rotate the object along x-axis (this part is done too).
For z-axis rotation, I want to detect a circular (or along an arc) mouse movement. I'm stuck with this part, and don't know how to implement this.
For the above two, i just use atan2() to determine the angle of movement. But how do I detect circular movements?
The only way to deal with this is to have a delay between the user starting to make the motion and the object rotating:
When user clicks and begins to move the mouse you need to determine if its going to become a straight line movement, or a circular one. This will require a certain amount of data to be collected before that judgement can be made.
The most extreme case would be requiring the user to make one complete circle first, then the rotation begins (in reality you could do much better than this). Just how small you are able to cut this period down to will depend on a) how precise you dictate your users actions must be, and b) how good you are with pattern recognition algorithms.
To get you started heres an outline of an extremely poor algorithm:
On user click store the x and y coordinates.
Every 1/10 of a second store the new coordinates and process_for_pattern.
in process_for_pattern you're looking for:
A period where the x coordinates and the y coordinates regularly both increase, both decrease, or one increases and one decreases. Over time if this pattern changes such that either the x or the y begins to reverse whilst the other continues as it was, then at that moment you can be fairly sure you've got a circle.
This algorithm would require the user to draw a quarter circle before it was detected, and it does not account for size, direction, or largely irregular movements.
If you really want to continue with this method you can get a much better algorithm, but you might want to reconsider your control method.
Perhaps, you should define a screen region (e.g. at window boundaries), which, when was clicked, will initiate arc movement - or use some other modifier, a button or whatever.
Then at a mouse click you capture the coordinates and center of rotation (mesh axis) in 2D screen space. This gets you a vector (mesh center, button down pos)
On every mouse move you calculate a new vector (mesh center, mouse pos) and the angle between the two vectors is the angle of rotation.
I don't think it works like that...
You could convert mouse wheel rotation to z-axis, or use quaternion camera orientation, which is able to rotate along every axis almost intuitively...
The opposite is true for quarternion camera: if one tries to rotate the mesh along a straight line, the mesh appears to rotate slightly around some other weird axis -- and to compensate that, one intuitively tries to follow some slightly curved trajectory.
It's not exactly what you want, but should come close enough.
Choose a circular region within which your movements numbered 1 and 2 work as described (in the picture this would be some region that is smaller than the red circle. However, when the user clicks outside the circular region, you save the initial click position (shown in green). This defines a point which has a certain angle relative to the x-axis of your screen (you can find this easily with some trig), and it also defines the radius of the circle on which the user is working (in red). The release of the mouse adds a second point (blue). You then find the angle this point has relative to the center of the screen and the x-axis (just like before). You then project that angle onto your circle with the radius determined by the first click. The dark red arc defines the amount of rotation of the model.
This should be enough to get you started.
That will not be a good input method, I think. Because you will always need some travel distance to discriminate between a line and a curve, which means some input delay. Here is an alternative:
Only vertical mouse having their line crossing the center of the screen are considered vertical. Same for horizontal. In other cases it's considered a rotation, and to calculate its amplitude, calculate the angle between the last mouse location and the current location relatively to the center of the screen.
Alternatively you could use the center of the selected mesh if your application works like that.
You can't detect the "circular, along an arc" mouse movement with anywhere near the precision needed for 3d model viewing. What you want is something like this: http://thetechartist.com/?p=80
You nominate an axis (x, y, or z) using either keyboard shortcuts or on-screen axis indicators that you can grab with the mouse.
This will be much more precise than trying to detect an "arc" gesture. Any "arc" recognition would necessarily involve a delay while you accumulate enough mouse samples to decide whether an arc gesture has begun or not. Gesture recognition like this is non-trivial (I've done some gesture work with the Wii-mote). Similarly, even your simple "vertical" and "horizontal" mouse movement detection will require a delay for the same reason. Any "simple threshold to filter slight deviations" will make it feel dampened and weird.
For 3d viewing you want 1:1 mouse responsiveness, and that means just explicitly nominating an axis with a shortcut key or UI etc. For x-axis rotation, just restrict it to mouse x, y-axis to mouse y if you like. For z you could similarly restrict to x or y mouse input, or just take the total 2d mouse distance travelled. It depends what feels nicest to you.
As an alternative, you could try coding up support for a 3D mouse like the 3dConnexion SpaceExplorer.

OpenCV C++ how to make dwell click?

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.