|
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.
|
|
|
|
|
Hi,
Can anyone tell me how to make the enter key work like a tab key in a dialog box.
For instance, I have two edit controls, a Checkbox control and three command button controls and I pressing the enter key should setfocus to the next control according to the TAB order.
Is it possible to do this without using event handlers for each and every control?
Regards,
Seagull.
|
|
|
|
|
PreTranslateMessage
How low can you go ? (MS retrofuck)
|
|
|
|
|
|
Hi.
I am implemented a very simple MFC program without the powerful of ClassWizard.
I added a CListCtrl listbox. Everything works as designed except for a double-click message handler. I cannot get the program to respond when the user double-clicks the listbox. I have tried different messages, but all failed.
I would like to know, What message do you handler for double-click (left mouse button) on a CListCtrl that is not in a dialog box and was not implemented using ClassWizard.
Thanks,
Kuphryn
|
|
|
|
|
Your dialog box receives the LBN_DBLCLK notification message when you double-click. You can add a command handler ON_COMMAND(LBN_DBLCLK, ...) in your parent window.
How low can you go ? (MS retrofuck)
|
|
|
|
|
Okay. Thanks.
The program ignores all solutions yet. There is something weird going on here. I try adding a hander for LBN_DBLCLK and it only works outside of the CListCtrl box. I believe the program ignores everything inside of the list box.
Kuphryn
|
|
|
|
|
kuphryn wrote:
I believe the program ignores everything inside of the list box.
The notification is sent TO THE PARENT WINDOW, that's by design.
Otherwise, you need to derive your own class, and tweak things a bit (many CP articles are here to help your way out).
How low can you go ? (MS retrofuck)
|
|
|
|
|
You're confusing the list box and list control. CListCtrl is the latter, and sends an NM_DBLCLK message to its parent when the control is double-clicked.
--Mike--
"I'd rather you just give me a fish today, because even if you teach me how to fish, I won't do it. I'm lazy." -- Nish
Just released - 1ClickPicGrabber - Grab & organize pictures from your favorite web pages, with 1 click!
My really out-of-date homepage
Sonork-100.19012 Acid_Helm
|
|
|
|
|
Okay.
NM_DBLCLK does not work either.
I tested ON_NOTIFY and ON_NOTIFY_REFLECT using NM_DBLCLK and LBN_DBLCLK.
Kuphryn
|
|
|
|
|
Okay. I figured out the bug. The bug was a human-error, not an MFC error.
I made an error during creation of the CListCtrl object.
Here is the error.
// Here is the incorrect creation code.
-----
m_LB_Box.Create(WS_CHILD | WS_VISIBLE | WS_BORDER | LVS_REPORT | LVS_SORTASCENDING, CRect(0, 100, 100, 50), this, 1);
-----
Notice the "1" in the last parameter.
// Here is the solution.
-----
m_LB_Box.Create(WS_CHILD | WS_VISIBLE | WS_BORDER | LVS_REPORT | LVS_SORTASCENDING, CRect(0, 100, 100, 50), this, IDC_LB_BOX);
-----
Thanks everyone,
Kuphryn
|
|
|
|
|
How can i open a default internet browser in new window ???
|
|
|
|
|
Use the opennew verb, intead of open.
How low can you go ? (MS retrofuck)
|
|
|
|