|
In VS you can open up multiple *.rc files at once and copy/paste between them. This is easier than dealing with them as text files, as you don't have to worry about assigning resource IDs, copying bitmap or icon files, etc.
farewell goodnight last one out turn out the lights Smashing Pumpkins, Tales of a Scorched Earth
|
|
|
|
|
What are the differences between OnErase and OnPaint.
Although I haven't actually tested or noticed, I assume OnPaint is called after. OnErase would be used for...drawing the background and OnPaint would be used for...drawing the forground, this is why i assume OnPaint is called second. Are there any other deifferences between them that i'm missing here...?
Also...double buffering doesn't seem to work in OnErase so I always get flicker.
CMemDC class works AWESOME!!! Kudos to the author, small simple...i one include file...I Like it!
However this class requires you to override onErase and return FALSE..?(i think) I guess this means all drawing should be done in OnPaint...???
I'm curious to know the purpose of OnErase...???
The reason I ask is i'm creating a control from scratch (CWnd) and do all the drawing etc...OnErase causes flicker and OnPaint don't...whats the deal...?
Cheers!
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
Seems to me that WM_ERASEBKGND is some kind of legacy message that has been maintained for compatibility reasons, but that lacks any real usefulness. The standard sequece of calls and messages is this:- When the window needs to be repainted,
WM_PAINT is sent. OnPaint typically calls BeginPaint , which prepares the window DC, sends WM_ERASEBKGND and returns the DC ready for painting. So, by the time BeginPaint returns, WM_ERASEBKGND has been already processed.- All drawing stuff takes place with the DC returned by
BeginPaint . - Once the drawing is finished,
EndPaint releases the DC and the handler for OnPaint exits. I've got two questions regarding this issue that surely Christian Grauss will be able to anwser (are you reading this, Chris ? ):
- What are the origins and purpose of the
WM_ERASEBKGND ? Is there more to this message than I said above?
- What is the difference between returning
TRUE or FALSE in OnEraseBkGnd ?
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Michael Dunn is the person who made me realise how useful WM_ERASEBKGND is, so he's probably a better person to answer this.
1. WM_ERASEBKGND seems to be used to redraw the background of a window, and any invalidate call that passes the default TRUE parameter calls it first. In this sense, I find that WM_PAINT is the redundant call, in that WM_ERASEBKGND is usually a better place to try and get flicker free drawing happening. The alternative is to prepare a buffer image, create a CPaintDC and immediately Blt the image over it, which makes for minimum flicker, but doing it in WM_ERASEBKGND is really what you're trying to get as close to simulating as possible, so why not do it there ? I actually tend to use OnPrepareDC, which is the prior call to OnDraw, and I have no idea why some app types can process both pairs of messages.
The one downside to all this is you must never call Invalidate(FALSE) if you are drawing in WM_ERASEBKGND.
Joaquín M López Muñoz wrote:
What is the difference between returning TRUE or FALSE in OnEraseBkGnd?
This is a question I'd like to look at myself. In theory it is telling the framework you did or didn't handle the call, but returning either instead of calling the base method appears to have the same effect, or at least that's how it seems based on my limited testing. I've always returned TRUE until someone posted an example returning FALSE and I noticed it did the same thing.
Christian
The tragedy of cyberspace - that so much can travel so far, and yet mean so little.
|
|
|
|
|
What is the difference between returning TRUE or FALSE in OnEraseBkGnd?
This is a question I'd like to look at myself. In theory it is telling the framework you did or didn't handle the call, but returning either instead of calling the base method appears to have the same effect, or at least that's how it seems based on my limited testing. I've always returned TRUE until someone posted an example returning FALSE and I noticed it did the same thing.
Hmm, between what you and Killowatt says, I will have to pull this up in the debugger and see what is going on. I really geek out over this stuff.
Tim Smith
I know what you're thinking punk, you're thinking did he spell check this document? Well, to tell you the truth I kinda forgot myself in all this excitement. But being this here's CodeProject, the most powerful forums in the world and would blow your head clean off, you've got to ask yourself one question, Do I feel lucky? Well do ya punk?
|
|
|
|
|
Christian Graus wrote:
WM_ERASEBKGND is usually a better place to try and get flicker free drawing happening
I don't know if your familiar with the CMemDC class found here Flick Free
but when I use it in OnDraw or OnPaint it works perfect, but in OnErase it still flickers...any idea as to why this might be..???
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
I'd say at a guess because you're trying to do something it handles itself, and that it uses the last minute creation of CPaintDC method I described.
Christian
The tragedy of cyberspace - that so much can travel so far, and yet mean so little.
|
|
|
|
|
Is hockeydude maybe calling the baseclass implementation, and then re-erasing background again afterwards?
I'd used this message handler, and done some really sloppy DC coding and still not had flickering. Hence I wonder if it's being done twice
Sorry to dissapoint you all with my lack of a witty or poignant signature.
|
|
|
|
|
WM_ERASEBKGND is still a very important message.
WM_ERASEBKGND reinitialized the display surface before you paint it. When you drag a window over the window that needs to be repainted, the WM_ERASEBKGND message is needed to remove the image of the window that obscurred your view of the target window.
If you override and return FALSE for WM_ERASEBKGND , and you do not provide a WM_PAINT handler, you will see that your display window will just get written on by any other window that is placed on top if your window.
If you return false in WM_ERASEBKGND , then you are telling the WM_PAINT handler that it is responsible for erasing the background of your window. The fErase field of the PAINTSTRUCT returned from BeginPaint will be true if you return FALSE in WM_ERASEBKGND .
|
|
|
|
|
Ok...so i'm not the only one that found OnErase un-nessecary. What bothers me is that my control (while painted in OnPaint to avoid flicker) will be painted over possibly by the derived versions OnDraw (It's actually a view not a CWnd). Unless the derived class does
void CNewView::OnDraw(CDC* pDC)
{
pDC->LineTo(100, 100);
COldView::OnDraw(pDC);
}
Would the above implementation avoid the problem..??
Hope you don't mind me asking...I realize i'm only one step away from trying it and figuring it out myself, but I always like to hear a second opinion on the subject before I ever try anything.
Cheers
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
Are you worried about other people deriving from your class and changing the way it looks, or even you deriving from your class? Is that the problem that you are trying to avoid?
If some one derives from your class there is very little that you can do to prevent them from doing anything that they want.
Let me know if you are trying to derive from someone else's class adding paint enhancements to what they have already done and avoid flicker by adding in your own new code.
|
|
|
|
|
I'm worried about anyone deriving from my class...I was kinda hoping there'd be a way around that problem.
It's not a big deal, it was really more outta curiousity than anything.
Thanx
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
I think that I see part of what you may be worried about with the code that you sent me earlier. If someone inherits from your view class, you want them to be able to update the view, but not draw on the Ruler Area. If this is correct, you could do something in a custom OnPaint Handler, and hope that the user handles their custom drawing in the OnDraw method.
If this is what you are worried about, and you want the process, let me know and I will tell you want to do.
|
|
|
|
|
OnErase, or WM_ERASEBKGND is generated inside of your call to ::BeginPaint. Of if you are using MFC inside of the creation of CPaintDC. All that OnErase is supposed to be used for is to clear the background that is currently invalid.
It is important to use the HDC that is handed in the WPARAM of the message, because the DC that you get is already primed with the clipping region of the invalid region that is being asked to be painted.
When you override the OnErase event, and return false, you are telling windows that you have not yet erased the background. Typically this means that the Erasing will have to be left up to the handler of the WM_PAINT message. Inside of the paint struct that is created in BeginPaint, the fErase field will be non-zero if the OnPaint handler should erase the background before painting.
The reason why the CMemDC class needs you to override the OnErase message is so that when the erase background handler is called, it does not erase the window that you are trying to prevent the flicker. Instead, the CMemDC erases the background on the double buffer, then blts the entire backbuffer to your window, elimiating the need for the default OnErase handler.
|
|
|
|
|
kilowatt wrote:
Instead, the CMemDC erases the background on the double buffer, then blts the entire backbuffer to your window, elimiating the need for the default OnErase handler.
Would this be the reason why CMemDC still causes flicker when used within OnErase...???
I'm flicker free when using it in OnPaint/OnDraw but NOT OnErase...??
Thanx again!
Cheers
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
HockeyDude wrote:
kilowatt wrote:
Instead, the CMemDC erases the background on the double buffer, then blts the entire backbuffer to your window, elimiating the need for the default OnErase handler.
Would this be the reason why CMemDC still causes flicker when used within OnErase...???
As long as you do not pass the Erase message on to the default handler, this would not continue to cause the problem.
Why don't you post the OnPaint and OnErase handler, and I will see if I can figure out why you are having this probelm.
|
|
|
|
|
i've decided to go with what works. I do all my drawing in OnPaint() and return FALSE in OnErase().
However this is basically what I had
void CMyClass::OnDraw(CDC* pDC)
{
}
void CMyClass::OnErase(CDC* pDC)
{
CMemDC buff(pDC);
buff.LineTo(100, 100);
CView::OnErase(pDC);
return FALSE;
}
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
Actually Kilo...i'm really curious, so here's my exact code...I dunno why it flickers in OnErase and Not OnDraw.
BOOL CRulerView::OnEraseBkgnd(CDC* pDC)
{
CMemDC buff(pDC);
CRect rect;
GetClientRect(&rect);
buff.FillSolidRect(0, 0, m_rulerSize, rect.bottom, ::GetSysColor(COLOR_BTNFACE));
buff.FillSolidRect(0, 0, rect.right, m_rulerSize, ::GetSysColor(COLOR_BTNFACE));
UINT nBorderWidth = ::GetSystemMetrics(SM_CXEDGE);
if(m_b3Dborder){
buff.DrawEdge(CRect(0, 0, rect.right, m_rulerSize), EDGE_RAISED, BF_RIGHT | BF_TOP);
buff.DrawEdge(CRect(0, 0, m_rulerSize, rect.bottom), EDGE_RAISED , BF_LEFT | BF_BOTTOM);
}
buff.DrawEdge(CRect(m_rulerSize-nBorderWidth, m_rulerSize-nBorderWidth, rect.right, rect.bottom), EDGE_SUNKEN, BF_TOP | BF_LEFT);
OnDrawRuler(&buff, CRect(nBorderWidth*2, m_rulerSize-nBorderWidth, m_rulerSize-(nBorderWidth*2), rect.bottom-m_nScrSize+nBorderWidth), RT_VERT);
OnDrawRuler(&buff, CRect(m_rulerSize-nBorderWidth, nBorderWidth*2, rect.right-m_nScrSize+nBorderWidth, m_rulerSize-(nBorderWidth*2)), RT_HORZ);
OnMouseMove(NULL, CPoint(-10,-10));
return FALSE;
}
void CRulerView::OnDraw(CDC* pDC)
{
}
Swap the code from OnErase into OnDraw and you'll see NO flicker...whats going on...?
I even tried writting to a memDC and blitting it myself to the screen (instead of using CMemDC) but no luck.
Either way would be great.
Thanx!
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
I created a simple project that mimicks the code that you have shown me, but I did not find any place that it could be flickering, I may be missing a piece of your program that is causing the flickering.
This is how I tested it, and this is what I suggest you should do if you want to find out why it flickers, this should only take about 10 minutes:
Size DevStudio and your program so that they do not overlap, and they will not interfere with each other, this is so that you do not generate an extra paint message while you are debugging.
Next, find the OnPaint handler in your program, which I assume is actually in MFCs code base. You can either search for it, or set a breakpoint on your OnErase handler and follow the stack down to the OnPaint handler. Set a Breakpoint on the same line that initializes the paint DC in OnPaint, and at the first line of the OnErase handler.
Next get your program so that it paints the window like normal and then enable the breakpoint.
Perform the action that invalidates your window in the way that causes the flicker. Step into the CPaintDC contstructor, and then through the OnErase handler waiting for the function call that causes the window to be erased.
You only have to step through until the end of the OnErase handler, because when this function exits the CMemDC class goes out of scope and paints to the window. After this happens I do not see any otherway for your window to be updated.
One other thing that I noticed is that the CMemDC class looks like it is quite inefficient to use it in painting. every time a paint is required, it creates a new memDC, a new bitmap to select into the mem DC, it then deletes these objects also. You may save some cycles by caching these object in your own class, and blitting the bitmap at the end of the OnDraw event yourself.
IMO, I think that the paint code should be in the OnDraw Handler anyway.
|
|
|
|
|
Is there a way (I haven't found one) to set my IDE default directory in the Open File dialog box to something other than the one it always is?? I use the IDE a lot without having a project open, and I hate having to manually navigate through the dirs every time I want to open a file.
Thanks.
- Jason
Do you have a Pulse?
SonorkID: 100.611 Jason
|
|
|
|
|
Make Drag & Drop with the Explorer. I have a short-cut whit my VCProjects Folder, I open that Folder, then the project folder (I left the folder open) and I make Drug & Drop between the explorer and the VS....
Regards;)
Carlos Antollini.
Sonork ID 100.10529 cantollini
|
|
|
|
|
I am new to VisualC++ and I'm having trouble with a first-chance exception message. I programming using a document/view structure. I have a dialog box calling a document function which is suppose to get me the size of a Carray. However, the program crashes. The message I get is the first-chance exception just before the crash. What is the problem and what can I do to stop this?
Thanks in advance
|
|
|
|
|
I can't tell what is wrong based on what you told me, however the first chance exception is the debuggers way of saying "there is a problem right here" and you can view the state of you program right where the exception was thrown.
What you need to do is look at all fo the variables around the current execution point, and determine if there is a memory access violation or somethine else like that. It may even be useful to set a breakpoint at the beginning of the function where the code crashes and watch what is happening.
Do you know what kind of exception your program is throwing? Are you catching the the exception?
|
|
|
|
|
First-chance exceptions are not in themselves a problem. They are just a message to the debugger that an exception has been thrown. Exceptions are thrown in a normal program execution and are not themselves indicative of error conditions. Usually someone or something will catch the exception and respond accordingly. The key word here is "First-chance" - this means the debugger gets a first chance to see the exception.
Since your program crash we can safely conclude that the exception thrown is indeed caused by a program error. You'll have to provide more info if we are to help you with this.
Cheers
Steen.
"To claim that computer games influence children is rediculous. If Pacman had influenced children born in the 80'ies we would see a lot of youngsters running around in dark rooms eating pills while listening to monotonous music"
|
|
|
|
|
I want to do a Restaurant project incorporated inventory and pricing. I want to do it in Visual C++ and this is generally what I want to do: have buttons that can be clicked with the name of the food, and then when the button is clicked, I want either a message box to be displayed or a a field to be updated stated how many are left in stock AND the price of the item itself AND the overall price of the entire order. I have set it up into functions. Is this the right way to go about it? Do you have any ideas that might be of help?? Thanks a lot.
|
|
|
|
|