|
Ok... more questions:
First of all, what do you mean CImage& is cheating? I mean, to me, it seems logical to use the reference (address in memory) of a CImage object (base on ISampleData interface), since I cannot return an instance (by value) of type ISampleData (pure abstract class).
Secondly, what do you mean by "inefficient"? Passing/returning by value versus by reference?
The other possiblity is to create the object on the heap (with new) and pass/return the pointer by value, like this:
ISampleData* Acquire()
{
CImage* result = new CImage();
...
return result;
}
CImage* image = (CImage*) Acquire();
But then I thought doing that is less "efficient" than copying an object to the 'caller' stack (by returning a reference to a CImage obj)????
The other thing is:
Surprisingly (and I thought the same as you did) polymorphism is NOT lost, and I don't know why...
I made a little experiment: I created a method in my class CImage called Display() which is not overloaded from CSampleData (i.e. just a new method specific to CImage). Then I did exactly as before (with "Acquire()" returning a reference to ISampleData):
CImage image = (CImage&) m_lpDigitizer->Acquire();
And guess what? when I call "image.Display()", well it works fine!
Why? Is it because I am dealing with reference to an object, not the object itself. Polymorphism apply to an object copy (by value), not to a reference copy of it?
Bertrand Boichon
|
|
|
|
|
Bertrand Boichon wrote:
Secondly, what do you mean by "inefficient"? Passing/returning by value versus by reference?
Yes. This is one of C++ basics. Of course, the 'inefficiency' greatly depends on the structure of class. Just remember that each object returned/passed by value is *copied*, and this can be quite expensive.
Could you post the Acquire function; simplify the actual code if needed but leave return type unchanged.
Tomasz Sowinski -- http://www.shooltz.com
*** Si fractum non sit, noli id reficere. ***
|
|
|
|
|
Here is the Acquire function, using a reference to a CImage (derived from ISampleData pure abstract class):
ISampleData& CCameraDigitizer::Acquire()
{
CImage sample;
// ... perform actual acquisition here ...
return sample;
}
The question is: what should I return ISampleData& (object by ref) or ISampleData* (pointer to obj, by value)?
I did some more tests on that matter (because I realized I don't know much about passing by reference vs by value). I added a dynamically allocated (on the heap) buffer (for the image itself) and an 'int' data field in the CImage class. Then I tried to use these in methods like Save or Display:
CImage image = (CImage&) m_lpDigitizer->Acquire();
image.Save("TEST.JPG");
image.Display();
I came to realize that even if Save and Display (using the buffer data field) are called correctly (what I saw at first), it actually displays crap since the buffer is pointing a random location, along with the 'int' field.
So the only solution is to return a pointer to a CImage obj (therefore allocated on the heap):
ISampleData* CCameraDigitizer::Acquire()
{
CImage* pSample = new CImage();
// ... perform actual acquisition here ...
return pSample;
}
And it works.
What do you think?
Best regards,
Bertrand Boichon
|
|
|
|
|
Returning the reference to local, non-static object is something you should *never* do in C++. The 'sample' variable is destroyed as soon as function returns - the CImage destructor is called. Your reference points to deallocated stack space which contains undefined bits.
So basically you have two options: allocated new object on the heap and return the pointer (as you did already) -or- pass the CImage object by reference to Acquire:
void CDigitizer::Acquire(CImage & image)
{
}
Tomasz Sowinski -- http://www.shooltz.com
*** Si fractum non sit, noli id reficere. ***
|
|
|
|
|
Is there any difference between returning and passing a reference to an object:
void Acquire(ISampleData& image)
vs
ISampleData& Acquire(void)
?
Because I tried the "ISampleData& Acquire(void)", and (of course) it de-allocates data fields when returning CImage reference. (cf previous email).
So you mean actually passing a CImage reference would not do that?
To me, the only option is to pass/return a pointer (to a CImage obj) by value.
bertrand
|
|
|
|
|
Bertrand Boichon wrote:
So you mean actually passing a CImage reference would not do that?
Yes, because you would not declare CImage inside Acquire:
void Acquire(ISampleData & image)
{
image.DoThis();
image.PerformThat();
}
...
CImage image;
Acquire(image);
The image Acquire is operating on is declared outside of function, so it's lifetime isn't bound to Acquire scope.
Returning a pointer to object allocated in Acquire is also OK. You may consider using std::auto_ptr or boost.org scoped_ptr to ensure proper deletion.
Tomasz Sowinski -- http://www.shooltz.com
*** Si fractum non sit, noli id reficere. ***
|
|
|
|
|
Thank you very much for the lesson!
Very helpful!
Bertrand Boichon
|
|
|
|
|
To enable / disable the toolbar buttons I use the update handler (ON_UPDATE_COMMAND_UI() macro)... ok... but when does the system change the state (enable/disable) of the toolbar buttons?
Have I to call Invalidate or UpdateWindow ???
--
Nice greets, Daniel.
|
|
|
|
|
'The system' (MFC app) updates the button state during its idle update cycle. See CWinApp::OnIdle and CFrameWnd::OnIdleUpdateCmdUI (undocumented).
Tomasz Sowinski -- http://www.shooltz.com
*** Si fractum non sit, noli id reficere. ***
|
|
|
|
|
Hi,
I would like use CMultiRectTracker into CScrollView to manipulate gdi
objects,
such as CRect, but when I try select object after scrolling there is bug
to move and positioning its RectTracker.
Can anyone help me?
Thanks, in advance
Gianfranco
|
|
|
|
|
Without any additional information about 'the bug', I guess you could forgot to convert from device units to logical units (with CDC::DPtoLP) in mouse event handlers.
Tomasz Sowinski -- http://www.shooltz.com
*** Si fractum non sit, noli id reficere. ***
|
|
|
|
|
I can get the select text in html in my ap. But how to get the position of the select text? Because next time I open the same html I want select the text auto.Or have any other way to do it?
|
|
|
|
|
This tag is part of the DOM, right ? So you need to store the path traversal from the root down to this node. It's up to you to find a convenient model. AFAIK, there's no such built-in model provided in the current IE DOM.
sometimes it helps to look at the IL generated code
a MS guy on develop.com "answering" .NET issues
|
|
|
|
|
So the html must have begin tag and end tag,if not. I would not do this feature right? Thx your reply.
|
|
|
|
|
Path traversal has nothing to do with end tags.
We are talking DOM IE API. That's just a matter of root node, and children.
She's so dirty, she threw a boomerang and it wouldn't even come back.
|
|
|
|
|
Sorry. I misunderstand. What is DOM IE API? Where I can find examples?
|
|
|
|
|
How can I change the bitmap of a toolbar button at runtime?
--
Nice greets, Daniel.
|
|
|
|
|
Try using the LoadBitmap() member function of CToolbar class.
|
|
|
|
|
Do you want to use any bitmap, or you just need to switch between some bitmaps you know at compile time?
Tomasz Sowinski -- http://www.shooltz.com
*** Si fractum non sit, noli id reficere. ***
|
|
|
|
|
Only between bitmaps I know at compile time (like a bitmap or a bitmap in a image list).
--
Nice greets, Daniel.
|
|
|
|
|
Use CToolBar::GetToolBarCtrl and CToolBarCtrl::AddBitmap to load bitmap from resource and append it to toolbar's image list, then CToolBar::SetButtonInfo to change the index of button's image. Bitmap should have the dimensions of your toolbar buttons, usually its 16 x 15. RGB(192, 192, 192) - light gray - is used as transparency by MFC toolbars.
Tomasz Sowinski -- http://www.shooltz.com
*** Si fractum non sit, noli id reficere. ***
|
|
|
|
|
Thanks... I try it...
--
Nice greets, Daniel.
|
|
|
|
|
How can I change the title of a dialog at runtime?
I want to add a constructor to my dialog, so that I can set the title of the dialog, like CMyDialog dlg(_T("Settings")); .
I save the title text in the constructor and want to set the title in the OnInitDialog function, but how can I set the title?
--
Nice greets, Daniel.
|
|
|
|
|
void SetWindowText( LPCTSTR lpszString );
|
|
|
|
|
In my application I am using Shellexecute to run SQLs through isql.exe.
I want to trap the exceptions/errors which isql throughs in messagebox dialogs.
Can I trap those messages anyway out.
Souchakra
|
|
|
|