ProgressBar lag when setting position with PBM_SETPOS [duplicate] - c++

This question already has answers here:
Windows 7 Aero Theme Progress Bar Bug?
(7 answers)
TProgressBar never fills up all the way - seems to be updating too fast? [duplicate]
(1 answer)
Closed 8 years ago.
I have a simple C++/MFC dialog that has a progress bar control in it. I set its position with the PBM_SETPOS message, or MFC's:
//CProgressCtrl myCtrl;
myCtrl.SetPos(position);
It works fine, except when I need this position to grow fast, it seems to lag behind.
Is there any way to remove this lag?
PS. I tried my app on older version of Windows (with classic visual styles) and this lag is not present there.

The lag is by design when visual styles are enabled to provide a smoother animated experience to the user. This is a little documented but well-known issue. You cannot remove the lag, but you can work around it. The lag only happens when increasing the position but not when decreasing it. Call SetPos(position+1) followed by SetPos(position), and the bar will jump immediately. The tricky part comes at the end. When you want to set the position to the max value, you have to first increase the max value +1, then set the desired position +1, then set the real position, then finally restore the original max value. That will allow the progressbar to fill the entire bar.
int lower, upper;
myCtrl.GetRange(lower, upper);
if (position >= upper)
{
myCtrl.SetRange(lower, upper+1);
myCtrl.SetPos(upper+1);
myCtrl.SetPos(upper);
myCtrl.SetRange(lower, upper);
}
else
{
myCtrl.SetPos(position+1);
myCtrl.SetPos(position);
}

Related

QSlider change the number of increments/decrements when using the mouse wheel

I have the following slider that currently goes from 1 to 2 in 12 steps on mouse wheel and keyboard arrows, what I want to make it do is to it takes 24 steps to go from 2 to 24?
QSlider *slider_speed = new QSlider;
slider_speed->setOrientation(Qt::Horizontal);
slider_speed->setTickPosition(QSlider::TicksAbove);
slider_speed->setRange(-12, 12);
slider_speed->setSingleStep(1);
slider_speed->setPageStep(4);
slider_speed->setTickInterval(12);
Ok. Before I do anything I should have checked the source code better :)
To change the steps I just had to change to range and tick interval to 24. And single step to 1. What confused me was a text label in the source code which would have shown a value better than 2.00 which messed me up since wasn't paying attention that that value was set my another function.

Borland c++ console functions

