As of 26 March 2015, problem solved, see bottom of this page, a very dirty trick.
As of 18 Aug 2014, partly solved: DWM is the culprit (see the last comment).
I've built my own window style using win32 API's. Everything went fine under windows XP and Windows 7. However, under windows 8 weird things happen: Dragging the left border of the window causes extreme jitter at the right side, while it shouldn't move at all. Take a look at this and you will understand what I mean.
When I drag the right border, the left side doesn't move as it should be. Admittedly, there is some flickering, but that's acceptable. See this
I've tried SetWindowPos()
and (begin/End)DeferWindowPos
with several flags, but to no avail. Even with SWP_NOREDRAW
and blocking all other paintings doesn't help. Neither with or without CS_HREDRAW
and CS_VREDRAW
.
Of course I'm using double buffering. Yet It seems impossible to get rid of that pesky jitter. I've also tried another driver for the Intel HD 4000 graphic engine, again to no avail. Do I overlook something? Is it a bug of Windows 8?
By the way, when I switch on the "Show window contents while dragging" option (in the Advanced system settings menu), all other applications show the same behavior.
Any help will be greatly appreciated.
Cheers, Edmond.
PS: Disabling "Show window contents while dragging" is no option, because it's built in feature of my application.
Edit1: It seems that d7samurai is struggling with the same problem.
Follow up: I've tried a lot of things to get rid of the jitter, but nothing helps. The problem is that W8 simply doesn't do what it should do. Take for example the SWP_NOREDRAW
flag. As expected, repainting of the window side that has been moved, is suppressed, So far so good. BUT.... the other side (of the window), which is still valid, this one gets repainted! It's not only totally needless and useless, but it is repainted with jitter! Moreover, painting is two times slower compared with W7 and XP. After spending a whole week on this problem, I'm through with W8, totally! It's really a POC and the guys who are responsible for this botch job are mentally deranged. I really hope that W9 will do a better job. Amen.
THOU SHALT JITTER:
It appeared that the anomalies described above are not limited to only W8. Also W7 showed the same behavior when it is set to "best appearance" or at least to "Enable desktop composition" together with "Use visual styles on windows and buttons". I then thought it might be possible to fool windows by not using the SetWindowPos function at all, rather by sending a ShowWindow( hWnd, SW_MAXIMIZE )
command and intercepting the WM_GETMINMAXINFO
msg where I specify the desired size and position. Guess what? I still got jitter. Arghhh !!!
What to do next? Is there any possibility to intercept the painting at a lower/deeper level (hooks?) in order to redraw a window in a decent way?
Update dd 03-26-2015, a very dirty trick:
Eureka! I finally found the solution to the problem. But first, let me explain what is happening and why dragging is accompanied with jitter. Suppose you want to expand the left side of a window. Contrary to expanding the right side, this is done in two steps. First, the content of the window with its original size is moved to the left. After this has been done, the content is expanded to such an extent that the new right side coincides with the previous right side. In short it's combination of a "move" followed by a "resize" and this is what causes the ugly jitter. Similar things happen when you are dragging the top of a window. In Windows 8.1 or 10, there is nothing you can do against it. I've also tried the new DWM functions (BufferedPaintInit
, BeginBufferedPaint
, EndBufferedPaint
, BufferedPaintUnInit
) regrettably, to no avail. Also SetWindowPlacement()
produces jitter. Apparently, all these functions lead to the same culprit which spoils a resize.
I then reasoned that when you create a new window and display it with a new size, it doesn't jitter at all. Rather obvious, I would say. So repeatedly creating a new window and subsequently destroying the previous one, might be a solution, but this isn't very efficient, of course. While playing with this idea, I discovered by chance that making a hidden window visible with a new/another size, followed by hiding the previous window, also doesn't show jitter. This procedure is much more efficient than a create/destroy sequence. So at the start of my program I just created two windows, the first one hidden and the second one visible. The code snippet below should explain the procedure for jitterless resizing in more detail:
........
i = prm->hpi; // get current index
h1 = prm->parent[i]; // get current handle
flags = SWP_NOCOPYBITS;
flags |= SWP_NOSENDCHANGING;
// if DWM tries to make a mess of it:
// DWM enabled top border right border
if( prm->parent[1] && ( rgn == TBE || rgn == LBE ) )
{
i = i + 1 & 1; // get new index
prm->hpi = i; // save new index
h2 = prm->parent[i]; // get new handle
prm->hParent = h2; // set as current one
flags |= SWP_NOREDRAW; // bypass message pump
flags |= SWP_SHOWWINDOW; // make h2 visible
SetWindowPos( h2, HWND_TOP, px, py, cx, cy, flags );
PaintParent( h2 ); // paint it now
DwmFlush(); // wait till finished
ShowWindow( h1, SW_HIDE ); // make h1 invisible
}
// DWM disabled or dragging the right or bottom border:
else SetWindowPos( h1, HWND_TOP, px, py, cx, cy, flags );
One more thing: use DwmFlush()
to ensure all painting of the new window is finished and then hide the other window, otherwise some flicker will be visible. Of course above procedure is a little slower than a regular one. On my system (with a i5-3570K processor) 3..26ms, depending on the size of the window and its content. But at least that horrible jitter has gone.
I do realize that it's a pretty dirty trick, so if someone knows a neater solution, please, let us know.
SetWindowPos
yourself, how did you prevent Windows from also calling its normal internalSetWindowPos
as the user drags the border? – Landis