I need to clear any mouse clicks which has happened before the end of an animation.Only mouse clicks afterwards have to be considered.
I tried enabling my mouse function after the animation,but any clicks that happened during the animation was considered.
To my understanding there is a buffer where mouseclicks are stored and during any mouse callback , it takes the co-ordinates and any other info of the first click stored in that buffer.so i need to know how to clear this.
I used fflush(stdin) but it doesnt clear keyboard or the mouse buffer.
Am using windowsxp and programming in visualsudio2008 in c language.i also use glut.h
i also use glut.h
Then you can't. If you're doing an animation, it's up to you to process (or choose not to process) any messages.
You should not be animating something by looping within your display method. Instead, you should set up a timer callback or something that will call glutPostRedisplay that will constantly call your drawing method. During this time, you should ignore any messages if you don't want to process them.
Related
I have a problem handling GLFW poll events. As far as I know, all user input events are handled via callbacks or via constantly checking keyboard / mouse states. The latter is not so efficient an can even result in missing some input (e. g. when button pressed and then released between checking state). What is more, some events like window resizing cannot be handled without callbacks.
So, the problem is that whenever user starts resizing window (presses mouse button but doesn't move mouse), the app seems to freeze. This is, assuming resize callback is enabled and defined validly (even when copied right from GLFW API). And the problem is not that window doesn't redraw. Redraw on callback can be done with creating and calling own render() function in callback function.
The actual problem is that even when I handle resize event properly and redraw on callback, there is still some lag. This lag is after mouse press on decorated window border and when mouse is not moving. Here's a demonstration (button click is highlighted green):
Sorry for messed up GIF. All callbacks listed in GLFW API are enabled and handled (window-, input-, joystick- and monitor-callbacks) and redraw is called in each one. It seems that I'm missing some of the callbacks or GLFW just works like that.
According to this answer, this can't be done without threading:
That only works when the user moves the mouse while holding - just holding left-click on the resize window part still stalls. To fix that, you need to render in a separate thread in addition to this. (No, you can't do that without threading. Sorry, this is how GLFW works, no one except them can change it.)
So, the questions are:
How can I fix this issue without threading? If I can't, I guess I can emulate resizing with different cursors shapes and resizing zones or smth like that...
If this is still impossible to solve in GLFW, do other GLFW alternatives have this issue?
Are there any problems with GLFW similar to this one?
GLFW is not at fault here. It's how the operating system handles certain user input events like mouse down on the decorator resize handles of a window or moving the whole window.
See this answer for a more elaborate detail: Win32: My Application freezes while the user resizes the window
GLFW uses the standard Windows PeekMessage -> TranslateMessage/DispatchMessage loop which you will find in any GUI Windows application. This will get invoked when you call glfwPollEvents() and it processes all Window event messages that the OS has accumulated so far for all windows in this process. After all messages so far have been processed, the call to glfwPollEvents() will return and will allow your own window/game loop to continue.
What happens is that once the user clicks down the window decoration's resize handles, effectively the call to glfwPollEvents() will block within the OS itself in order for the OS / window-manager to intercept the mouse and keyboard messages to do its window resizing/reshaping thing.
I'm afraid that even though Windows will inform the process about the start of a window resize or move action (after which the OS will have control of the window message processing) and GLFW already handling these events internally, right now GLFW will not notify the client application about this. It would be possible though for GLFW to provide an appropriate event callback to the application, so that the application can start a timer or thread only for as long as the window resize/move action happens (as is also mentioned in the linked other Stackoverflow answer).
So, the only thing that you can do in order to keep rendering while the user holds onto the resize handles or while the user moves the window around, is to render in a separate thread.
I wrote an application that detects all active Windows and puts them into a list.
Is there a way to simulate a mouseclick on a spot on the screen relative to the Windows location without actually moving the cursor?
I don't have access to the buttons handle that is supposed to be clicked, only to the handle of the window
Is there a way to simulate a mouseclick on a spot on the screen relative to the Windows location without actually moving the cursor?
To answer your specific question - NO. Mouse clicks can only be directed where the mouse cursor actually resides at the time of the click. The correct way to simulate mouse input is to use SendInput() (or mouse_event() on older systems). But those functions inject simulated events into the same input queue that the actual mouse driver posts to, so they will have a physical effect on the mouse cursor - ie move it around the screen, etc.
How do I simulate input without SendInput?
SendInput operates at the bottom level of the input stack. It is just a backdoor into the same input mechanism that the keyboard and mouse drivers use to tell the window manager that the user has generated input. The SendInput function doesn't know what will happen to the input. That is handled by much higher levels of the window manager, like the components which hit-test mouse input to see which window the message should initially be delivered to.
When something gets added to a queue, it takes time for it to come out the front of the queue
When you call SendInput, you're putting input packets into the system hardware input queue. (Note: Not the official term. That's just what I'm calling it today.) This is the same input queue that the hardware device driver stack uses when physical devices report events.
The message goes into the hardware input queue, where the Raw Input Thread picks them up. The Raw Input Thread runs at high priority, so it's probably going to pick it up really quickly, but on a multi-core machine, your code can keep running while the second core runs the Raw Input Thread. And the Raw Input thread has some stuff it needs to do once it dequeues the event. If there are low-level input hooks, it has to call each of those hooks to see if any of them want to reject the input. (And those hooks can take who-knows-how-long to decide.) Only after all the low-level hooks sign off on the input is the Raw Input Thread allowed to modify the input state and cause GetAsyncKeyState to report that the key is down.
The only real way to do what you are asking for is to find the HWND of the UI control that is located at the desired screen coordinates. Then you can either:
send WM_LBUTTONDOWN and WM_LBUTTONUP messages directly to it. Or, in the case of a standard Win32 button control, send a single BM_CLICK message instead.
use the AccessibleObjectFromWindow() function of the UI Automation API to access the control's IAccessible interface, and then call its accDoDefaultAction() method, which for a button will click it.
That being said, ...
I don't have access to the buttons handle that is supposed to be clicked.
You can access anything that has an HWND. Have a look at WindowFromPoint(), for instance. You can use it to find the HWND of the button that occupies the desired screen coordinates (with caveats, of course: WindowFromPoint, ChildWindowFromPoint, RealChildWindowFromPoint, when will it all end?).
I searched, but most posts are just telling me what I already have, so below is basically my code right now:
DIKeyboard->Acquire();
DIMouse->Acquire();
DIMouse->GetDeviceState(sizeof(DIMOUSESTATE), &mouseCurrState);
DIKeyboard->GetDeviceState(sizeof(keyboardState),(LPVOID)&keyboardState);
MousePos.x += mouseCurrState.lX;
MousePos.y += mouseCurrState.lY;
Any post telling me how to get absolute position just says to use those last two lines. But my program is windowed, and the mouse can start anywhere on the screen.
i.e. If my mouse happens to be in the centre of my screen, that becomes position 0,0. I basically just want the top left of my window (not my screen) to be my 0,0 mouse coordinates, but am having a hard time finding anything relevant.
Thanks for any help! :)
Following the discussion in the comments, you'll have to decide which method works best for you. Unfortunately, having never worked with DirectInput, I do not know the ins-and-outs of it.
However, Window Messages work best for RTS-style controls, where a cursor is drawn to screen. This is due to the fact that this respects user settings, such as mouse acceleration and mouse speed, whereas DirectInput only uses the driver settings (so not the control panel settings). The user will expect the mouse to feel the same, especially in windowed mode.
DirectInput works better for FPS-style controls, when there is no cursor drawn, as window messages give you only the cursor coordinates, and not offset values. This means that once you are at the edge of the screen, window messages will no longer allow you to detect the mouse being moved further (actually, I am not 100% sure on this, so if someone could verify, please feel free to comment).
For keyboard, I would definitely suggest window messages, because DirectInput offers no advantages, and WM input is easier to use, and quite powerful (the WM_KEYDOWN messages contains a lot of useful data), and it'll allow you (via TranslateMessage) to get good text input, adjusted to locale, etc.).
Solving your problem with DirectInput:
You could probably use GetCursorPos followed by ScreenToClient to initialise your MousePos structure. I'm guessing you'll need to redo this every time you lose mouse input and reacquire it.
Hybrid solution (for RTS like controls):
It might be possible to use a hybrid solution for the mouse if you desire RTS-like controls. If this is the case, I suggest, though I have not tested this, to use WM for the movement of the mouse, which avoids the need for workaround mentioned above, and only use DirectInput to detect additional mouse buttons.
Now one thing I think you should do in such a hybrid approach is not directly use the button when you detect it via DirectInput, but rather post a custom application message to your own message queue (using PostMessage and WM_APP) with the relevant information. I suggest this because using WM you do not get the real-time state of the mouse & keyboard, but rather the state at the time of the message. Posting a message that the button was pressed allows you to handle the extra buttons in the same state-dependent manner (I don't know how noticeable this 'lag' effect is). It also makes the entire input handling very uniform, as every bit of input with this enters as a window message.
Hi this is my first post on stack overflow.
I am using visual studio 2006 with mfc to build a snake game.Im trying to make it so when you press an arrow (left) the snake goes the direction of that arrow (left) until the snakes dies(hits a wall,himself) or the player presses another button.
Now I need some help with going from a function to OnDraw without deleting the stuff on the screen.
Also i want to know, how to make it so that when the program is in a middle of a function that is going call another function and at a point before the other function is called you press a button,the function continues till the moment that the other function is called but does not call the function instead it goes to OnKeyDown?
OnDraw is required to redraw the whole window because that window might have just been uncovered, or un-minimized. If you want to ignore that basic Windows requirement then just make yourself a DrawMore function and use CClientDC to get a DC to use to draw more.
Your other question implies an incorrect design. Do something in response to a message, then return to MFC so it can get keys, mouse, etc. messages. Your program has to be message-driven. To keep things moving along even when there is no keystroke you can use a timer (SetTimer, handle WM_TIMER messages).
At the moment I simply use the WM_MOUSEMOVE message, but it limits the mouse movement to the maximum resolution. So what's the best way of capturing the mouse with Win32 (on a OpenGl window)? I don't want to use freeglut or any extra library.
For games and realtime DirectInput is very suitable, it's moderately hard to use.
That is not core win32 api, the winapi way of getting the input is either GetCursorPos/SetCursorPos driven by your own update loop, so you query and reset with your own frequency.
Or SetCapture and then upon WM_MOUSEMOVE you call SetCursorPos.
The point of setting the cursor pos is to give room for movement so you can get the delta, the amount the cursor moved since the last update and then put it back the cursor into the center of your window.
If you want to be able to capture mouse events after the mouse has existed the window, then you might want to look into the SetCapture function
If your problem is that you want to make a FPS game and you want your character to be able to spin in a continuous motion, then you want to set the mouse position to the center of the window after each mouse move event and handle input based on the difference between the position of the cursor when the mouse move event is fired and the center of the screen. To set the position of the mouse you can use the SetCursorPos function.
Your best bets are to either use DirectInput (which can be a bit of a pain to set up) or RawInput.
There is a fairly comprehensive example available in the Using RawInput page (See example 2).