|
You may try to use a Windows hook - WH_GETMESSAGE or WH_CALLWNDPROC and monitor WM_ENDSESSION message.
Just a thought...
|
|
|
|
|
Igor, where were you yesterday?
That's exactly what i did and it gives me the desired notification. - thanks.
I would be interested in another method though if you have any thoughts.
Kind Regards
Carl
|
|
|
|
|
I would like to insert some controls (such as button or combo box) into
the cell of the ActiveX FlexGrid in MFC, How can I do it?
I found there is really not much resource about the FlexGrid on the Web.
|
|
|
|
|
Hello!
I'm trying to insert an ActiveX control written in VB into an ATL program. I've got it inserted, but can't execute any methods.
Here's the relevant Code:
BOOL CPageMarksBar::RegisterAndCreateWindow()
{
RECT rect;
::GetClientRect(m_hWndParent, &rect);
m_hWnd = ::CreateWindow(TEXT("STATIC"),
TEXT("Insert ActiveX Control Here"),
WS_CHILD | WS_VISIBLE | SS_CENTER,
rect.left, rect.top,
rect.right - rect.left,
rect.bottom - rect.top,
m_hWndParent,
NULL,
NULL,
NULL);
USES_CONVERSION;
CComPtr<IUnknown> spUnk;
CComPtr<IUnknown> spOut;
HRESULT hRet = AtlAxCreateControlEx(T2COLE("ActiveLinksControl.ActiveLinks"), m_hWnd, NULL, &spUnk, &spOut, IID_NULL, NULL);
HRESULT hrQI1 = spOut.QueryInterface(&m_pAlinks);
return ::IsWindow(m_hWnd);
}
I've also added:
#import "ActiveLinksControl.ocx" named_guids,raw_interfaces_only
using namespace ActiveLinksControl;
---
Now, this contains a class ActiveLinks, which I've tried to access, but I keep getting errors like "error C2027: use of undefined type 'ActiveLinks'error C2027: use of undefined type 'ActiveLinks'" and "Undeclared identifier"
Please help, because this is really annoying!!!
Best Regards,
David G
Did you realise that Watford Junction is the only station in East Anglia served by Virgin Trains.
|
|
|
|
|
I have a set of int's and string's that have a one-to-one relationship with each other. There are never any duplicates on either side. Whats the best collection class to hold these pairs so that it is easy to find an entry given either the left or right hand value of the pair?
std::map has a find function but it only finds on the 'key' field, I also need the equivalent for the 'value' field.
|
|
|
|
|
Hi Paul,
I wrote a class called bimap which seems to me is exactly what you're looking for. Check it out here[^] (Caveat, it does not work for MSVC 7.1.)
The original idea of bimap , namely to maintain several access orders over the same set of elements, has been much expanded in a Boost library called Boost.MultiIndex[^]. A bidirectional map is just a particular case of what can be achieved with Boost.MultiIndex (though the syntax is not as terse as in bimap .) Boost.MultiIndex works for MSVC 7.1 and is generally much more powerful, so I'd recommend going for this.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
Want a Boost forum in Code Project? Vote here[^]!
|
|
|
|
|
Hello!
I've implemented IShellExtInit and IContextMenu and followed the Complete Idiots guide by Michael Dunn. But I'm using ATL7.0 and some stuff is different. Like the CComModule has been replaced. From MSDN:
"As of ATL 7.0, CComModule is obsolete: see ATL Module Classes for more details."
The wizard in VS.NET 2003 implemented CAtlDllModuleT . Everything compiles, but my class (T2TContextMenu) isn't called (I have set up breakpoints in all functions). I've checked the registry and my key is there:
HKEY_CLASSES_ROOT\.omfg\ShellEx\ContextMenuHandlers\This2That
default value = "{3E670573-EA3F-498A-8EB1-F72DA6B5D221}" as a string
The only difference I can see between my code and the tutorial is in the DllMain() . The tutorial calls _Module.Init(ObjectMap, hInstance, &LIBID_SIMPLEEXTLib); and has a Object map that includes the COM class the DLL is going to use. Mine doesn't. So my guess is that I have to pass the CLSID and maybe my classname somewhere to CAtlDllModuleT .
MSDN gave me this:
"Init and Term methods have moved into the constructors and destructors for the module classes; there is no longer a need to call Init and Term."
VS.NET created CThis2That like this:
class CThis2ThatModule : public CAtlDllModuleT< CThis2ThatModule >
{
public :
DECLARE_LIBID(LIBID_This2ThatLib)
DECLARE_REGISTRY_APPID_RESOURCEID(IDR_THIS2THAT, "{3E670573-EA3F-498A-8EB1-F72DA6B5D221}")
};
And CT2TContextMenu like this (I added the IShellExtInit/IContextMenu stuff):
class ATL_NO_VTABLE CT2TContextMenu :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CT2TContextMenu, &CLSID_T2TContextMenu>,
public IDispatchImpl<IT2TContextMenu, &IID_IT2TContextMenu, &LIBID_This2ThatLib, 1, 0>,
public IShellExtInit,
public IContextMenu
{
public:
CT2TContextMenu(){}
DECLARE_REGISTRY_RESOURCEID(IDR_T2TCONTEXTMENU)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CT2TContextMenu)
COM_INTERFACE_ENTRY(IT2TContextMenu)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IShellExtInit)
COM_INTERFACE_ENTRY(IContextMenu)
END_COM_MAP()
HRESULT FinalConstruct(){ return S_OK; }
void FinalRelease() {}
public:
STDMETHOD(Initialize)(LPCITEMIDLIST, LPDATAOBJECT, HKEY);
STDMETHOD(GetCommandString)(UINT, UINT, UINT*, LPSTR, UINT);
STDMETHOD(InvokeCommand)(LPCMINVOKECOMMANDINFO);
STDMETHOD(QueryContextMenu)(HMENU, UINT, UINT, UINT, UINT);
private:
};
So... How do I pass my CT2TContextMenu COM implementation to the CAtlDllModuleT implementation (called CThis2That )?
Or is it something else?
Cheers!
/JP
|
|
|
|
|
Hmmm... do you have an instance in your module of CThis2That ? I.e. like:
CThis2That myModuleThingyStuff;
I think you need it because then the constructor/destructor of it will be called when the DLL is loaded (and _Module.Init()/ .Term() will also be called).
Hope that helps,
/Rob
|
|
|
|
|
Yes, VS.NET created that for me. There's a global
CThis2ThatModule _AtlModule;
Init() is completely gone according to MSDN and is "replaced" by the constructor. While Term() is still there it's called by the destructor.
What I don't know how to do is how I should pass my CT2TContextMenu so CThis2ThatModule will register it or whatever it's called. When the Init() function was available in ATL3.0 there was a object map and that was passed to _TheGlobalModule.Init(), this is where my CT2TContextMenu would've been passed. But I don't know how to do it in ATL7.0...
|
|
|
|
|
The tutorial had this:
BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_SimpleShlExt, CSimpleShlExt)
END_OBJECT_MAP()
_Module.Init(ObjectMap, hInstance, &LIBID_SIMPLEEXTLib);
What I found out from MSDN is that that type of object map has been replaced by OBJECT_ENTRY_AUTO and inspecting my code VS.NET had already generated this for me:
OBJECT_ENTRY_AUTO(__uuidof(T2TContextMenu), CT2TContextMenu)
What I've understood that means that the main module object does has some kind of reference to my context menu. But why isn't it called?
|
|
|
|
|
I have an input BSTR which I am having problems with converting to a char*. I have tried:
STDMETHODIMP MYCLASS::MyFunction( BSTR bsInput )<br />
{<br />
USES_CONVERSION;<br />
...<br />
char* pInput = OLE2T( bsInput );<br />
...<br />
}
this was fine until I tried using really big input strings say 1,000,000 chars in length. Then I tried:
STDMETHODIMP MYCLASS::MyFunction( BSTR bsInput )<br />
{<br />
USES_CONVERSION;<br />
...<br />
int iLen = lstrlenW( bsInput );<br />
char* pInput = ATLW2AHELPER( ( LPSTR ) new char[ iLen ], bsInput, iLen );<br />
...<br />
}
This causes a memory leak.
I am at present stumped, and would appreciate some advise.
|
|
|
|
|
I think in this case, I'd write some 'proper' code to do it...
eg:
char* pConv = new char[iLen+1];
WideCharToMultiByte(....)
...
delete [] pConv;
This is essentially what the conversion macros do, but some versions of them use the stack, I think, which is why big strings kill them.
Heap is better in this regard , but you have to remember to free them afterwards.
Steve S
Developer for hire
|
|
|
|
|
Thanks, I had just come to the same conclusion after studying the code for ATLW2AHELPER( ... ) in the strconv.h
I have now implemeted thus:
char* pInput = new char[ iLen+1 ];
int retval = WideCharToMultiByte( CP_ACP, 0, bsString, -1, pInput, iLen+1, NULL, NULL );
and was just testing for memory leaks (none found) due to the delete [] pInput;
Thanks again, very frustrating it was.
|
|
|
|
|
I found the _bstr_t class for such conversions a little gem (it's part of the VC6 COM support classes in comdef.h or comutil.h)
internally it always holds a BSTR, and caches it's char * representation after you asked for it once. Further, it is reference counted with copy-on-write semantics,
So you can:
_bstr_t bstr(myBStr, false);
char const * p = bstr;
It's not always perfect, but nice to know.
we are here to help each other get through this thing, whatever it is Vonnegut jr. boost your code || Fold With Us! || sighist | doxygen
|
|
|
|
|
Thanks, I tried it with a BSTR containing 1,000,000 chars and it threw an exception. I will stick with WideCharToMultiByte .
|
|
|
|
|
weird, works fine for me.
idea: if you use _bstr_t(s, false), the BSTR is attached, and is freed by the _bstr_t destructor (unfortunately, it lacks an "detach"). Maybe a double release is causing the problem.
But it's just an recommendation anyway. If you don't care about a copy, asciiOrWideString = _bstr_t(asciiOrBSTR) is a very convenient thing, and can be use as argument / return parameter, too.
we are here to help each other get through this thing, whatever it is Vonnegut jr. boost your code || Fold With Us! || sighist | doxygen
|
|
|
|
|
(a) Is this possible with std::map, and a custom allocator?
I'd say so.
(b) Is this possible for VC6 with it's "half-an-STL"?
A little more difficult, but doable, I think.
(c) Anyone done this already? (available?)
I've got a block allocator[^] for VC++ 6.0 with a little more complicated allocation policy (caveat, it doesn't work in VC++ 7.1.) It shouldn't be hard to tweak it to meet your requirements. In case you decide to follow down this track, tell me so and I can try to give you assistance.
Also, Boost has an allocator library (Boost.Pool) but after a quick glance seems like it doesn't have what you're after, and it doesn't support VC++ 6.0 evil allocator interface.
(d) Anyone having performance data for that?
No, but I'm pretty sure you'll get a brutal performance boost (VC++ 6.0 malloc , on which std::allocator is based, is notably slow.)
HTH
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
Want a Boost forum in Code Project? Vote here[^]!
|
|
|
|
|
Thanks for your answer.
Regarding (a):
If I understand Scott Myers correctly, a custom allocator cannot be "stateful", i.e. the pool may not be a non-static member of the allocator class.
I want each mymap instance to have it's own pool.
As I understand the common implementation, the allocator is a non-static member of the class, so the problem would occur only when items are moved from one container to the other (which could be prevented due to encapsulation). But I don't want to jump through all STL allocator weirdness (esp. on VC6) when it's a non-standard solution.
So is there a trick around the problem? IIRC the VC6 STL cannot promote from allocator<x> to allocator<y> which might be required for it.
we are here to help each other get through this thing, whatever it is Vonnegut jr. boost your code || Fold With Us! || sighist | doxygen
|
|
|
|
|
Strictly speaking, allocators should be made stateless, but fortunately for you Dinkumware STL properly handles stateful allocators. The issue does not ocur when moving items around, but rather when swapping (and only when swappng.) So, if it suits your particular app I'd go with stateful allocators.
So is there a trick around the problem? IIRC the VC6 STL cannot promote from allocator to allocator which might be required for it.
This is a different problem. Yes, VC6 does not support the rebind mechanism, so either your allocator is generl enough to provide chunks of whatever size (via the non-standard _Charalloc memebr function) or you somehow precalculate the size of the chunks the allocator will be requested for a particular container instantaiation. I've done the latter in my block_allocator , you might want to check it out.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
Want a Boost forum in Code Project? Vote here[^]!
|
|
|
|
|
I believe that this may be possible, however it's not something that I'd like to write. ATM Ion Gaztañaga has been proposing an implementation of a shared memory library to be added to boost on the boost-dev mailing list. I assume that this might have some commonality with the code that you would need to write, if not, it's another source of architectures for designing allocators. http://news.gmane.org/gmane.comp.lib.boost.devel[^]
Have you considered other alternatives to using a custom allocator? boost multi-index[^] might offer you the ability to manage ownership in one container and to use an optimised 'map-like' interface for accessing data.
Loki::AssocVector is a vector which supports some map operations Loki[^]
This would make a great article if you get it to work (and you're allowed to write about it ) It would be nice to know what types of performance constraints and requirements have driven you to consider this, and how much help the solution provided
If you can keep you head when all about you
Are losing theirs and blaming it on you;
If you can dream - and not make dreams your master;
If you can think - and not make thoughts your aim;
Yours is the Earth and everything that's in it.
Rudyard Kipling
|
|
|
|
|
boost multi-index might offer you the ability to manage ownership in one container and to use an optimised 'map-like' interface for accessing data.
I'm afraid Boost.MultiIndex is not designed to solve peterchen's problem. Allocation of elements is done through the same allocator interface as regular STL containers. Again, a custom pool allocator would be needed.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
Want a Boost forum in Code Project? Vote here[^]!
|
|
|
|
|
Andrew Walker wrote:
This would make a great article if you get it to work (and you're allowed to write about it )
Yeah you leeches!
Andrew Walker wrote:
It would be nice to know what types of performance constraints and requirements have driven you to consider this
I regularly need a containers that are "only growing" (i.e. no elements are removed until the map is destroyed completely). Most common is a map, which is the "performance bully" (sucking the most allocations and CPU cycles). While not an immediate problem at one point, I notice I'm always hesitant to use a map for that very reason (many of these are generic components in turn, and I have no idea in advane how they are used. Mostly, my collegues either ignore them completely, or drive them to the limits and beyond in 23 seconds )
I was thinking about a "reduced map" implementation, that starts with a pool allocator, and switches to the normal allocator only after memory is wasted by a factor of two or something. (would involve a copy of the nodes at that point, but that's usually ok for my appplications)
we are here to help each other get through this thing, whatever it is Vonnegut jr. boost your code || Fold With Us! || sighist | doxygen
|
|
|
|
|
Please find below a (working) prototype for the kind of stuff you're looking for. Things to keep in mind:- The allocator does not check whether it's running out of space. It is up to you to dimension the pool appropriately
- No alignment issues are consided, though this is not a problem on Intel architectures.
Please consider this as a very rough prototype, but it can get you started.
#include <stddef.h>
template<typename T,size_t pool_size>
class brute_allocator
{
public:
brute_allocator():
pool(new char[pool_size]),next(pool)
{}
brute_allocator(const brute_allocator&):
pool(new char[pool_size]),next(pool)
{}
brute_allocator& operator=(const brute_allocator&)
{
return *this;
}
~brute_allocator()
{
delete[]pool;
}
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T *pointer;
typedef const T *const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T value_type;
template<typename Other> struct rebind
{
typedef brute_allocator<Other,pool_size> other;
};
pointer address(reference x)const{return &x;}
const_pointer address(const_reference x)const{return &x;}
pointer allocate(size_type n,const void *hint=0)
{
return reinterpret_cast<pointer>(_Charalloc(sizeof(T)));
}
char* _Charalloc(size_type n)
{
char* res=next;
next+=n;
return res;
}
void deallocate(void *p,size_type n)
{
}
void construct(pointer p,const T& val)
{
new ((void *)p) T(val);
}
void destroy(pointer p)
{
p->T::~T();
}
size_type max_size()const
{
size_type n=(size_type)(-1)/sizeof(T);
return (0<n?n:1);
}
bool operator ==(const brute_allocator& x) const
{
return this==&x;
}
bool operator !=(const brute_allocator& x) const
{
return this!=&x;
}
bool operator <(const brute_allocator&) const;
bool operator >(const brute_allocator&) const;
private:
char* pool;
char* next;
};
#include <map>
#include <iostream>
typedef brute_allocator<int,20000> b_allocator;
typedef std::map<int,int,std::less<int>,b_allocator> fast_map;
int main()
{
fast_map fm;
for(int i=0;i<500;++i)fm[i]=2*i;
for(fast_map::iterator it=fm.begin(),it_end=fm.end();it!=it_end;++it){
std::cout<<it->first<<" "<<it->second<<std::endl;
}
return 0;
}
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
Want a Boost forum in Code Project? Vote here[^]!
|
|
|
|
|
I'd like to use a pool allocator for a given instance of a container (not all instances)
Imagine I have a map from which items are never removed, until the map is deleted.
The map items should be allocated from a pool, i.e. a special allocator that does not track individual allocations, but releases *all* memory when the map is destroyed.
The map is completely encapsulated and does not need to expose container behavior.
(a) Is this possible with std::map, and a custom allocator?
(b) Is this possible for VC6 with it's "half-an-STL"?
(c) Anyone done this already? (available?)
(d) Anyone having performance data for that?
we are here to help each other get through this thing, whatever it is Vonnegut jr. boost your code || Fold With Us! || sighist | doxygen
|
|
|
|
|
Can someone tell me why the following doesn't compile:
#include <list>
using namespace std;
class CSort
{
public:
CSort(int i) : m_i(i) { }
int m_i;
};
struct lessThan : public greater<CSort>
{
bool operator()(const CSort &pfi1, const CSort &pfi2) const
{
return pfi1.m_i < pfi2.m_i;
}
};
void SortTest()
{
list<CSort> l3;
l3.push_back(CSort(11));
l3.push_back(CSort(01));
l3.push_back(CSort(21));
l3.push_back(CSort(14));
l3.push_back(CSort(41));
l3.sort(lessThan());
}
int main(int argc, char* argv[])
{
SortTest();
return 0;
}
it gives me the following errors:
C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\functional(80) : error C2784: 'bool __cdecl std::operator >(const class std::list<_Ty,_A> &,const class std::list<_Ty,_A> &)' : could not deduce template argument for 'const class std::list<_Ty,_
A> &' from 'const class CSort'
C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\functional(80) : while compiling class-template member function 'bool __thiscall std::greater<class csort="">::operator ()(const class CSort &,const class CSort &) const'
C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\functional(80) : error C2784: 'bool __cdecl std::operator >(const class std::reverse_iterator<_RI,_Ty,_Rt,_Pt,_D> &,const class std::reverse_iterator<_RI,_Ty,_Rt,_Pt,_D> &)' : could not deduce te
mplate argument for 'const class std::reverse_iterator<_RI,_Ty,_Rt,_Pt,_D> &' from 'const class CSort'
C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\functional(80) : while compiling class-template member function 'bool __thiscall std::greater<class csort="">::operator ()(const class CSort &,const class CSort &) const'
C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\functional(80) : error C2784: 'bool __cdecl std::operator >(const struct std::pair<_T1,_T2> &,const struct std::pair<_T1,_T2> &)' : could not deduce template argument for 'const struct std::pair<
_T1,_T2> &' from 'const class CSort'
C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\functional(80) : while compiling class-template member function 'bool __thiscall std::greater<class csort="">::operator ()(const class CSort &,const class CSort &) const'
C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\functional(80) : error C2676: binary '>' : 'const class CSort' does not define this operator or a conversion to a type acceptable to the predefined operator
C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\functional(80) : while compiling class-template member function 'bool __thiscall std::greater<class csort="">::operator ()(const class CSort &,const class CSort &) const'
thanks.
|
|
|
|
|