|
Unless there are convenient reasons not to, e.g., interacting with MFC serialization, I would go for STL. STL is generally much more powerful. As Neville says below there is a learning curve but it's worth it. Plus I found that STL was easier to use than it was to understand!
I often use CString in preference to string in an MFC app. because it makes for easier interaction with MFC controls, etc., and it has better functionality. For everything else I go for STL these days.
Kevin
|
|
|
|
|
Hi fellows,
Thank you for your lovely help.
Regards,
Shlomi
|
|
|
|
|
Hi,
I have created an ATL dll which has a modeless dialog box containing a WebBrowser control. My problem is that whenever I'm pressing TAB key over the WebBrowser control, the focus is not shifting to other controls or links within the web page which is getting displayed within the control.
I have implemented a hook to trap WH_GETMESSAGE message, after that I'm able to get response from the 4 arrow keys and TAB key, but that too within the dialog box.
I have to make the TAB key acting normal within the WebBrowser control that is within that dialog box.
Can anyone of you help me out? Thanks in advance.
Regards,
Ashish
|
|
|
|
|
The short answer is that the dialog owner needs to forward keystrokes to the CAxWindow that ATL uses to host the WB control. If you get the WTL AppWizard and use it to make a modeless dialog-based app, you'll see the necessary code in the generated PreTranslateMessage() .
--Mike--
LINKS~! Ericahist | 1ClickPicGrabber | CP SearchBar v2.0.2 | C++ Forum FAQ | You Are Dumb
|
|
|
|
|
Hi all,
I have really big problem w/ my web servervice.
I implemented the web server w/ ATL, so now I have a Cws ATL class that implements the web service and a CwsIsapi that implements the ISAPI extension. Then I am consuming this web service in C#.
/////////////////////// ATL WEB SERVER /////////////////////////
<br />
class Cws<br />
{<br />
[soap_method]<br />
HRESULT init ( int num) {<br />
m_mem = num;<br />
return S_OK;<br />
};<br />
[soap_method]<br />
HRESULT get_number ( int *val)<br />
{<br />
*val = num;<br />
return S_OK;<br />
}<br />
protected:<br />
int m_mem;<br />
};<br />
/////////////////////////////// C# CONSUMER ///////////////////////////////////////////
<br />
...<br />
mymachine.Cws service = new mymachine.Cws ();<br />
service.init (3);<br />
int val;<br />
service.get_number (out val);<br />
if (val != 3)<br />
{<br />
}<br />
...<br />
This code DOES NOT WORK !!!
In fact when
"service.get_number (out val)"
is invoked, an instance of Cws is created then destroyed, so when
"service.get_number (out val)"
is invoked, the instance is different and m_mem is not initialized to 3 any more !!!
Is there any way in order to change this behaviour?
Any help will be appreciated.
Thanx very much.
Regards,
Andrea
|
|
|
|
|
Web services are a stateless RPC protocol. After the call is finished the instance is destroyed. There is a way to enable session state in web services but I don't know how to do it in ATL. Information on How To Enable session state in a C# Web service is located at the following link.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconstatemanagementinaspnetwebservices.asp
Best of luck
Forever Developing
|
|
|
|
|
Hello,
I have created a Dll by ATL and I want
to #import it in my MFC App.
How can I use the classes inside my DLL?
Best Wishes,
Thanks.
|
|
|
|
|
|
Some years ago I was fourced to write a VB program that required TAPI support for data modem. Well now I have to fix it since the PDQTapi control has a bug in it that crashes crashes (closes) the program when the a HangUp command is issued (On Win2000/XP). I have written a C++ class to replace it and am writing an ActiveX control (using ATL) as a drop in replacement.
Problem (in VB): PlaceCall(varControl,szPhone As String)
PDQTapi.PlaceCall(PDQCom,szPhone)
Questions:
1) What argument (PDQComm) type do I specify to allow a control to be passed to the new control.
2) There is anouther method that can take any control type as long as it has a SetItem method.
My ATL 3.0 COM book does not seem to have the answer, but I am still looking there and on the net.
Thanks for any help you can give.
TaTa!
INTP
|
|
|
|
|
I just realize that it is probably a VARIANT or VARIANTARG.
INTP
|
|
|
|
|
Yup. Typically, you QI the control for IUnknown or IDispatch, and set the variant type accordingly (VT_UNKNOWN, VT_DISPATCH).
Steve S
Developer for hire
|
|
|
|
|
Hi, I have a dll that runs in the address space of Explorer. (Shell extension)
So i do not have a main app, just a dll. I could use either MFC or ATL.
My problem is i need to know when a Windows Shutdown event is being fired. I've never had this problem before because all my apps have a main window and receive this notification. However the dll just keeps working and terminates in an undetermined state.
I can't have the dll called from an app. I have no alternative but to use what i've got.
how can i register to receive a WM_SHUTDOWN event from my dll?
Please don't suggest i change the design of the solution. I'm confined to what i have.
thanks in advance
Carl
|
|
|
|
|
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.
|
|
|
|
|