|
I've written a Windows service with the help of the VS2008 ATL project wizard. I've added a ATL simple object which I hope will allow external processes to interact with my service via its interface.
1. I assume I can use the _AtlModule global variable to achieve this. Is it safe to call _AtlModule methods from the ATL simple object, e.g. _AtlModule.MyMethod(x)?
2. I plan to write some ASP server side script and use Server.CreateObject("xxxx.yyyyy") to access the service using the ATL simple object I created. (a) Will this be possible? (b) Are there any special permissions that will need to be set in IIS or anywhere else (I'm using Windows Server 2003)?
3. Does the service need to be running for such a call to succeed or will it be started?
Sorry for all the questions but I've never written a Windows service like this before.
Thanks in advance.
|
|
|
|
|
markiemooster wrote: Sorry for all the questions but I've never written a Windows service like this before.
Then I strongly urge you to find, read and understand materials that explain what services are. You do not seem to be on the correct track with services at this time.
Introduction to Windows Services[^]
led mike
|
|
|
|
|
Thanks Mike. But I've written about half a dozen or so services in my time. Perhaps you weren't aware that you can create an ATL COM service using the VS2008 project wizard?
You choose the ATL Project template. In the Applications Settings dialog box, select the "Service" radio button. Now add an ATL class in the usual manner: "Add", "Class", "ATL Simple Object".
All that aside, could someone please shed some light on my queries.
Thanks.
|
|
|
|
|
markiemooster wrote: 1. I assume I can use the _AtlModule global variable to achieve this. Is it safe to call _AtlModule methods from the ATL simple object, e.g. _AtlModule.MyMethod(x)?
2. I plan to write some ASP server side script and use Server.CreateObject("xxxx.yyyyy") to access the service using the ATL simple object I created. (a) Will this be possible? (b) Are there any special permissions that will need to be set in IIS or anywhere else (I'm using Windows Server 2003)?
3. Does the service need to be running for such a call to succeed or will it be started?
1. Depends on what you mean by "safe"...
Your service may be accessed from different applications which means that you have to make it thread safe.
2(a). I suppose that you are limited to automation compatible interfaces when using scripting languages, but that's fine.
2(b). I don't think so, but that may depend more on what you're trying to do from your service than the fact that you're exposing COM objects from it. You also have to call ::CoInitializeSecurity() in your wizard generated class derived from CAtlServiceModuleT . At least
CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_NONE,
RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL );
3. No, the service doesn't have to be started, but it must be installed as a service. The service is started when the client tries to create an instance of an object that the service exposes.
"It's supposed to be hard, otherwise anybody could do it!" - selfquote "High speed never compensates for wrong direction!" - unknown
|
|
|
|
|
Hello everyone,
When writing an ATL COM server, MIDL compiler will automatically generated file _i.c and _i.h from IDL definition.
My question is whether my below usage for the two files are correct when writing a COM client (consumer)?
1. I put _i.h file into the "Header files" of the client project, and using it to make the build for client project;
2. I put the _i.c into the "Source files" of the client project, and using it to make the build for client project.
thanks in advance,
George
|
|
|
|
|
I don't think you need the .c file for COM, just the .h file. If you look at this page[^], it says that the C stub file is only needed when IDL is used to define RPC interfaces.
IIRC, the C stub contains code to serialize parameters for RPC calls into an interchangeable form.
|
|
|
|
|
Hi Stuart,
If I do not include the .c file, there will be link error. Any ideas?
1>d:\visual studio 2008\projects\testatl2\teststruct1\main.cpp(14) : error C2275: 'TestStrcut1' : illegal use of this type as an expression
1> d:\visual studio 2008\projects\testatl2\teststruct1\testatl2_i.h(58) : see declaration of 'TestStrcut1'
1>d:\visual studio 2008\projects\testatl2\teststruct1\main.cpp(17) : error C2275: 'ITestStrcut1' : illegal use of this type as an expression
1> d:\visual studio 2008\projects\testatl2\teststruct1\testatl2_i.h(99) : see declaration of 'ITestStrcut1'
#include "TestATL2_i.h"
int main()
{
HRESULT hr;
ITestStrcut1* pITS;
CoInitialize (NULL);
MyValue data;
data.x = 5;
hr = CoCreateInstance ( TestStrcut1,
NULL,
CLSCTX_INPROC_SERVER,
ITestStrcut1,
(void**) &pITS );
if ( SUCCEEDED ( hr ) )
{
hr = pITS->SetMyStruct (&data);
pITS->Release();
}
else
{
}
CoUninitialize();
return 0;
}
regards,
George
|
|
|
|
|
It's been a while since I've done ATL, but it's coming back now I was wrong about the .c file not being needed - that's a *different* .c file!
The .c file defines the CLSID and IID for the ATL object and interfaces. You can compile the .c file and incorporate the .obj file into a .lib file - that's what Microsoft do in the Windows SDK (look for uuid.lib) - or just #include the .c file into your client. I usually use the second approach, so if I have generated interface files called a_i.c and a_i.h , I'd use something like the code below in the .cpp file containing my main or WinMain :
#include "a_i.h"
#define INITGUID
#include "a_i.c"
The #define INITGUID causes the code in the .c file to define variables that contain the IID and CLSID.
HTH!!!
|
|
|
|
|
Thanks Stuart,
I am confused about your two solutions.
1. The first solution is to include _i.c file into the COM consumer project, I agree and understand. Is it what you mean?
2. The second solution is to use uuid.lib?? Could this lib file contains all customer defined CLSID/IID, since this lib file is shipped before you write any customized code? I doubt it will have the same effect as solution 1.
regards,
George
|
|
|
|
|
George_George wrote: 1. The first solution is to include _i.c file into the COM consumer project, I agree and understand. Is it what you mean?
Yes
George_George wrote: 2. The second solution is to use uuid.lib?? Could this lib file contains all customer defined CLSID/IID, since this lib file is shipped before you write any customized code? I doubt it will have the same effect as solution 1.
No - I used uuid.lib as an example of how CLSID and IIDs can be packaged - in fact, how Microsoft package up CLSIDs and IIDs for COM objects defined within Windows.
I meant that you could compile your _i.c file and put the .obj file into a .lib file, then get consumers to link against the .lib file you've produced. This way of doing things could be easier if you have several COM components to distribute.
|
|
|
|
|
Thanks Stuart,
Good idea -- "compile your _i.c file and put the .obj file into a .lib file"! You mean a static lib file, and not import lib file, correct?
regards,
George
|
|
|
|
|
George_George wrote: You mean a static lib file, and not import lib file, correct?
Yep, that's right. Create a static library project in VS and add the _i.c file as a source.
|
|
|
|
|
Thanks Stuart,
I like your alternative solution.
regards,
George
|
|
|
|
|
Hi,
I have a activeX ATL control embeded in an html page. The page also defines some javascript which I'd like to call from my ActiveX object. From reading several articles I realize I could to use connectionpoints to accomplish this. However, I'm stuck with a compile error:
error C2787: '_IWebPluginControlEvents' : no GUID has been associated with this object.
Is there some step i'm missing here? Any help is greatly apperciated!
I have defined a connectionpoint within my IDL file as follows:
In "WebPlugin.idl"
[
uuid(FD84D4F2-4D92-48DE-9A16-0D2F1A43DD6D),
helpstring("_IWebPluginControlEvents")
]
dispinterface _IWebPluginControlEvents
{
properties:
methods:
[id(1), helpstring("method Finished")] HRESULT Finished();
};
coclass WebPluginControl
{
[default] interface IWebPluginControl;
[default, source] dispinterface _IWebPluginControlEvents;
};
I have implemented IProvideClassInfo2Imp and added the COM_ENTRIES as follows:
WebPluginControl.h
class ATL_NO_VTABLE CWebPluginControl :
public CComObjectRootEx<ccomsinglethreadmodel>,
public IDispatchImpl,
public IPersistStreamInitImpl<cwebplugincontrol>,
public IOleControlImpl<cwebplugincontrol>,
public IOleObjectImpl<cwebplugincontrol>,
public IOleInPlaceActiveObjectImpl<cwebplugincontrol>,
public IViewObjectExImpl<cwebplugincontrol>,
public IOleInPlaceObjectWindowlessImpl<cwebplugincontrol>,
public ISupportErrorInfo,
public IPersistStorageImpl<cwebplugincontrol>,
public ISpecifyPropertyPagesImpl<cwebplugincontrol>,
public IQuickActivateImpl<cwebplugincontrol>,
public IDataObjectImpl<cwebplugincontrol>,
public IProvideClassInfo2Impl<&CLSID_WebPluginControl, &__uuidof(_IWebPluginControlEvents), &LIBID_WebPluginLib>,
public IObjectSafetyImpl<cwebplugincontrol,>,
public IConnectionPointContainerImpl<cwebplugincontrol>,
public IConnectionPointImpl<cwebplugincontrol,&__uuidof(_iwebplugincontrolevents)>,
public IPropertyNotifySinkCP<cwebplugincontrol>,
public IPersistPropertyBagImpl<cwebplugincontrol>,
public CComCoClass<cwebplugincontrol,>,
public CComControl <cwebplugincontrol>,
public CProxy_IWebPluginControlEvents<cwebplugincontrol>
BEGIN_COM_MAP(CWebPluginControl)
COM_INTERFACE_ENTRY(IWebPluginControl)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IViewObjectEx)
COM_INTERFACE_ENTRY(IViewObject2)
COM_INTERFACE_ENTRY(IViewObject)
COM_INTERFACE_ENTRY(IOleInPlaceObjectWindowless)
COM_INTERFACE_ENTRY(IOleInPlaceObject)
COM_INTERFACE_ENTRY2(IOleWindow, IOleInPlaceObjectWindowless)
COM_INTERFACE_ENTRY(IOleInPlaceActiveObject)
COM_INTERFACE_ENTRY(IOleControl)
COM_INTERFACE_ENTRY(IOleObject)
COM_INTERFACE_ENTRY(IPersistStreamInit)
COM_INTERFACE_ENTRY2(IPersist, IPersistStreamInit)
COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)
COM_INTERFACE_ENTRY(ISupportErrorInfo)
COM_INTERFACE_ENTRY(ISpecifyPropertyPages)
COM_INTERFACE_ENTRY(IQuickActivate)
COM_INTERFACE_ENTRY(IPersistStorage)
COM_INTERFACE_ENTRY(IDataObject)
COM_INTERFACE_ENTRY(IProvideClassInfo)
COM_INTERFACE_ENTRY(IProvideClassInfo2)
COM_INTERFACE_ENTRY(IPersistPropertyBag)
COM_INTERFACE_ENTRY_IID(IID_IObjectSafety, IObjectSafety)
COM_INTERFACE_ENTRY(IConnectionPointContainer)
END_COM_MAP()
BEGIN_CONNECTION_POINT_MAP(CWebPluginControl)
CONNECTION_POINT_ENTRY(__uuidof(_IWebPluginControlEvents))
CONNECTION_POINT_ENTRY(IID_IPropertyNotifySink)
END_CONNECTION_POINT_MAP()
</cwebplugincontrol></cwebplugincontrol></cwebplugincontrol></cwebplugincontrol></cwebplugincontrol></cwebplugincontrol></cwebplugincontrol></cwebplugincontrol></cwebplugincontrol></cwebplugincontrol></cwebplugincontrol></cwebplugincontrol></cwebplugincontrol></cwebplugincontrol></cwebplugincontrol></ccomsinglethreadmodel>
The proxy class (auto-generated) looks like:
#pragma once
template<class t="">
class CProxy_IWebPluginControlEvents :
public IConnectionPointImpl<t,>
{
public:
HRESULT Fire_Finished()
{
HRESULT hr = S_OK;
T * pThis = static_cast<t>(this);
int cConnections = m_vec.GetSize();
for (int iConnection = 0; iConnection < cConnections; iConnection++)
{
pThis->Lock();
CComPtr<iunknown> punkConnection = m_vec.GetAt(iConnection);
pThis->Unlock();
IDispatch * pConnection = static_cast<idispatch>(punkConnection.p);
if (pConnection)
{
CComVariant varResult;
DISPPARAMS params = { NULL, NULL, 0, 0 };
hr = pConnection->Invoke(1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, ¶ms, &varResult, NULL, NULL);
}
}
return hr;
}
};
</idispatch></iunknown></t></class>
I am using Visual Studio 2003 under windows XP SP2
MIDL compiler version 6.00.0361
Every ATL.dll on my system is versioned > 3 (not sure how to check the exect one visual studio is using)
|
|
|
|
|
Ok I've figured it out, I was placing code in the wrong spot inside my idl file. Specifically, the following needed to be inside the "library" tag.
[
uuid(FD84D4F2-4D92-48DE-9A16-0D2F1A43DD6D),
helpstring("_IWebPluginControlEvents")
]
dispinterface _IWebPluginControlEvents
{
properties:
methods:
[id(1), helpstring("method Finished")] HRESULT Finished();
};
|
|
|
|
|
I need a sample application for connecting to sql server database in ATL.
Thanks..
|
|
|
|
|
|
How can create I an ActiveX which can still active after close IExplorer?
|
|
|
|
|
I wrote a plugin for IE with ATL. Now my requirement is to pop up a modeless dialog in IE so that it can display some information extracted from the page of my IE explored.
When I use DoModal(), it works fine
But I need to show it modeless, so when I use (SW_SHOWNORMAL), my plug in crashed. it says error in atlwin.h 2815 line
Anyone can tell me why and do me a favor? Below is my code:
CMainDialog d;
HWND hIE;
HRESULT hr = m_pBrowser->get_HWND((long*)&hIE);
d.Create(hIE);
d.ShowWindow(SW_SHOWNORMAL);
//error code in atlwin.h
virtual ~CWindowImplRoot()
{
#ifdef _DEBUG
if(m_hWnd != NULL) // should be cleared in WindowProc
{
ATLTRACE(atlTraceWindowing, 0, _T("ERROR - Object deleted before window was destroyed\n"));
ATLASSERT(FALSE);
}
#endif //_DEBUG
}
|
|
|
|
|
Hi everyone,
Look at follow code:
UINT uFormat = DT_WORDBREAK|DT_EXTERNALLEADING;
CRect rect(10,30,200,60);
::DrawText(dc,"hi harry, how are you! there are no persons in the school fdsfdsfsd fsdfdsf",-1,rect,uFormat);
Run this code in the OnPaint(), the result is that there is no compelete string show in the region(CRect rect(10,30,200,60));
I want to add "..." into the end string display. If someone can help me, please tell me how.
Thanks.
|
|
|
|
|
Add DT_END_ELLIPSIS to your uFormat.
- S
50 cups of coffee and you know it's on!
A post a day, keeps the white coats away!
|
|
|
|
|
Hi Steve,
It's only one line for this case, I want to show string like this:
many of them virtual, to convert an object to and from other types. This conversion is mainly used by the property browser to convert...
Can you help me how show string in mutlti lines with '...'.
Thanks
|
|
|
|
|
Yeah, I don't think end ellipsis works with multiline. You might try DT_WORD_ELLIPSIS.
I saw some post about adjusting the height of the rect to make it an integral of the font size, but that seems like a pain.
- S
50 cups of coffee and you know it's on!
A post a day, keeps the white coats away!
|
|
|
|
|
DT_WORD_ELLIPSIS also is fit in this case.
|
|
|
|
|
I wanna implement a toolbar for Windows using WTL classes like CToolBarCtrl. For the toolbar to work I saw in numerous examples that you have to create a reflection window, that is essentially a hidden parent for the toolbar so you can fetch the commands send by the toolbar.
I wonder if you could implement a reflective toolbar using the CWindowWithReflectorImpl?
I never got it to work though. The created window did not repaint itself and the toolbar was not visible. Anyone here knows how to use CWindowWithReflectorImpl?
Thanks in advance!
Happy coding,
Philipp Kursawe
|
|
|
|
|