|
VC++ 6.0 SP5
I have an MFC dialog application and I wanted to expose a COM interface for it so that other apps may call the interface while the dialog is up and running. I wanted to make the application free threaded so that calls to the interface from multiple clients would not be serialised.
I have done this by clicking on the Insert menu in VC6 and selecting 'New ATL Object...'. Once the object was inserted into the project I then edited stdafx.h and replaced _ATL_APARTMENT_THREADED with _ATL_FREE_THREADED. I then changed the ATL class so that it derives from CComObjectRootEx<CComMultiThreadModel>.
Testing has shown that when multiple clients call the interface the calls are all serialised because the ATL object in the dialog application is running on the UI thread. Is there any way in an MFC app to force COM to pick an RPC-managed pool thread rather than do all the work on the UI thread?
Regards
Martin
|
|
|
|
|
|
Did you initialize the apartment as multithreaded? See CoInitializeEx (or AfxInitializeOle, or whatever it's called in MFC)
--
Wir müssen leben bis wir sterben.
|
|
|
|
|
Thanks. That was the problem.
Regards
Martin
|
|
|
|
|
Hello!
I am yet learning MFC, but I intened to learn the ATL and WTL... What I want to ask is that what the WTL really is, what are the benifits of it over MFC. Also, please guid me about the ATL as well...
Polite Programmer
More Object Oriented then C#
|
|
|
|
|
Read Michael Dunn's post in the thread "ATL / STL : Dumb question maybe" just a few lines below
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
Want a Boost forum in Code Project? Vote here[^]!
|
|
|
|
|
Thanx a lot... You guided me well... However, Just few more questions... What are the benifits of using WTL over MFC?(if any...) Moreover, I am learning MFC... Any tips to minize the learning curve will be helpfull, Also, when it is a good time to learn ATL?
Lastly, How you see the future of MFC/ATL/VC++ in the world of .NET (especially, please consider the 'interpreted' nature of .NET...)
Moreover, if Microsoft is not maintaining WTL, then who is?
Polite Programmer
More Object Oriented then C#
|
|
|
|
|
First of all, I know very little about ATL, so some of my responses are tentative at best.
What are the benifits of using WTL over MFC?
It is cleaner, it does not suffer from some design defects affecting MFC (most notably in multithreading issues) and does not impose a complete framework on you (that meaning, you can add just a bit of WTL to an otherwise perfectly regular Win32. MFC, OTOH, forces you to write the whole app according to the framework it provides.)
On the cons side, WTL does not provide you with wizards (I think) and it is somewhat harder to learn, as the tecnhiques it relies on are more advanced.
Also, when it is a good time to learn ATL?
I couldn't say. Probably, knowing some UI stuff (plain Win32 or MFC) before delving into WTL is good.
Lastly, How you see the future of MFC/ATL/VC++ in the world of .NET (especially, please consider the 'interpreted' nature of .NET...)
I think WTL just does not apply to .NET UI.
Moreover, if Microsoft is not maintaining WTL, then who is?
http://sourceforge.net/projects/wtl/[^]
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
Want a Boost forum in Code Project? Vote here[^]!
|
|
|
|
|
MFC is not only a set of classes, it is an entiere framework.
if you plan to program a console based program, you won't use MFC...
more, STL (standard template library) provides a collection of containers and algorythms that permit to manipulate every types (it is the purpose of the templates).
TOXCCT >>> GEII power
|
|
|
|
|
I found 2-byte leak in my application, and trying to detect it I cut everything except this:
class CMyWindow : public CWindowImpl<CMyWindow>
{
public:
DECLARE_WND_CLASS("MyName")
BEGIN_MSG_MAP(CMyWindow)
MESSAGE_HANDLER(WM_PAINT, OnPaint)
END_MSG_MAP()
LRESULT OnPaint(UINT nMsg, WPARAM wParam,
LPARAM lParam, BOOL& bHandled)
{
return 0;
}
};
extern "C" int WINAPI _tWinMain(HINSTANCE , HINSTANCE hPrevInstance,
LPTSTR , int nShowCmd)
{
#ifdef _DEBUG
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF);
#endif
{
ATLASSERT(AUX_SUCCEEDED(OleInitialize(0) == S_OK));
AtlAxWinInit();
{
CMyWindow w;
w.Create(0, 0, 0, WS_OVERLAPPEDWINDOW);
w.DestroyWindow();
}
AtlAxWinTerm();
OleUninitialize();
}
#ifdef _DEBUG
if (_CrtDumpMemoryLeaks())
::MessageBeep(MB_ICONEXCLAMATION);
#endif
}
The following dump is written to output:
Detected memory leaks!
Dumping objects ->
{49} normal block at 0x00944D70, 2 bytes long.
Data: < > DA C2
Object dump complete.
When I comment out w.Create(0, 0, 0, WS_OVERLAPPEDWINDOW); leak disappears.
Then I created another program, almost the same:
#define WIN32
#define _WINDOWS
#define _CRTDBG_MAP_ALLOC
#define _ATL_MIN_CRT
#define _DEBUG
#include <windows.h>
#include <comutil.h>
#include <stdio.h>
#include <tchar.h>
#include <atlbase.h>
#include <atlwin.h>
#include <windows.h>
class CMyWindow : public CWindowImpl<CMyWindow>
{
public:
DECLARE_WND_CLASS("MyName")
BEGIN_MSG_MAP(CMyWindow)
MESSAGE_HANDLER(WM_PAINT, OnPaint)
END_MSG_MAP()
LRESULT OnPaint(UINT nMsg, WPARAM wParam,
LPARAM lParam, BOOL& bHandled)
{
return 0;
}
};
extern "C" int WINAPI _tWinMain(HINSTANCE , HINSTANCE hPrevInstance,
LPTSTR , int nShowCmd)
{
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
HANDLE logFile;
logFile = CreateFile("bstr_t_leak_LOG.txt", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_WARN, logFile);
_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_ERROR, logFile);
_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_ASSERT, logFile);
{
ATLASSERT(OleInitialize(0) == S_OK);
AtlAxWinInit();
{
CMyWindow w;
w.Create(0, 0, 0, WS_OVERLAPPEDWINDOW);
w.DestroyWindow();
}
AtlAxWinTerm();
OleUninitialize();
}
exit(0);
}
and there is no leak!
|
|
|
|
|
You can try to identify the code which allocates this particular memory block using
_CrtSetBreakAlloc(49);
where the 49 is the chunk number from the leaked memory report. In debug mode, your app will break into the debugger when it is allocated. Since the number is so low, it seems like it is constant in your application. If it isn't, it will get a little bit more complicated.
HTH
|
|
|
|
|
I have a Class CMyEdit which is inherit from CWindowImpl class and contains the Message Map for LButtonDown message.
Now at run time I want to attach this class with Edit box using its window handler and want to capture the LButtondown event. Problem is i am not able to capture the LButtonDown message even if CMyEdit class is attached to Edit box.
Code below show the way i am doing it.
<br />
class CMyEdit : public CWindowImpl <CMyEdit><br />
{<br />
BEGIN_MSG_MAP(CMyEdit)<br />
MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)<br />
END_MSG_MAP()<br />
<br />
};<br />
<br />
<br />
CMyEdit oMyEdit;<br />
oMyEdit.Attach(hWdnEdit);
<br />
thanks
qur
|
|
|
|
|
Is possible to use ATL 7.0 in VC.6 ?
I want to use CRBMultiMap template, but unfortunately I had to use VC 6.0.
Thanks.
Rodrigo Pinho Pereira de Souza
|
|
|
|
|
install the correct SDK...
TOXCCT >>> GEII power
|
|
|
|
|
Will STL's multimap do what you want?
Kevin
|
|
|
|
|
Yes, but it'll require the crt libraries...
--
Wir müssen leben bis wir sterben.
|
|
|
|
|
And what's wrong with that? VC6 has them.
Kevin
|
|
|
|
|
There's nothing wrong with them per se, unless you're trying to avoid them for size reasons.
--
Wir müssen leben bis wir sterben.
|
|
|
|
|
Hi all,
I am new to STL and am developing an application that will take any kind of values as keys.But the key_compare function object is then making a comparison of the addresses of the keys rather than their values. Can somebody tell me how should i go about in my attempt to compare the values of the keys and not their addresses. Sample code below:
<code>#include<map>
#include<iostream>
int main()
{
using namespace std;
map< void*,void*,less<void*> > m1;
map< void*,void*,less<void*> >::key_compare kcl=m1.key_comp();
map< void*,void*>::iterator pIter;
char* do=new char[100];
strcpy(do,"this");//key1
char* dont="that";//value mapped with key1
m1.insert(map< void*,void*,less<void*> >::value_type(do,dont));
char* do1=new char[100];
strcpy(kc,"this");//key2
char* dont1="that";//value mapped with key2
m1.insert(map< void*,void*,less<void*> >::value_type(do1,dont1));
//problem is in next line-how do i compare the values in the keys..what
//happens now is a comparison of address
bool bresult=kcl(do,do1);//this should always return true as values
//are equal
if(bresult==true)
{
cout<<"Match";
for(pIter=m1.begin();pIter!=m1.end();pIter++)
{
cout << " " << (char *)(pIter -> first);
cout << "." << endl;
}
}
else
{
cout<<"Mismatch";
for(pIter=m1.begin();pIter!=m1.end();pIter++)
{
cout << " " << (char *)(pIter -> first);
cout << "." << endl;
}
for ( pIter = m1.begin( ) ; pIter != m1.end( ) ; pIter++ )
cout << " " << (char *)(pIter -> second);
cout << "." << endl;
}
cin.get();
}</code>
"When life offers you Lemons,Learn to make Lemonade"
|
|
|
|
|
As you point out yourself, having void * as the key type for your map defaults to comparing addresses instead of the contents. One easy solution is to use something better behaved as the key, like std::string (this, also, has the nice extra benefit that you are not risking storing pointers to deleted contents, as it can be the case with your current scheme.)
But I guess you have a valid reason for storing void pointers inetsad, since you talk about "an application that will take any kind of values as keys". If you absolutely need to store void pointers, how do you expect your app to work when the keys stored are of different types? (like for instance one is pointing to a char array and the other to a double )
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Thanks for the quick response Joaquin..Well actually i would be comparing like valued keys only(there will be a sort of switch case to compare keys of same type)so issue of keys being of different types does not affect me.This is precisely why am going for a void *.
As regards storing pointers to deleted contents,i shall be using smart pointers so that issue will also be taken care of.
What i am looking for is some kind of an overloaded function for less trait in the map that does the comparison here for the values and not the addresses.Is that possible?
|
|
|
|
|
Well, you can have something like this:
struct void_ptr_compare
{
bool operator()(void* x, void* y)const
{
return strcmp((const char *)(x),(const char *)(y))<0;
}
};
...
map< void*,void*,void_ptr_compare > m1;
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
that solves all my problems(for now at least). Exactly what i wanted but did not know how to go about it. Thanks Joaquin!!
|
|
|
|
|
I have created a custom listview in which different control (Edit, Combo, Button) are placed on each subitem.
Now every time Items are redrawn whole screen flicker. Reason for this that came to my mind is movement of each control that causes the flickering effect. I have already using the DeferPos function to move the controls in one go.
How can i remove the flicker problem. Secondly is this a correct approach to show control on each subitem.
Thanks
|
|
|
|
|
Hi,
I have the following struct:
<br />
typedef struct _MyStruct {<br />
int one;<br />
int two;<br />
} *pMyStruct, MyStruct;<br />
from which I constructed vector:
<br />
typedef std::vector<MyStruct> MyStructContainer;<br />
typedef std::vector<MyStruct>::iterator MyStructIter;<br />
In the one of my functions, I walk through all elements of vector:
<br />
MyStructContainer c;<br />
MyStructIter iter;<br />
pMyStruct p;<br />
<br />
for (iter = c.begin(); iter != c.end(); iter++)<br />
{<br />
<br />
};<br />
How to get a pointer to MyStruct by iterator?
Sincerely Yours,
RadioShark
|
|
|
|
|