|
Hello,
I want to know if there is any way to get an handle to PopUp box / Alert box.
These alert's are mostly displayed by Javascript functions on a webpage display.
I have a Webbrowser Control in my C++ application(mfc) and need to know when the Alert box is shown and also what was the user's action on it(He/she might click OK or Cancel button).
Thanking you in advance.
Prasad
|
|
|
|
|
hi,
I'm developing ATL ActiveX EXE server that runs as a Window services using ATL wizard.
This server contains one ATL object (CTest).
How I can set the server so that when it started (via Window Services Applet), the server will :
1) initiate/create CTest.
2) Call method/function in this ATL object (CallMe).
3) destroy CTest when server stopped.
Thanx in advance.
Regards.
|
|
|
|
|
You will need to overwrite CServiceModule::Run - after the service will register the class objects, init your object and call the method. After the message loop sequence, destroy your object.
|
|
|
|
|
hi,
thanx for ur replay
I've change my code. But when I try to start my service I got an error :
Could not start the Test on Local Computer.
Error 1053: The service did not respond to the start or control request
in a timely fashion.
And one more thing; how i want to destroy the ATL object in a correct way:
m_Obj->Release()
or
m_Obj = NULL
Below is code for CServiceModule::Run() :
<small>void CServiceModule::Run()<br />
{<br />
_Module.dwThreadID = GetCurrentThreadId();<br />
<br />
HRESULT hr = CoInitialize(NULL);<br />
<br />
_ASSERTE(SUCCEEDED(hr));<br />
<br />
CSecurityDescriptor sd;<br />
sd.InitializeFromThreadToken();<br />
hr = CoInitializeSecurity(sd, -1, NULL, NULL,<br />
RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);<br />
_ASSERTE(SUCCEEDED(hr));<br />
<br />
hr = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER, REGCLS_MULTIPLEUSE);<br />
_ASSERTE(SUCCEEDED(hr));<br />
<br />
<big>
CComObject<CMyObj> *m_Obj;<br />
CComObject<CMyObj>::CreateInstance(&m_Obj);</big><br />
<br />
<big>
m_Obj->CallMe();</big><br />
<br />
LogEvent(_T("Service started"));<br />
if (m_bService)<br />
SetServiceStatus(SERVICE_RUNNING);<br />
<br />
MSG msg;<br />
while (GetMessage(&msg, 0, 0, 0))<br />
DispatchMessage(&msg);<br />
<br />
<big>
m_Obj->Release();</big><br />
<br />
_Module.RevokeClassObjects();<br />
<br />
CoUninitialize();<br />
}</small>
Below is code for CMyObj :
<small>HRESULT CMyObj::FinalConstruct()<br />
{<br />
return S_OK;<br />
}<br />
<br />
void CMyObj::FinalRelease()<br />
{<br />
<br />
}<br />
<br />
<big>STDMETHODIMP CMyObj::CallMe()<br />
{<br />
MessageBox(NULL, "Window services called me.", "MyObj", MB_OK);<br />
return S_OK;<br />
}</big></small>
Sorry for the silly questions.
Thanx in advance.
Regards.
|
|
|
|
|
NT Services are running into a window station which is not interactive, so they cannot have a user interface - your service will be blocked at MessageBox call from CallMe method. Try to write something to the debug output instead. To release the object call Release ( setting the smart ptr to NULL will NOT dereference the object), or use CComObjectStack instead of CComObject, since your object is used only in Run method.
ps. If you really want, you can change your service to interact with the active desktop ( to have a user interface ), by using service_interactive flag when you call CreateService.
|
|
|
|
|
Or if you really want to use the messagebox inside the service, really only for debugging purposes or something like that, you can use the MB_SERVICE_NOTIFICATION flag for the messagebox function
<br />
MessageBox( NULL, "some message", NULL, MB_OK | MB_SERVICE_NOTIFICATION );<br />
This will pop-up the message box on the default desktop.
Assigining a NULL value to the smart pointer is also a correct way of releasing the pointer - if you look into the implementation of CComPtr, it will first call release on currently assigned pointer and then attaches to the new one. This is a must for correctly working = operator, so I guess it is valid for each com smart pointer. Then if you assign NULL, it will first call the Release and then stores your NULL value.
|
|
|
|
|
You are right - assigning NULL to a CComPtr instance will dereference the contained interface. Thanks!
|
|
|
|
|
hi,
When I call m_Obj->Release() or m_Obj = NULL; my FinalRelease() never called
void CServiceModule::Run()<br />
{<br />
_Module.dwThreadID = GetCurrentThreadId();<br />
<br />
HRESULT hr = CoInitialize(NULL);<br />
<br />
_ASSERTE(SUCCEEDED(hr));<br />
<br />
CSecurityDescriptor sd;<br />
sd.InitializeFromThreadToken();<br />
hr = CoInitializeSecurity(sd, -1, NULL, NULL,<br />
RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);<br />
_ASSERTE(SUCCEEDED(hr));<br />
<br />
hr = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER, REGCLS_MULTIPLEUSE);<br />
_ASSERTE(SUCCEEDED(hr));<br />
<br />
CComObject<CMyObj> *m_Obj;<br />
CComObject<CMyObj>::CreateInstance(&m_Obj);<br />
<br />
m_Obj->CallMe();<br />
<br />
LogEvent(_T("Service started"));<br />
if (m_bService)<br />
SetServiceStatus(SERVICE_RUNNING);<br />
<br />
MSG msg;<br />
while (GetMessage(&msg, 0, 0, 0))<br />
DispatchMessage(&msg);<br />
<br />
<big>
m_Obj->Release();</big> <br />
<br />
_Module.RevokeClassObjects();<br />
<br />
CoUninitialize();<br />
}<br />
Below is .h code for CMyObj :
<br />
<br />
#ifndef __MYOBJ_H_<br />
#define __MYOBJ_H_<br />
<br />
#include "resource.h"
<br />
class ATL_NO_VTABLE CMyObj : <br />
public CComObjectRootEx<<CComSingleThreadModel>>,<br />
public CComCoClass<<CMyObj, &CLSID_MyObj>>,<br />
public IDispatchImpl<<IMyObj, &IID_IMyObj, &LIBID_TESTLib>><br />
{<br />
public:<br />
CMyObj()<br />
{<br />
}<br />
<br />
HRESULT FinalConstruct()<br />
{<br />
MessageBox(NULL, "Start", NULL, MB_OK | MB_SERVICE_NOTIFICATION );<br />
return S_OK;<br />
}<br />
<br />
<big><br />
void FinalRelease()<br />
{<br />
MessageBox(NULL, "stop", NULL, MB_OK | MB_SERVICE_NOTIFICATION);<br />
}</big><br />
<br />
DECLARE_REGISTRY_RESOURCEID(IDR_MYOBJ)<br />
<br />
DECLARE_PROTECT_FINAL_CONSTRUCT()<br />
<br />
BEGIN_COM_MAP(CMyObj)<br />
COM_INTERFACE_ENTRY(IMyObj)<br />
COM_INTERFACE_ENTRY(IDispatch)<br />
END_COM_MAP()<br />
<br />
public:<br />
STDMETHOD(CallMe)();<br />
};<br />
<br />
#endif //__MYOBJ_H_<br />
Thanx in advance
Regards.
|
|
|
|
|
hi all,
i am stuck.please help. my problem is I want to make a setup program for my vc++ application as we have in VB.can anyone help me out?
thanks in advance
regards
Himanshu
|
|
|
|
|
hey
use the SMS installer 16/32
~~~~Code the Dreams~~~~~
|
|
|
|
|
Is it possible for a COM Class I've made using the ATL Wizard thingie to inherit from another class.
The following code doesn't compile since I added "public INewParentClass", I get the following error on the COM_INTERFACE_ENTRY(IDispatch) line.
c:\temp\code\mymethod2\mymethod.h(29) : error C2594: 'static_cast' : ambiguous conversions from 'class CMYMETHOD *' to 'struct IDispatch *'
Code is as follows.
/////////////////////////////////////////////////////////////////////////////
// MYMETHOD.h : Declaration of the CMYMETHOD
#ifndef __MYMETHOD_H_
#define __MYMETHOD_H_
#include "resource.h" // main symbols
#include "IParentClass.h"
/////////////////////////////////////////////////////////////////////////////
// CMYMETHOD
class ATL_NO_VTABLE CMYMETHOD :
public CComObjectRootEx<ccomsinglethreadmodel>,
public CComCoClass<cmymethod, &clsid_mymethod="">,
public IDispatchImpl<ivpim, &iid_imymethod,="" &libid_mymethodserver2lib="">,
public INewParentClass
{
public:
CMYMETHOD()
{
}
DECLARE_REGISTRY_RESOURCEID(IDR_MYMETHOD)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CMYMETHOD)
COM_INTERFACE_ENTRY(IMYMETHOD)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()
// IMYMETHOD
public:
STDMETHOD(Hello)(/*[in]*/ BSTR sClientName);
};
#endif //__MYMETHOD_H_
|
|
|
|
|
Yes it is possible. Not sure what the cause of the error is, but most likely it is coming from something in INewParentClass. An ATL based class can inherit from a regular C++ class, not another ATL class.
|
|
|
|
|
Probably INewParentClass is inherited from IDispatchImpl too.
|
|
|
|
|
Hi all,
I have what seems to be a trivial problem...
I need to convert an array of doubles to a SAFEARRAY**
i.e. I have:
double MyArray[50];
I need to pass this to a third part function as a SAFEARRAY**
I'm sure this is a doddle - but I just keep crashing it with what I pass.
I'm new to all this COM stuff... why does it have to be so complicated?!
Thanks
--
The Obliterator
|
|
|
|
|
Something like this should help:
SAFEARRAY* CFoo::DoubleArrayToSafeArray(double* array, int n)<br />
{<br />
<br />
SAFEARRAYBOUND rgsabound[1];<br />
rgsabound[0].lLbound = 0;<br />
rgsabound[0].cElements = n;<br />
<br />
SAFEARRAY* pReturn = NULL;<br />
pReturn = SafeArrayCreate( VT_R8 , 1, rgsabound);<br />
<br />
if (pReturn == NULL)<br />
return pReturn;<br />
<br />
long idxPos = 0;<br />
for (idxPos = 0 ; idxPos < n; idxPos++)<br />
{<br />
HRESULT hr = SafeArrayPutElement(pReturn, &idxPos, (void*) &(array[idxPos]));<br />
}<br />
return pReturn;<br />
}
Regards
Barry
|
|
|
|
|
Barry,
Can you point me to a good overview on the use of SafeArrays and Variants?
Thanks.
|
|
|
|
|
I spent ages trawling through MSDN I'm afraid. I would imagine that there are some articles on safearrays and variants here on CodeProject as well.
Regards
Barry
|
|
|
|
|
|
I want to design a card game ,use Com+ server.
But when 4 clients connected,it's created 4 com+ instance in server,
so it's hard to manage.
I want to know :
how I can connect every 4 clients to 1 com+ instance in server.
|
|
|
|
|
|
Hi,
I've got a CLSID for a COM object in a C++ program, how do I access methods on this object. Do I have to call QueryInterface() somehow?
I can do a CoCreateInstance() but that requires an interface ID. Assuming all I have is the CLSID, how do I do it?
Thanks!
|
|
|
|
|
Try to QI for IUnknown or IDispatch
CLSID clsid;//some valid clsid
LPDISPATCH pDisp;
HRESULT hr = CoCreateInstance(clsid,NULL,CLSCTX_SERVER,IID_IDispatch,(LPVOID*)&pDisp);
if(SUCCEEDED(hr))
{
//now call interface methods
pDisp->AutomationCall();
}
}
|
|
|
|
|
hmm, in fact, you can create the object, asking CoCreateInstance for IID_IUnknown as an Interface ID (IID). Then you will receive the pointer to the IUnknown.
But the question is what you want to do next - for nearly every other activity you will need to retrieve some interface from the object, else you will be able only to call IUnknown methods or might be IDispatch methods, but without any further info you are generally not able to perform any operation over that object.
I don't know if I expressed myself correctly, but the situation then is similar to having a .lib without header - so you have some objects inside the lib but you don't know how to talk to them.
|
|
|
|
|
I have created a COM collection object for use by our UI team, but now requirements seem to have changed and they no longer want COM collections but something like ADO recordsets they can bind to their grids. It seemed to me that a data bound control is probably just using an interface on the ADO recordset objects to navigate the collection. And since I already had my COM collection implemented, if I could implement this mysterious DataSource interface I could make everyone happy. Can anyone give me a push in the right direction? What interface do I need to implement in my COM collection to act as a DataSource for a VB Data Bound control? Thanks in advance.
|
|
|
|
|
Take a look at the ATL OLEDB data producer classes1. Many grids support OLEDB as well if I'm not mistaken..
Just fire up an ATL project, and add an OLEDB data producer class using the ATL wizard, and go on from there.
1 I'm not sure this is the correct name. I'm 100 miles from home, so I can't lookup the name right now. But just look at the ATL wizards and you'll know it when you see it.
--
Only in a world this sh*tty could you even try to say these were innocent people and keep a straight face.
|
|
|
|