WinAPI: Trackbar scroll begin notification - c++

I have a trackbar control in my app and I want to do something when user starts scroll operation (when he clicks on the trackbar's thumb). Since WM_HSCROLL doesn't notify about such event, I was wondering how do I get to know when user starts scrolling. I'd like to avoid processing SB_THUMBTRACK request since thay would mean I'd have to process it all the time when user's scrolling, and I just want to know when he starts doing it.

Just process TB_THUMBTRACK and ignore all subsequent TB_THUMBTRACKs until you get TB_ENDTRACK. That's roughly 5-9 lines of code.
For trackbars you also should use the TB_* (trackbar) constants and not the SB_* (scrollbar) constants even if their respective values are the same (e.g. SB_ENDSCROLL == TB_ENDTRACK == 8, SB_THUMBPOSITION == TB_THUMBPOSITION == 4).

Related

Qt C++ preventing program to show error-messages when busy

Hi I have a question concerning error-messages.
I have a window with several buttons including a OK and Cancel-button. My OK-button executes a program that moves some chart series and for doing so it needs to read in lots of data from a file and shift these values. The Cancel button cancels this operation. The calculations cannot be separated into smaller portions of code.
This works well for smaller amount of data but when I use it with large sets of data the program acts as if it crashed. Nevertheless, after some time everything is back to normal, the calculation is done.
There are 2 things I don`t like:
1) When I leave the program alone the program changes the headerline of my window to ....(keine Rückmeldung) which means no response.
After the end of the calculation the text ...(keine Rückmeldung) disappears in the header and everything is back to normal.
2) When I try to press the "cancel" button in my window while running the calculation, an additional window appears:
There again, when I leave the program alone and the calculation is finished this window disappears ( as well as the (keine Rückmeldung) in the header of my window) and and everything is back to normal.
To solve problem 2 I tried to disable my "Cancel" button but this does not help. The slot which is behnid the cancel-button gets executed anyway.
My question now is: Since I don´t want the user to see these error-messages, is there a way to prevent the program of showing them?
Thank you
Consider using a QThread for expensive computation tasks. Or better, you can use other built-in multi-threading utilities such as QConcurrentRun and QFuture.
You can then easily get the state of your background function and show a loading Window, or allow the user to perform other operations in the meantime.

How can i slow down QSpinBox scrolls while holding Up/Down (Keyboard)

The scenario is the following:
When my active Widget is a QSpinBox, I can change the value by clicking or holding a click on an arrow of the box or by pressing or holding Page Up/Page Down/ ▲ / ▼ .
The problem is, that i have some hardware communications on valueChanged() which needs some milliseconds.
While i permascroll (mouse) or hold the click on a boxes arrow, this isn't a problem, because the scroll seems to be slower here (acceleration off), but when i use my keyboard (acceleration also off), the scrollspeed is much faster which causes the timing problem. The application slows down, then freezes for some seconds until the event queue is finished.
I need to allow using the keyboard input (including holding the keyboard key), so I'd like to know if there is a way to slow down key repeat rate of arrow/page up/down.
Actually I'm triggering a 200 msec oneshot timer on value changed, which passes the spinbox value on timeout. The timer will only be triggered if it's not running. That means when i change the value it will always have a 200 msec delay and the update frequency can only be 5 updates/sec or slower. It actually works, but I'd really like to improve this by reducing the key repeat rate somehow.
Ok no I see problem. Here problem is keyboard repaying character on button hold.
To overcome this without direct interaction with keyboard, I would try use event filter, observe key press events and reject some of them if then are arriving to fast.
Your device communication subsystem has two states: busy and available. When it's busy, you should schedule an update of a particular variable in your target, but don't execute it just yet. When the previous communications are done, and the subsystem is available, it should pick up any outstanding changes and propagate them.

GLFW Input States

I'm having a hard time with GLFW's input system, figuring out how to make it work the way I want it, so I've come to people with more experience for wisdom. Using GLFW 3.
There are 3 states 0 Release, 1 Press and 2 Repeat. This is exactly what I would want, only, the key state from Press to Repeat takes about a second to change. Ideally, I would want it to have a state "Press" only for 1 frame, and then change into a repeat state.
The goal: Be able to easily call functions based on what state my key is as follows:
press Tap (do once)
repeat Continuous (do every frame)
release Don't respond
LINK
Please have a look in the files on the link above, and let me know if there's another way around it. Or is the approach itself rubbish, the way I do it? Thanks guys, all feedback and help appreiated.
One way is to simply ignore the "repeat" event, and only go with the "press" and "release" events.
When you get the "press" event set a flag, and clear the flag on the "release" event. Then simply check this flag every frame.
It is very important that there is a delay between "press" and "repeat". Most human beings are incapable of pressing and releasing a key, such that your game only registers the key being pressed for exactly one frame. And the few who are capable of that cannot do so consistently, with any accuracy.
So a user will never be able to "do once". They will be doing it for multiple frames. That's generally bad.
Also, there is a conceptual difference between pressing, holding, and repeating. Holding is just what happens when you hold down the key. Repeating is a facility that is governed by the OS (which is why GLFW doesn't give you a way to set the repeat rate). Key repeating is typically meant for text input (which GLFW takes care of for you anyway via its text-based callback).
Essentially, you should ignore it. In a game situation, a key has 4 possible useful states: not pressed, was just pressed, being held down, and was just released. You can infer this from the button's previous state (which you can store) and the button's current state provided by the callback.
If all you want to do is take an action when a button "was just pressed", then you need to know that the button was not pressed in the previous frame. If the key is pressed now but not in the previous frame, take the action.

How to create a control flow? C++

First of all, sorry for the generic title, I didn't know who to write my question.
I'm in a trouble, i'm trying to create a control but I don't know how to do it. Here is what I would like to do:
I created a chronometer (just an int that increase 1 by 1) and I want to write that: If clickNumber == 1 and the chronometer is less than 144, wait until it reach this number, if it is 144, then make and action, then exactly the same, if clickNumber == 2 and the chronometer is less than 72, wait until it reach this number, if the chronometer is == 72 then make and action.
I think it might be so easy to do, but I can't see how to do it.
Thank you all
Your issue is better thought in terms of events and objects.
Let's say you have a Chronometer and it has at least three parts: Display, button and code. The display will show the value of the chronometer. The button will behave as you describe. The code is the part that manages everything.
Your chronometer code will be receiving events from at least two sources: Timer and Button. The timer is a system time that sends you message periodically (like once a second). The button will send your chronometer code an event when the user clicks on the button.
So you will need to have some static variables to hold your information.
You will need to think in terms of the event:
if event == button click
then increment click and check click count.
endif
if event == timer
then
increment chronometer value.
if chronometer value == limit, then stop the timer.
endif
The implementation of the algorithm depends on the GUI framework you are using.

Change repeat key threshold c++

I'm building a c++ tetris game (not c++ .Net). I feel my controls are weird. I want to make it so that when user presses one of the arrow keys, about 10ms of holding it down will start the repeat function windows has. It is set to about 500ms by default, and it is too laggy for my game. How can I set the speed at which it changes from the keydown to the repeat keydown? Not how many times / sec it repeats.
Thanks
*what I want to do is change the repeat delay to short
In control panel in keyboard settings there is repeat rate, how do i set this?
Typically what you would do for this is instead of reacting to the WM_CHAR message that is subject to the normal key repeat settings, you would look for WM_KEYDOWN and WM_KEYUP, and take action based on a timer that you've got running. If you set the timer to fire every 50 ms for example, then you can repeat every 50 ms and still take the first action immediately when you get the WM_KEYDOWN message.
According to MSDN, it also looks like you could use the SystemParametersInfo function, and call use SPI_SETKEYBOARDSPEED, SPI_SETKEYBOARDDELAY.
void Key_Set()
{
DWORD old = 0;
SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &old, 0);
SystemParametersInfo(SPI_SETKEYBOARDDELAY,0, &old, 0);
}