|
Create using the parent and position as parameters, making sure they are set to visible. Messages from controls are WM_COMMAND with the controls ID as a parameter.
|
|
|
|
|
Thanks for the reply .
But can you please provide a sample code snippet to make it more clear.........?
|
|
|
|
|
Sorry I don't have any code that I can find, I just seem to remember doing this sort of thing. I had a quick look on the net... and found an MS MFC example [^] which should translate to ATL. What have you tried?
|
|
|
|
|
Hi all,
I have an ATL control based on CComCompositeControl. In the control's dialog box I have a web browser, from which I am sinking events. I also have another COM object which is not on the dialog box from which I'm sinking events. I'm getting an assert thrown as my control initialises in AtlAdviseSinkMap. In this ATL method there is a loop which goes over all the ids of the sink entries and calls:
HWND h = pT->GetDlgItem(pEntries->nControlID);
ATLASSERT(h != NULL);
While this works perfectly for the embedded web browser, the other object not on the dialog box causes an exception.
Is there a setting I can use to inform the initialisation that it is not a dialog object and that this is not appropriate but without the assert being thrown.
Many thanks
Cheers
Tom
Philosophy: The art of never getting beyond the concept of life.
Religion: Morality taking credit for the work of luck.
|
|
|
|
|
You must have added that setting somehow. Just taking some example code from an ATL object of mine that sinks events from a non control as a guide I have: a typedef to make things readable:
const UINT ID_QUEUEDEVENTS = 1;
typedef IDispEventImpl<ID_QUEUEDEVENTS, CMSMQEventControl, &DIID__IQueueMonitorEvents ,&LIBID_MSMQEVENTTEST2Lib ,1,0> IQueueMonitorEventSink ;
Then the beginning of class which inherits (the typedef):
public IQueueMonitorEventSink,
Then a sink map for the events:
BEGIN_SINK_MAP(CMSMQEventControl)
SINK_ENTRY_EX(ID_QUEUEDEVENTS , DIID__IQueueMonitorEvents, 1, QueuedMessage)
SINK_ENTRY_EX(ID_QUEUEDEVENTS , DIID__IQueueMonitorEvents, 2, QueuedError)
END_SINK_MAP()
Do you have something different?
|
|
|
|
|
Hi, thanks for the response.
I have something very similar.
In my class declaration I have:
public IDispEventSimpleImpl<0, COfficeDlgX, &__uuidof(_IOfficeAutomaterEvents)>,
public IDispEventImpl<IDC_WB,COfficeDlgX>,
In my class I then create a typedef for calling the advise method.
typedef IDispEventSimpleImpl<0, COfficeDlgX, &__uuidof(_IOfficeAutomaterEvents)> OfficeAutomaterEventsImpl;
Then I generate the sink map:
BEGIN_SINK_MAP(COfficeDlgX)
SINK_ENTRY(IDC_WB, 259, DocumentCompleteWb)
SINK_ENTRY(IDC_WB, 252, NavigateComplete2Wb)
SINK_ENTRY(IDC_WB, 250, BeforeNavigate2Wb)
SINK_ENTRY_INFO(0, __uuidof(_IOfficeAutomaterEvents), 1, &COfficeDlgX::__OnDocumentClosed, &OnMenuItemClickedInfo)
SINK_ENTRY_INFO(0, __uuidof(_IOfficeAutomaterEvents), 2, &COfficeDlgX::__OnMenuItemClicked, &OnMenuItemClickedInfo)
END_SINK_MAP()
in my code, when I create an instance of IOfficeAutomater I call:
hr = OfficeAutomaterEventsImpl::DispEventAdvise((IUnknown*)m_spOfficeAutomater, &__uuidof(_IOfficeAutomaterEvents));
IDC_WB is the dialog id of my WebBrowser.
I don't have to call DispEventAdvise for the web browser control myself as the framework does it for me. It does it by using the id to get to the control. Herein lies the problem. Somehow, the framework now thinks all the sink entry ids refer to an item on the dialog box. The system therefore runs through all the sink entry id and calls GetDlgItem with them. When it uses the id of my non dialog item ie 0, it of course comes back NULL. This value runs through an assert and hey presto I get a message box up telling me something's wrong.
On one hand it's only an assert and so it won't come up in the release build and it in no way affects whether my app works or not but it does seem very messy. What would be ideal is having two sink maps. One for dialog items and the other for anything else.
Cheers
Tom
Philosophy: The art of never getting beyond the concept of life.
Religion: Morality taking credit for the work of luck.
|
|
|
|
|
Looking at my ATL Internals (B.Rector & C.Sells) they say:
Easiest way...event sinks...derive ... from IDispEventImpl...
... when the event source is a contained control and the event recipient is a composite control, the identifier is the contained control's child window identifier.
When your class is a composite control, you should use the AtlAdviseSinkMap function to establish and remove connections...of the contained controls listed in the sink map...Using CWindow::GetDlgItem method, AtlAdviseSinkMap navigates to a child window handle...
When your class isn't a composite control you must explicitly call the DispEventAdvise method of each of your IDispEventSimpleImpl ... base classes to connect.
You seem to have the correct use of IDispEventImpl and IDispEventSimpleImpl. It also seems use of AtlAdviseSinkMap is out due to its requirement of "contained controls listed in the sink map" as one of your mapped controls isn't contained - as you say. So it seems you can't prevent AtlAdviseSinkMap calling GetDlgItem.
All it would seem you can do is not use AtlAdviseSinkMap but do it manually by using GetDlgItem etc on one and "explicitly call the DispEventAdvise" of the other (or both).
|
|
|
|
|
Thanks for your advice. It's much appreciated. I now know I'm not just being goofy about things too. Which is always good
Cheers
Tom
Philosophy: The art of never getting beyond the concept of life.
Religion: Morality taking credit for the work of luck.
|
|
|
|
|
If I have a c++ template class declared in Point.hpp file as below
template <typename>
class Point
{
....
}
If I want a new class derived from the above class in Node.hpp file but the data type is specialized to be double:
class Node: public Point<double>
{
...
}
When I compile the codes, the compiler complains that in Node.hpp that the base class Point is undefined. I know that I have included Point.hpp in Node.hpp. Why that error? Or how can I derived a node class (which should be a non template class) from a template Point class with double data type?
|
|
|
|
|
After fixing your posted fake code to be real code it compiles fine for me
|
|
|
|
|
Why not let the function decided the size of the _Result parameter?
It'll be (_Last1-_First1+1) + (_Last2-_First2+1) firstly, then the function knows to keep it lean, also it can keep the extra elements at the end in memory if any, then size() <= capacity().
What is the desiners' idea?
template<class class="" outputiterator="">
OutputIterator set_union(
InputIterator1 _First1,
InputIterator1 _Last1,
InputIterator2 _First2,
InputIterator2 _Last2,
OutputIterator _Result
);</class>
|
|
|
|
|
Who says the thing the output iterator applies to has a size? Consider this code:
#include <iostream>
#include <algorithm>
#include <iterator>
int main(int, char**)
{
int a[] = { 1, 2, 3, 4, 5 };
int b[] = { 2, 4, 6, 8 };
std::set_union(a, a+5, b, b+4, std::ostream_iterator<int>(std::cout, ", "));
return 1;
}
It writes 1, 2, 3, 4, 5, 6, 8, to standard output. No size involved there...
The STL design of containers, iterators and algorithms is all about generality - iterators do not (repeat DO NOT) have to be associated with containers - they are a more general concept than that.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
All right.
But there is another question, about this code:
vector<int> va, vb, v;
set_union::(va.begin(), va.end(), vb.begin(), vb.end(), v.begin());</int>
It courses a runtime error, because I haven't make v large enough.
I don't know why it is designed this way, why it can't be done inside the function.
|
|
|
|
|
That would pose a serious limitation to how the function can be used.
For example, this would not be possible.
set_union(v1.begin(), v1.begin() + 3, v2.begin(), v2.end(), v1.begin() + 4);
«_Superman_»
I love work. It gives me something to do between weekends.
|
|
|
|
|
followait wrote: I don't know why it is designed this way, why it can't be done inside the function.
In effect, it can be - use a back_inserter (which uses push_back to insert items) rather than a plain output iterator. To minimise allocations, use the reserve member of vector .
vector va, vb, v;
v.reserve(va.size() + vb.size());
set_union::(va.begin(), va.end(), vb.begin(), vb.end(), std::back_inserter(v));
That's one of those tricksy iterator adaptors I mentioned in an answer to one of your previous queries...
[edit]PS - I've told you why it's designed this way - to maximise generality.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
Hi,
The current application i'm working on has a single vector having a list of structures with data as well as a flag set (true/false). If flag is true , i'll add the vector data to string A else string B.
Is there a performance difference of having 2 vectors rather than having a single vector or it doesn't matter?
Thanks in advance,
Mayur M
|
|
|
|
|
mayur8u wrote: Is there a performance difference of having 2 vectors rather than having a single vector or it doesn't matter?
I don't think there'll be any significant performance difference.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
I have the following codes (partially copied for illustration) using template class:
template<typename T>
struct _BoundingBox
{
T x0, x1, y0, y1;
};
template<typename T>
class CMyObject
{
public:
typedef struct _BoundingBox<t> stBBOX;
CMyObject()
{
Init(); // do class initialization here
}
CMyObject(const CMyObject<t> &Obj) // copy constructor
{
// do some data copy here
....
_Box = Obj.GetBountingBox();
}
virtual ~CMyObject() {}
public:
stBBOX GetBoundingBox() { return _Box; }
protected:
stBBOX _Box;
};
int main(argc, char* argv[])
{
CMyObject<int> obj1
CMyObject<int> obj2(obj1);
}
After compile (using VC 2005, the compiler gave the following error message:
error C2662: 'CMyObject<t>::GetBoundingBox' : cannot convert 'this' pointer from 'const CMyObject<t>' to 'CMyObject<t> &'
with
[
T=int
]
Conversion loses qualifiers
However, if I change
_Box = Obj.GetBountingBox();
to
_Box = Obj._Box;
in the copy constructor, the error disappears.
Anyone knows what the problem is? Thanks. </t></t></t>
<div class="ForumMod">modified on Tuesday, February 24, 2009 5:18 PM</div>
|
|
|
|
|
You need to make GetBoundingBox a const method of CMyObject :
stBBOX GetBoundingBox() const { return _Box; }
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
Thanks. I tried according to your suggestion and it worked.
But i still didn't get it why GetBoundingBox() should be a const function? what if the return value is a pointer?
|
|
|
|
|
The return value doesn't matter - it's where you use GetBoundingBox:
CMyObject(const CMyObject<t> &Obj)
{
....
_Box = Obj.GetBountingBox();
}
You are saying that Obj is const. Given that, you can only perform const methods on Obj. So, to use GetBoundingBox there, it has to be a const method.
A const method is making a promise that it doesn't alter the object on which it's called.
_Box = Obj._Box is implicitly 'const', as you are reading a member variable (it's an rvalue).
The error message gcc gives for your code is a bit better than VC++'s:
a.cpp: In copy constructor ‘CMyObject<T>::CMyObject(const CMyObject<T>&) [with T = int]’:
a.cpp:34: instantiated from here
a.cpp:20: error: passing ‘const CMyObject<int>’ as ‘this’ argument of ‘_BoundingBox<T> CMyObject<T>::GetBoundingBox() [with T = int]’ discards qualifiers
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
I get an access violation when trying to add to a map in my release build. Since it works fine in debug, and if I turn off optimisations in release, I know its something I'm doing wrong. But I don't know what...
Interestingly (?), the code that fails is in a loop which works on the first iteration, and fails on the second, suggesting perhaps a problem with initialising (or reinitialising) something.
Any help or tips very much appreciated
The code that fails is (bold line):
ManInfo mi;
...
...
if (m_ManMap.count(lSubmainID) == 0)
{
mi.SubmainJunctionPt = m_pCADEngine->GetEntityPoint(pSubmainJnc->GetHandle(), 1);
mi.LatEndPt[0] = m_pCADEngine->GetEntityPoint(pFreeEnd->GetHandle(), 1);
mi.LatLen[0] = mi.SubmainJunctionPt.GetDistanceTo2D(mi.LatEndPt[0]);
mi.DistToRef = mi.SubmainJunctionPt.GetDistanceTo2D(m_ManRefPt);
m_ManMap[lSubmainID] = mi;
}
else
{
...
I have a structure thus:
struct ManInfo
{
Point3D SubmainJunctionPt;
Point3D LatEndPt[2];
double LatLen[2];
double DistToRef;
ManInfo()
{
SubmainJunctionPt.Construct(NO_ELEVATION, NO_ELEVATION, NO_ELEVATION);
LatEndPt[0].Construct(NO_ELEVATION, NO_ELEVATION, NO_ELEVATION);
LatEndPt[1].Construct(NO_ELEVATION, NO_ELEVATION, NO_ELEVATION);
LatLen[0] = -1.0L;
LatLen[1] = -1.0L;
DistToRef = -1.0L;
}
ManInfo& ManInfo::operator= (const ManInfo& second)
{
if (this != &second)
{
SubmainJunctionPt.Construct(second.SubmainJunctionPt);
LatEndPt[0].Construct(second.LatEndPt[0]);
LatEndPt[1].Construct(second.LatEndPt[1]);
LatLen[0] = second.LatLen[0];
LatLen[1] = second.LatLen[1];
DistToRef = second.DistToRef;
}
return *this;
}
};
And a map member variable thus:
typedef map<LONG, ManInfo> ManMap;
ManMap m_ManMap;
|
|
|
|
|
I don't know if it helps determine what the problem is, but I can fix it by disabling inline function expansion...
|
|
|
|
|
Given you've got an assignment operator, do you need a copy constructor as well? And a destructor?
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
Good suggestion Stuart, given that:
In C++, the implicitly declared assignment operator is a public and inline member function.
but it didn't help I'm afraid...
|
|
|
|
|