-
January 30th, 2014, 06:41 PM
#1
[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?
-
February 5th, 2014, 06:12 AM
#2
Re: [win32] - avoid flicker and do a correct redraw
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
Best regards,
Igor
-
February 5th, 2014, 07:54 AM
#3
Re: [win32] - avoid flicker and do a correct redraw
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?
-
February 5th, 2014, 01:40 PM
#4
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.
Best regards,
Igor
-
February 5th, 2014, 05:48 PM
#5
Re: [win32] - avoid flicker and do a correct redraw
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)
-
February 6th, 2014, 09:06 AM
#6
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.
Best regards,
Igor
-
February 6th, 2014, 09:21 AM
#7
Re: [win32] - avoid flicker and do a correct redraw
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
-
February 7th, 2014, 08:13 AM
#8
Re: [win32] - avoid flicker and do a correct redraw
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.
Last edited by OReubens; February 7th, 2014 at 08:16 AM.
-
February 9th, 2014, 02:54 PM
#9
Re: [win32] - avoid flicker and do a correct redraw
Originally Posted by OReubens
WM_PAINT is never SENT to a window by Windows.
WM_PAINT message
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.
Best regards,
Igor
-
March 29th, 2015, 04:07 PM
#10
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?
-
March 29th, 2015, 05:30 PM
#11
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.
-
March 30th, 2015, 04:07 AM
#12
Re: [win32] - avoid flicker and do a correct redraw
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?
-
March 30th, 2015, 04:35 AM
#13
Re: [win32] - avoid flicker and do a correct redraw
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.
Last edited by Igor Vartanov; March 30th, 2015 at 04:38 AM.
Best regards,
Igor
-
March 30th, 2015, 04:35 AM
#14
Re: [win32] - avoid flicker and do a correct redraw
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.
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
March 30th, 2015, 05:03 AM
#15
Re: [win32] - avoid flicker and do a correct redraw
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?
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|