[Last Call] Learn about multicloud storage options and how to improve your company's cloud strategy. Register Now

x
?
Solved

change brush color

Posted on 2002-06-07
12
Medium Priority
?
529 Views
Last Modified: 2010-05-18
OK, I have CBrush myBrush, then I put:
myBrush.CreateSolidBrush(RGB(100,200,10));
 Now, the problem is, how to change myBrush to another color. It popped up an error when I try to use CreateSolidBrush again on that object.?? Any clue. Thanks.
0
Comment
Question by:quanghoc
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 5
12 Comments
 
LVL 8

Expert Comment

by:fl0yd
ID: 7062419
You have to select it out of the current device context and call myBrush.DeleteObject before you can call myBrush.CreateSolidBrush(...) again.

A basic note: Posts like 'an error popped up' aren't really helpful if you don't tell us what error it was.
0
 
LVL 1

Author Comment

by:quanghoc
ID: 7062805
The error was Debug assertion failed!
0
 
LVL 8

Expert Comment

by:fl0yd
ID: 7062940
That's what I guessed -- but I'm sure it said more than just some debug assertion, right? I probably said that CBitmap::m_hObject != NULL
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 1

Author Comment

by:quanghoc
ID: 7063043
yes, ASSERT(someobject==NULL) return false and that made the error. I found out when I choose "debug". So, what I don't understand is what actually wrong with it? Can someone explain?
0
 
LVL 8

Expert Comment

by:fl0yd
ID: 7063247
ASSERT is there to help you. In general it follows this syntax:
ASSERT( some_condition )
if some_condition is false, this dialog comes up. It is there to give you runtime-diagnostics. It is there to check whether an assumption you made is correct. In the case of your CBrush it ensures that the object isn't attached to any GDI-object when you call any of the creation functions. This prohibits any memory leaks within your application's drawing functions.
Btw: You can put as many ASSERT's in your code as you like -- in the Release build they are not compiled into your executable. With this in mind, you should never change any variables or call functions that change them inside an ASSERT. If you need to call such functions use the VERIFY-macro instead.
0
 
LVL 1

Author Comment

by:quanghoc
ID: 7063301
Okey, I kinda got that ASSERT is to check memory leaks, but how come doing myBrush.CreateSolidBrush(RGB(100,200,10)) twice is wrong?? And I already tried myBrush.DeleteObject, not work either.
0
 
LVL 8

Expert Comment

by:fl0yd
ID: 7063413
No, ASSERT isn't to check for memory leaks but to make sure some condition that is crucial for your application is met. In the CBrush class it is used to prevent memory and resource leaks not to see if there are any.
To understand why applying CreateSolidBrush twice is wrong you have to understand what CBrush actually is. An object of class CBrush never contains a GDI brush -- all it does is control the way you interact with it. So if you call a creation function for the second time, the GDI object still exists -- I'm not sure, but a CBrush::Detach() could help after you called CBrush::DeleteObject(); I thought a DeleteObject() was enough though, noone is perfect...
Basically, my opinion is that using MFC without having a strong win32-background is making things more complicated than necessary. This usually becomes apparent when dealing with drawing routines, CDC's, CGdiObject's and the likes.
0
 
LVL 8

Expert Comment

by:fl0yd
ID: 7063436
I just checked it: you don't need to call CBrush::Detach() -- it is called in CBrush::DeleteObject(). This means that you can call CreateSolidBrush() after calling DeleteObject() and there should be no error. You should check the return value of CBrush::DeleteObject() -- it can return FALSE. Also, make sure that the brush is *NOT* selected into any device context when calling DeleteObject() -- otherwise it will fail and not reset CBrush::m_hObject thus the
ASSERT( m_hObject == NULL )
will be false the second time you try to create a brush and the dialog will pop up.
0
 
LVL 1

Author Comment

by:quanghoc
ID: 7064204
----------
make sure that the brush is *NOT* selected into any device context when calling DeleteObject() --
----------
sorry, what does it mean?
0
 
LVL 8

Accepted Solution

by:
fl0yd earned 600 total points
ID: 7064257
Somewhere in your code you have something like

CBrush* pOldBrush = static_cast<CBrush*>( cdc.SelectObject( &myBrush ) );

or maybe

CBrush* pOldBrush = (CBrush*)cdc.SelectObject( &myBrush );

This line of code selects the brush into the device context to make it available for drawing. As long as the brush is selected into the device context it cannot be deleted. So you have to call

cdc.SelectObject( pOldBrush );

before going on to delete your brush using

BOOL success = myBrush.DeleteObject();

This is a bit of inverse logic here: You cannot select a CGdiObject-derived object (CPen, CBrush, ...) out of a device context. However, at any given time there can only be ONE object of any type selected into the device context, thus if you select your old brush back into the device context, the currently used brush is deselected.

Don't get me wrong here, but I think you should definately do some reading on win32-/gdi-programming before going on using mfc. I'm not trying to discourage you, but from my own experience I know that it was pure luck, that my first mfc experiments did work at all. Once you have a somewhat solid understanding of the windows gdi you will find your way around those mfc-anomalies a lot more easily. Believe me, it is surely not all that complex as it presents itself to you at the moment.
0
 
LVL 11

Expert Comment

by:griessh
ID: 7261565
Dear quanghoc

I think you forgot this question. I will ask Community Support to close it unless you finalize it within 7 days. You can always request to keep this question open. But remember, experts can only help you if you provide feedback to their questions.
Unless there is objection or further activity,  I will suggest to accept

     "fl0yd"

comment(s) as an answer.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
======
Werner
0
 
LVL 1

Author Comment

by:quanghoc
ID: 7263272
Sorry, actually, I got it worked. The reason this question has forgotten because there was a bug in this forum preventing me from submitting any response. Thanks all.
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
Suggested Courses

656 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question