I'm studing now and I got this homework / tasks to do:
1) If you press the CTRL + L key, all numeric symbols should change the color.
2) If you press the CTRL + S key, you will get the length of the word, left from the cursor.
I found this function int bioskey(int cmd);
So now I can check if the key is pressed, but how to change the color only of numeric symbols, or read words from console to get their length ?
Some of us still remember the MS-DOS (let it rest in peace or pieces...)
if you are really in MS-DOS then you can not expect that the content of the console would be changed in colors for only specific areas. You need to do that your self. The problem is we do not know anything about your project background so we do not know what and how yours stuff is represented,rendered/outputed/inputed etc...
I assume EGA/VGA BIOS text mode is used so you can exploit direct access to the VRAM. So you need to set pointer to the address B800:0000 and handle it as array where each character on screen has 2 BYTEs. one is color attribute and the other is ASCII code (not sure in which order anymore)...
So for already rendered stuff you just:
loop through whole screen
usually 80x25x2 Bytes
test each ASCII for alpha numeric value
so ASCII code >= '0' and code<='9' for numbers or add all the stuff you are considering as alphanumeric like code>' ' and code<='9'.
change colors for selected characters
just by changing the attribute byte.
When you put it together for numbers it will look like this:
char far *scr=(char far*)0x0B0000000;
int x,y,a;
for (a=0,y=0;y<25;y++)
for (x=0;x<80;x++,a+=2)
if ((scr[a+0]>='0')&&((scr[a+0]<='9'))
{
scr[a+1]=7; //attribute with the different color here
}
if it does not work than try swap scr[a+0] and scr[a+1]. If an exception occur then you are not in MS-DOS and you do not have access to VRAM. In that case use DOS-BOX or driver that allows access to memory like dllportio ...
For more info see some more or less related QA's:
Display an array of color in C
What is the best way to move an object on the screen?
If you got problem with the CTRL+Key detection not sure if in-build function in TC++ allows CTRL (was too long ago) then you can exploit BIOS or even hook up the keyboard ISR. See the second link where ISR for keyboard handler is there present... You can port it to C++ or google there must be a lot of examples out there especially TP7.0 (which is pascal but easily portable to TC++)

Jumping to a single frame in Node created in Cocos Studio

I have a Node named "Fruit" which contains 4 single frames for each fruit. It also contains a shadow, which should be the same for all fruits. I'm creating this node like this:
auto newFruit = CSLoader::createNode("Fruit.csb");
auto fruitAction = CSLoader::createTimeline("Fruit.csb");
newFruit->runAction(fruitAction);
Now when I'm creating this fruit I want to set a random frame:
fruitAction->gotoFrameAndPause(r + 1);
r is from 0 to 3.
However it doesn't work. It doesn't change frame at all. When I run debugging I can see correct frame number.
So I've tried different solution. I've made 4 1-frame animations named "a1", "a2", "a3" and "a4".
Then:
fruitAction->play("a" + to_str(r + 1), false);
Now I'm getting sometimes good sometimes not. Giving constant r continuously is giving me different results.
Only solution I've found is to make all animation 2-frames long (with 1 offset) so "a1": 0->1, "a2": 2->3, "a3":4->5, "a4":6->7, but this is too complicated to be worth using. Also it sometimes blinks first frame for a frame or few (so it looks very bad then).
Is it a bug or I'm doing something wrong?
After digging in cocos2d-x code it seems more troublesome than it looks.
There are 3 problems in current implementation:
1) when you won't play your animation it'll have playing property set to false so ActionTimeline::step won't even pass first if (checking if playing) and it'll never render another frame.
2) when you use gotoFrameAndPause _endFrame is never set (it's 0 by default) and because of that setCurrentFrame will always fail, because of this if:
if (frameIndex >= _startFrame && frameIndex <= _endFrame)
3) when you use "play" _startFrame and _endFrame are set between just this one particular animation and you won't be able to "jump" to frame outside it.
I've made a little workaround and put that in 3 macros:
#define CC_INIT_ACTION(__ACTION__) __ACTION__->gotoFrameAndPlay(0, __ACTION__->getDuration() + 1, 0, false); __ACTION__->pause()
#define CC_JUMP_ACTION_TO_FRAME(__ACTION__, __FRAME__) __ACTION__->setCurrentFrame(__FRAME__); __ACTION__->resume(); __ACTION__->step(0.0001f); __ACTION__->pause()
#define CC_JUMP_ACTION_TO_FRAME_BY_NAME(__ACTION__, __NAME__) int __FRAME__ = __ACTION__->getAnimationInfo(__NAME__).startIndex; CC_JUMP_ACTION_TO_FRAME(__ACTION__, __FRAME__)
CC_INIT_ACTION makes possible to jump to every frame.
CC_JUMP_ACTION_TO_FRAME jumps to particular frame number.
CC_JUMP_ACTION_TO_FRAME_BY_NAME jumps to first frame in particular animation.
Also step(0.0001f) in CC_JUMP_ACTION_TO_FRAME is necessary, because step sometimes calculates current frame wrong (maybe rounding problem, not sure).

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

Using SetKeyboardState along with GetKeyboardState in C++

I don't know how to write a good question here, but, basically, does anyone know where I can possibly find some C++ source code using these to actually set keyboard state? For some reason using it the way MSDN does on Windows 7 doesn't do...anything at all.
Basic code:
PBYTE keyState;
GetKeyboardState(keyState);
...
// Later on when I need to set the keyboard state (key pressed etc) back to original:
SetKeyboardState(keyState);
and ... nothing happens :(
From:
http://www.gamedev.net/community/forums/topic.asp?topic_id=43463
First off, GetKeyboardState() would be the wrong function to use because as Windows has a chance to process keyboard messages (whether you want it too or not) it updates the results of the keyboard's state for the next call to GetKeyboardState().
Here's a little function that I use to get the status of the keyboard's keys. Be carefull though, depending on how fast your main loop is, it may cause problems if you aren't expecting it.
You need to keep track of whether or not a specific key was pressed the last time you called the ReadKeyboard() function. If your loop polls the keyboard 30 times a second, then pressing a key once probably causes the key to be flagged 3 or 4 calls in a row. Rather confusing sometimes. Just thought I'd mention it.
void ReadKeyboard( char* keys )
{
for (int x = 0; x < 256; x++)
keys[x] = (char) (GetAsyncKeyState(x) >> 8);
}