[RESOLVED] [win32] - avoid flicker and do a correct redraw
for resize or readraw the control i do:
Code:
SetWindowPos(hwnd, 0, 0, 0, 0, 0,
SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|
SWP_DRAWFRAME | SWP_FRAMECHANGED|SWP_NOCOPYBITS);
but theses flags: SWP_DRAWFRAME and SWP_FRAMECHANGED give me the flicker.
if i have the control transparent and don't use these code, the control isn't redraw, when i change the text :(
so how can redraw the control without flicker? or 'clean' correctly the control, before give it the next text?
Re: [win32] - avoid flicker and do a correct redraw
Quote:
Originally Posted by
Cambalinho
for resize or readraw the control
To redraw a control you need InvalidateRect.
Besides, resizing hardly gets along with zero values and SWP_NOSIZE flag. There's definitely must be something about the resizing that I don't know or understand. :)
As for the flicker, you need to read more about WM_ERASEBKGND
Re: [win32] - avoid flicker and do a correct redraw
Quote:
Originally Posted by
Igor Vartanov
To
redraw a control you need
InvalidateRect.
Besides,
resizing hardly gets along with zero values and SWP_NOSIZE flag. There's definitely must be something about the
resizing that I don't know or understand. :)
As for the flicker, you need to read more about
WM_ERASEBKGND
"The DefWindowProc function erases the background by using the class background brush specified by the hbrBackground member of the WNDCLASS structure. If hbrBackground is NULL, the application should process the WM_ERASEBKGND message and erase the background.
An application should return nonzero in response to WM_ERASEBKGND if it processes the message and erases the background; this indicates that no further erasing is required. If the application returns zero, the window will remain marked for erasing. (Typically, this indicates that the fErase member of the PAINTSTRUCT structure will be TRUE.) "
sorry... can you explain better?
Re: [win32] - avoid flicker and do a correct redraw
What part looks unclear to you? You need to get to a habit of reading MSDN on every single entity you meet in the text you are to understand. This literally means that to understand this fragment you need to have a background about DefWindowProc, WNDCLASS structure and related, PAINTSTRUCT and related, etc.
So please don't wait until somebody digests everything for you. You have to learn to survive on your own having only a few hints from the community about possible directions.
Re: [win32] - avoid flicker and do a correct redraw
Quote:
Originally Posted by
Igor Vartanov
What part looks unclear to you? You need to get to a habit of reading MSDN on every single entity you meet in the text you are to understand. This literally means that to understand this fragment you need to have a background about DefWindowProc, WNDCLASS structure and related, PAINTSTRUCT and related, etc.
So please don't wait until somebody digests everything for you. You have to learn to survive on your own having only a few hints from the community about possible directions.
"An application should return nonzero if it erases the background; otherwise, it should return zero."
so:
Code:
case WM_ERASEBKGND:
return true;//or even '1'... but must be diferent than '0' or don't clean it.
what make me confuse is: if we are talking about controls, why the MSDN speaks about WM_PAINT message?
(the WM_PAINT is for rebuild, for example, a new control and show images and work with HDC)
Re: [win32] - avoid flicker and do a correct redraw
WM_PAINT is sent to any window, including controls, which area became invalid.
It might be invalid due to various reasons. For example, parent window was moved the way that the control or some part of it was displaced off the screen, and moved back to screen again. This way the window, or invalid part of it needs to be re-painted, and that's why WM_PAINT is sent.
Or in case the window internally changes its state, e.g. the text it renders on screen, to be re-painted it declares itself invalid by calling InvalidateRect. This will again result in sending WM_PAINT to the window to be re-painted with the updated content.
Re: [win32] - avoid flicker and do a correct redraw
Quote:
Originally Posted by
Igor Vartanov
WM_PAINT is sent to any window, including controls, which area became invalid.
It might be invalid due to various reasons. For example, parent window was moved the way that the control or some part of it was displaced off the screen, and moved back to screen again. This way the window, or invalid part of it needs to be re-painted, and that's why WM_PAINT is sent.
Or in case the window internally changes its state, e.g. the text it renders on screen, to be re-painted it declares itself invalid by calling InvalidateRect. This will again result in sending WM_PAINT to the window to be re-painted with the updated content.
thanks for all
Re: [win32] - avoid flicker and do a correct redraw
Quote:
Originally Posted by
Igor Vartanov
WM_PAINT is sent to any window
Need to pick a nit here...
WM_PAINT is never SENT to a window by Windows. (and you should never send it yourself either)
The messagequeue has a flag that indicates that any part of the windows associated with said messagequeue have become invalidated and thus needs repainting.
When you get messages from the queue, and the queue is empty) and the invalid flag is set, then GetMessage will return a WM_PAINT.
This is why multiple invalidates only result in 1 WM_PAINT...
...and why WM_PAINT messages seem to be "pushed back" in the messagequeue and other messages get prioritized). If you invalidate a window and then send/post a message, you will first get the sent/posted message, then a WM_PAINT.
There are other messages that equally don't actually get queued in the message queue but rather set a flag with the flag generating a returned message.
Such as WM_TIMER, this works similarly, because if you don't get messages for X time (bad idea, but hey...), you won't suddenly get a flood of WM_TIMER messages you haven't been processing during that time).
It's different to WM_PAINT in that a message is generated when you do GetMessage() and the timer flag is set rather than when the queue is empty. THere's several flags, but the point at which they generate a message is different.
Re: [win32] - avoid flicker and do a correct redraw
Quote:
Originally Posted by
OReubens
WM_PAINT is never SENT to a window by Windows.
WM_PAINT message
Quote:
The WM_PAINT message is sent when the system or another application makes a request to paint a portion of an application's window. The message is sent when the UpdateWindow or RedrawWindow function is called, or by the DispatchMessage function when the application obtains a WM_PAINT message by using the GetMessage or PeekMessage function.
The reality is a little bit trickier.
Re: [win32] - avoid flicker and do a correct redraw
1 - for do transparent i do(for all drawed controls):
Code:
case WM_ERASEBKGND:
{
return (LRESULT)TRUE;
}
break;
2 - for avoid flicker i add the WS_CLIPCHILDREN style on parent.
3 - for readraw, i use:
Code:
RECT d;
GetClientRect(hwnd,&d);
InvalidateRect(hwnd,&d,TRUE);
why the child control isn't clear, before call the WM_PAINT message?
Re: [win32] - avoid flicker and do a correct redraw
because you didn't clear it in the WM_ERASEBKGND :-)
that's what that message is there for.
Re: [win32] - avoid flicker and do a correct redraw
Quote:
Originally Posted by
OReubens
because you didn't clear it in the WM_ERASEBKGND :-)
that's what that message is there for.
i'm confused..i thot that i was doing it :(
from MSDN: "An application should return nonzero if it erases the background; otherwise, it should return zero."
so what i'm doing wrong?
Re: [win32] - avoid flicker and do a correct redraw
Quote:
Originally Posted by
Cambalinho
i'm confused..i thot that i was doing it :(
from MSDN: "An application should return nonzero if it erases the background; otherwise, it should return zero."
so what i'm doing wrong?
You just return TRUE, but erase nothing. As the result, neither you nor Windows takes care of the background.
Re: [win32] - avoid flicker and do a correct redraw
Quote:
from MSDN: "An application should return nonzero if it erases the background; otherwise, it should return zero."
so what i'm doing wrong?
You are returning a nonzero value for WM_ERASEBKGND (ie indicating that the background has been erased) without actually erasing the background! If you need background processing different to that provided by DefWindowProc() then this needs to be done in WM_ERASEBKGND.
Re: [win32] - avoid flicker and do a correct redraw
Quote:
Originally Posted by
2kaud
You are returning a nonzero value for WM_ERASEBKGND (ie indicating that the background has been erased) without actually erasing the background! If you need background processing different to that provided by DefWindowProc() then this needs to be done in WM_ERASEBKGND.
i'm doing it:
Code:
case WM_ERASEBKGND:
{
if(inst->blnTransparent==true)
{
SetClassLongPtr(hwnd, GCLP_HBRBACKGROUND,(LONG_PTR)GetStockObject(NULL_BRUSH));
}
else
{
SetClassLongPtr(hwnd, GCLP_HBRBACKGROUND,(LONG_PTR)CreateSolidBrush(inst->clrBackColor));
}
DefWindowProc(hwnd, msg, wParam, lParam);
}
break;
but i'm doing 1 error. why isn't transparent?