C++ Record on mouse release - c++

I am trying to get a program to write to a text file when the left button on the mouse is released, and only released. Below is the code that I have tried. In the GUI there is a slider that the user can move back and forth to zoom in and out on a video with. I want to be able to grab just the value the user stops at. Currently it prints the starting and stopping values as well as all the values in between. I thought that getting it to print the stopping value on the mouse release would work. Currently it still just prints all the info not just on the mouse release.
if(WM_LBUTTONUP)
{
myfile1.open("testing.txt", std::ios_base::app);
myfile1 << "testing";
myfile1 << "\n";
myfile1.close();
}

Your condition is always true because WM_LBUTTONUP is a non-zero constant. You should compare a uMsg == WM_LBUTTONUP in your WindowProc callback.

Related

C++: How to return output at the cursor position?

If we take the standard "Hello world" example, I want to send the output to the current cursor position, NOT to the console window. In fact, I would like the console window to disappear.
What I want to do is basically an autocorrect function: cin >> ae; cout << รค;
Grabbing the first part works, but sending the output to the right location proves surprisingly difficult, even after reviewing countless youtube videos...

how to flush or clear GetAsyncKeyState's buffer

i'm using GetAsyncKeyState in an MFC application to check if Esc button is pressed,
but when i press on Esc button from dialog and use GetAsyncKeyState in a different dialog it returns nonzero because it's exists in the message queue.
how can i clear or flush GetAsyncKeyState's buffer or delete this message from message queue?
Thanks in advance.
The direct answer to your question would be just calling it a second time, discarding the value from the first time.
But I guess that what you really want to know is how to read the current status of the key, regardless of when you last checked. Since you wrote "returns nonzero" I believe you are not using it correctly.
You need to check for the bit with value 0x8000 because this one indicates whether it's pressed right now. The bit with the value 1 is the one which is set if the key was pressed since the last check, and that's the one tripping you over, so just ignore it and directly test for the bit with value 0x8000.
Example code:
if(GetKeyState(VK_RETURN) & 0x8000) yayReturnIsPressed();
Checking if(GetKeyState(VK_RETURN)) or if(GetKeyState(VK_RETURN) != 0 will not do what you want because it will be fulfilled if any of the bits in the return value are set.
In GetAsyncKeyState documentation you can read:
If the most significant bit is set, the key is down, and if the least significant bit is set, the key was pressed after the previous call to GetAsyncKeyState.
(emphasis mine)
so to check current state of ESC button you should only check most significant bit:
bool isEscPressed = GetAsyncKeyState(VK_ESCAPE) & 0x8000;
if you check state like that: if (GetAsyncKeyState(VK_ESCAPE)) {} then it will enter if statement even if ESC is not currently pressed.

SDL_GetRelativeMouseState strange behaviour

I have an application in SDL 2.0.3 that enters relative mouse mode before entering the main game loop. In addition, function mouse_input is called in each step:
int mdltx = 0, mdlty = 0;
void mouse_input () {
auto r = SDL_GetRelativeMouseState(&mdltx, &mdlty);
if (mdltx != 0 || mdlty != 0)
cout << "(" << mdltx << "," << mdlty << ")" << endl;
// Update mouse key presses
mpul = !!(r&SDL_BUTTON(1)) | ((!!(r&SDL_BUTTON(3)))<<1);
}
According to the documentation of SDL_GetRelativeMouseState:
(...) x and y are set to the mouse deltas since the last call to SDL_GetRelativeMouseState() or since event initialization.
I've added the output lines for debugging purposes, because the resulting effect in the application was very awkward. It turns out that each time I move the mouse (and only when I move it), the console prints values in an unreasonable range. Below is a sample from doing simple mouse movements. The affected axis seems correct (moving horizontally will set mdlty to 0 and moving vertically will set mdltx to 0), but the numbers can get much higher than the screen resolution, and all of them are positive, regardless of the direction I move the mouse.
(342,216)
(47290,0)
(23696,0)
(23730,0)
(23764,0)
(23799,0)
(71190,0)
(117970,83397)
(23491,41802)
(23457,0)
(23423,83811)
(0,41871)
(23389,208322)
(23355,82847)
(0,41320)
(46812,0)
I have been looking around the web for people having the same problem, without any success.
Also note that this application was previously made for SDL 1, relying on SDL_GetMouseState and SDL_WarpMouse, but the latter function does not seem to do anything in some platforms. I'm working on the application under an Arch Linux + LXDE installation, which seems to simply ignore the mouse warp. This is the same machine where this other strange behaviour is happening.
The question is: why is this happening and how can I fix it with compatibility in mind, while keeping the advantages of having relative mouse mode? I even wonder if it could be an issue within SDL itself.
For anyone else struggling with this problem, it might help to set:
SDL_SetHintWithPriority(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, "1", SDL_HINT_OVERRIDE);
SDL_SetRelativeMouseMode(SDL_TRUE);
This seems to give you relative mouse-output, where the center of the screen is (0,0).
However for me it doesn't currently reset the Cursor-coordinates properly, so while every frame resets this to (0,0), it jumps straight to the previous coord += movement.
This is a lot better than the alternative though, it seems.
The same code is working in a different machine, so this seems to be a bug. And it seems that some people found it too, with a broader range of misbehaviours than the one mentioned.
https://bugzilla.libsdl.org/show_bug.cgi?id=2150

Clear input command line?

I'm making an console application. It starts with a menu where if I press the key; 1. The menu changes into another menu screen. But note, without me pressing 'Enter'. This means that my 1 still remains, which is obviously bad when stepping down further in the menus.
How do I clear the input command line?
The function im using.
if(GetAsyncKeyState('1'))
{
IEventDataPtr gameState(GCC_NEW EvtData_Set_Game_State("PREGAMESTATE"));
em->VTriggerEvent(gameState);
//Enter line clearing code.
}
The function GetAsyncKeyState gives you "the current state of a key". So it will return true between the point when the keyboard driver has received the "key for 1 has been pressed" until the keyboard driver receives "key for 1 has been released".
I would seriously suggest that you use ReadConsoleInput instead if you want to get one keypress at a time.
The alternative is to use something like this:
while(GetAsyncKeyState('1'))
{
// Do nothing.
}
to wait for that key to be released.

How do I make something happen on the screen even without a key being pressed?

I am making Pacman in C++ with the Ncurses library. I am able to move Pacman with my code, but I want to move it so that pacman keeps moving even when I am not pressing any key and when I press another direction key, it changes direction. Right now, the pacman only takes one step when I press a key. Also I have to press a key 2 or 3 times before pacman moves in that direction.
if (ch==KEY_LEFT)
{
int b,row,column;
getyx(stdscr,row,column);
int h;
do // do-whileloop to move the pacman left until it hits the wall
{
column-=1;
mvprintw(row,column,">"); //print the ">" symbol
refresh();
waitf(0.1); //this pauses the game for 0.1sec
attron(COLOR_PAIR(1));
mvprintw(row,column,">");
attroff(COLOR_PAIR(1));
refresh();
waitf(0.1);
mvprintw(row,(b),"O"); //showing the open mouth of pacman
refresh();
waitf(0.1);
attron(COLOR_PAIR(1));a
mvprintw(row,column,"O");
attroff(COLOR_PAIR(1));
h = getch();
}
while(h == KEY_LEFT);
}
right = getch();
loop to move right in an if condition
up = getch();
loop to move up in an if condition
down = getch();
oop for moving down in an if condition.
The standard solution to this is the finite-state machine. The character has six or so possible states: standing, moving up, moving right, moving down, moving left, dead. Rather than a keypress directly moving the character, the keypress should change the character's state.
In such a small application, rather than implementing an incredibly flexible finite-state machine, you may use a very simple implementation as such:
enum PlayerState {
Standing,
MovingUp,
MovingRight,
MovingDown,
MovingLeft,
Dead
};
Then, inside your game loop you can add a very simple state check which then takes the appropriate action for the frame.
switch(state) {
case Standing:
break;
case MovingUp:
player.PositionY += 1;
break;
// ...
}
The last step is to hook input, which depends on your method of retrieving input. Using callbacks, an example is:
void KeyDown(Key k) {
switch(k) {
case UpArrow:
if(state != Dead)
state = MovingUp;
break;
case RightArrow:
if(state != Dead)
state = MovingRight;
// ...
}
}
You can see why in a larger project it would be important to implement a more flexible finite-state machine, but hopefully this example has given you an easy-to-understand idea.
You need an equivalent of kbhit, ie. a non-blocking getch. Which really gives the solution, set O_NONBLOCK on the input. See an example here. Once you have this, simply loop contiguously and just check for the key hit, w/o waiting on actual key press.
Function getch is blocked until some key is pressed. If you don't want to be blocked then call _kbhit before getch too make sure that there is something in input buffer.
EDIT: Take a look at ncurses functions nodelay and cbreak. They enable asynchronous input.
I suggest you take a look at the model-view-controller model, it will help you with this problems and all the other problems that you will have if you continue your program like this.
Edit: shortcut
To move your pacman continuously you will need a separate thread to control it and make it move. Take a look at pthreads for that.
If you keep only the user input in the main run loop of your program, the problem that you have to press the keys a few times will go away too (the problem here is that the processor has to be on the getch() line when you press the key, otherwise it will not be detected.
It is pretty easy
for each direction make 4 function
and inside the function,put in the other 3 direction function which get activated by kbhit.
and put a else statement in which it keeps moving forward if you do not hit a button i.e (!kbhit());
and then put all this in a loop.
If you do this for all the direction functions you should be able to get the desirable outcome.