|
how can i load a bitmap on a control which automatically changes the color (the rectangle part without the main image)as same as the current dialog color(when i change properties>>appearence tab)..
I like the dreams of the future than the history of the past.
|
|
|
|
|
first, get COLOR_BTNFACE, then use the color modify your bitmap (from buffer or on dc - best on memory dc).
it is very easy for me.
only hard thing is how to decide the "rectangle"
includeh10
|
|
|
|
|
That's strange and I needed a while to find that a CBitmap can't be stored into a vector. What can I do?
|
|
|
|
|
|
|
Hmm, what are you trying to do exactly. Have you tried a vector of pointers to CBitmap class
e.g.
std::vector<CBitmap *> v_pBitmap;
|
|
|
|
|
yes that works.... but you need to do the cleanup manualy.
I would prefer a vector of real objects, if possible. I guess a constructor or copy constructor is missing in CBitmap... anyone knows exactly why CBitmap fails?
|
|
|
|
|
Could you wrap it with an auto_ptr or something?
Yep, I can't see a copy constructor, which would go a long way to stop it from working.
|
|
|
|
|
|
Anonymous wrote:
I would prefer a vector of real objects, if possible.
it's probably "failing" because the CBitmap destructor is being called. objects in vectors may be copied and destroyed many times as a result of adding, resizing, sorting, etc.. this is simply the way they work. so, your CBitmaps are being copied and destroyed (which releases the bitmap data) simply as a rsult of adding them to the vector.
that's why you need to use pointers to objects in vectors, if the objects have any kind of memory management or external resources.
-c
Alcohol is the anesthesia by which we endure the operation of life.
-- George Bernard Shaw
|
|
|
|
|
Thx for your help!
Chris Losinger wrote:
it's probably "failing" because the CBitmap destructor is being called.
I dont think so, ctor/dtor are empty:
_AFXWIN_INLINE CBitmap::CBitmap() { }<br />
_AFXWIN_INLINE CBitmap::~CBitmap() { }<br />
Im still suprised, a copy ctor would copy the data to another object.... so adding, resizing shouldn't be a problem. prolly not efficient, but I wonder why it has to fail with CBitmap.
Could it be that CBitmap is bad designed (missing ctor)? From the source it looks like a simple wrapper for a HBITMAP , I'm not that good in C++ and templates. I dont get why a CBitmap could not work with STL containers.
|
|
|
|
|
Anonymous wrote:
I dont think so, ctor/dtor are empty
CBitmap is derived from CGDIObject, which has a virtual destructor. that destructor looks like this:
_AFXWIN_INLINE CGdiObject::~CGdiObject()
{ DeleteObject(); }
so every time a CBitmap goes out of scope (which happens a lot when adding to a vector) it deletes the object it holds.
in general, anything that holds onto external resources (GDI objects, other objects, heap memory, etc) and that deletes them in the destructor needs special care when used in STL containers.
-c
Alcohol is the anesthesia by which we endure the operation of life.
-- George Bernard Shaw
|
|
|
|
|
Chris Losinger wrote:
_AFXWIN_INLINE CGdiObject::~CGdiObject() { DeleteObject(); }
oh thx!
so every time a CBitmap goes out of scope (which happens a lot when adding to a vector) it deletes the object it holds.
You can use reserve() for a vector. So the amount of copy ctors and assignments is very less (as long as the container does not need to shrink or relocated). Advantage, vectors are very fast to iterate, especially when holding real objects (extra indirection from pointers makes more cache breaks).
That's why I wanted to use a vector of CBitmap (actually it's a structure with a CBitmap). Also I wanted to get rid of manual cleanup code (delete *CBitmap).
Hmmm
|
|
|
|
|
Anonymous wrote:
You can use reserve() for a vector.
sure, but that won't fix the problem of CBitmaps deleting their contents.
you really need to use a CBitmap* (or a CBitmap* wrapped in an auto_ptr) if you're going to put it in any kind of container.
-c
Alcohol is the anesthesia by which we endure the operation of life.
-- George Bernard Shaw
|
|
|
|
|
Chris Losinger wrote:
sure, but that won't fix the problem of CBitmaps deleting their contents.
yes, and thanks for pointing this out.
May I ask what I don't understand:
Why is there no copy ctor in CBitmap?
A copy ctor would normaly copy the CBitmap object to another object
before the dtor is called. You can visualize this:
#include <stdio.h>
#include <vector>
class testme
{
public:
testme() {
value = 0;
printf("testme ctor (%d,0x%X)\n", value, (unsigned int) this);
}
testme(int t) {
value = t;
printf("testme ctor (%d,0x%X)\n", value, (unsigned int) this);
}
testme(const testme& ref) {
value = ref.value;
printf("testme copy ctor (%d,0x%X <- 0x%X)\n", value, (unsigned int) this, (unsigned int) &ref);
}
~testme() {
printf("testme dtor (%d, 0x%X)\n", value, (unsigned int) this);
}
testme& operator= (const testme &ref) {
value = ref.value;
printf("testme assigning %d,0x%X <- 0x%X\n", value, (unsigned int) this, (unsigned int) &ref);
return *this;
}
private:
int value;
};
int main()
{
std::vector<testme> v;
v.reserve(3);
testme test1(1);
testme test2(2);
testme test3(3);
printf("push_back\n");
v.push_back(test1);
v.push_back(test2);
v.push_back(test3);
printf("erase first\n");
v.erase(v.begin());
v.clear();
}
Output from above:
testme ctor (1,0xBFFFF55C)
testme ctor (2,0xBFFFF558)
testme ctor (3,0xBFFFF554)
push_back
testme copy ctor (1,0x804C340 <- 0xBFFFF55C)
testme copy ctor (2,0x804C344 <- 0xBFFFF558)
testme copy ctor (3,0x804C348 <- 0xBFFFF554)
erase first
testme assigning 2,0x804C340 <- 0x804C344
testme assigning 3,0x804C344 <- 0x804C348
testme dtor (3, 0x804C348)
testme dtor (2, 0x804C340)
testme dtor (3, 0x804C344)
testme dtor (3, 0xBFFFF554)
testme dtor (2, 0xBFFFF558)
testme dtor (1, 0xBFFFF55C)
|
|
|
|
|
Anonymous wrote:
Why is there no copy ctor in CBitmap?
i'm not actually sure, but speculation is fun. maybe it was to avoid the confusion of "who owns the HBITMAP now??". maybe it's just an oversight - i think CBitmap predate MS's STL awareness, so maybe they never thought there'd be a need.
Alcohol is the anesthesia by which we endure the operation of life.
-- George Bernard Shaw
|
|
|
|
|
Chris Losinger wrote:
who owns the HBITMAP now??
Hmm yes.... *thinking*
Question: Can I make a new HBITMAP from an existing HBITMAP, not just a copy of the handle? A real new HBITMAP so that the content (loaded image) is really duplicated? Perhaps I can use CreateBitmapIndirect(&m_hObject), but I'm not very good in Win32.
If it's possible I could theoretically derive a class from CBitmap, add a copy ctor and make STL containers happy.
Thanks again for your help.
|
|
|
|
|
Anonymous wrote:
Can I make a new HBITMAP from an existing HBITMAP, not just a copy of the handle?
yes, but it involves creating a new blank CBitmap a memory DC and a BitBlt - in other words, you have to draw the source onto the output. that's a pretty expensive operation, just to please STL.
take a look at auto_ptr. it will handle reference counting for you, and delete the contained object when there are no more references to it.
-c
Alcohol is the anesthesia by which we endure the operation of life.
-- George Bernard Shaw
|
|
|
|
|
thanks a lot for your patience! you convinced me.
PS: What I found on Google, short resume from our thread:
http://groups.google.com/groups?q=copy+constructor&hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=6i70hv%24iav%242%40news.LF.net&rnum=2
|
|
|
|
|
|
thx for reminding this!
e.g from 'Effective STL' Item 8: Never create containers of auto_ptrs
|
|
|
|
|
frankly, i never use auto_ptr at all, anywhere. i would just use a vector of CBitmap*s.
so, Anonymous, sorry about the bad auto_ptr advice - but i was trying to get you to use CBitmap * !
-c
Alcohol is the anesthesia by which we endure the operation of life.
-- George Bernard Shaw
|
|
|
|
|
Agreed, CBitmap*s is the way to go in this specific case.
I recently tried to use the MS auto_ptr and failed miserably because it doesn't implement reset(). Instead I used boost::scoped_ptr to very good effect. I plan to use it more in the future. Worth a look.
Neville Franks, Author of ED for Windows. www.getsoft.com
|
|
|
|
|
No, thanks for your help! I didn't like auto_ptr in the past and I will go back to my old code with CBitmap*
|
|
|
|
|
Probably the problem comes from HBITMAP , which is a handle and can't be simply "copied". If you simply copy the value of the HBITMAP , you would create a reference... which would become invalid if the original HBITMAP fades away.
I guess a CBitmap copy-ctor has to test 1. HBITMAP to be valid and 2. create a new handle by duplicating the original.
I don't know if this is possible with Win32. Perhaps not or CBitmap would already do it? Comments?
PS: Using auto_ptr of *CBitmap (rathern than CBitmap) seems to be a solution.
|
|
|
|