|
Hi all,
I've been digging through tons of documentation but as of yet, I still haven't found an answer to a simple question.
When an MFC ActiveX control fires an event, does it return immediately or does it return only after the container's event handler is finished?
Thanks!
|
|
|
|
|
|
Im doing a simple non-MFC application.. I need to convert an ASCII string into an OLECHAR array. I want to pass my string into a SysAllocString(); function call like this:
<br />
char string[] = "ASCII STRING";<br />
(t+f)->str = SysAllocString(string);<br />
Of course this doesnt work because, SysAllocString is expecting an OLECHAR FAR*. The function works fine when I do:
<br />
(t+f)->str = SysAllocString(OLESTR("Test String"));<br />
Im actually passing in an array of UDTypes with variable length strings from VB and populating each element of the array / structure.
Im not very familiar with this whole ATL/COM string stuff.. =) Ill be honest, Im a C programmer, so Im out of my element. What can I do.. Please Help.
Ryan Baillargeon
Software Specialist
Fuel Cell Technologies Inc.
|
|
|
|
|
|
If you #include <atlbase.h> & <atlconv.h> , you can use the ATL string conversion macros. These convert strings 'on-the-fly':
const char* s;
BSTR s = ::SysAllocString(A2COLE(s));
LPCTSTR ts;
BSTR s = ::SysAllocString(T2COLE(ts));
They 'do the right' thing wrt conversion to/from Unicode & ASCII & use the stack for temporary string allocation (so are reasonably efficient and deallocate the temporaries automatically).
Alternatively, the CComBSTR or _bstr_t classes seem to work pretty well (I tend to use _bstr_t because it's got char* & wchar_t* extraction operators). The following code should properly allocate a BSTR for use in a C struct
struct {
....
BSTR bs;
....
} thing;
char* s;
thing.bs = CComBSTR(s).Detach();
Just remember to make sure that the BSTR is properly deallocated - using SysFreeString if you do it yourself. For this reason, you'd be better having a CComBSTR in your struct if that's at all practical, as the CComBSTR will deallocate the BSTR in it's destructor.
HTH
Stuart Dootson
'Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p'
|
|
|
|
|
Just take care of the conversion macros like A2W, W2A, A2COLE, etc.. for 2 reasons:
1) They dynamically allocate memory ON THE STACK. This is good because it is fast and memory autmatically gets freed when the stack goes out of scope. However, there are memory limitations, so big strings could cause nasty things....
2) CComBSTR (or any other BSTR strings) support EMBEDDED NULLs. For those who do not know what embedded nulls are - basically, a BSTR could be: "Hello\0World" (notice the 0 in the middle.). When a BSTR is counted using SysStringLen(), the proper lenght is taken (SysAllocString stores the lenght of the string). However, if strlenW is used, it will stop after the "Hello" and not count the "World" part. A2W, W2A, A2COLE etc.. use strlenW to get the lenght of the string and not SysStringLen... this causes a converted string to be truncated when it encounters and embedded NULL.
Jeremy.
"Hey man, Taliban, Tali me Banana."
|
|
|
|
|
I have a dialog resource within a COM object and have added a thirdparty ActiveX control to the dialog box.
During execution, while loading the dialog resource I get the following error message..
"Dialog has OLE controls, but not matching DLGINIT resource"
I checked the .rc file and there is DLGINIT resource defined.
Any clue. Thanks
|
|
|
|
|
Hi,
I have seen and replied to an earlier post of yours.
I think there is no problem in your programming and
the fault lies with the ActiveX control.
The ActiveX control should support specific interfaces
for saving information during design time, so as to enable
the Application to load it during runtime.
I think that your AciveX control is having specific
Run-time validation which is not fullfilled by the
default behavior of Dialog start up.(ActiveX Control Support).
What you need to do now is create the Active X control at
runtime and then place it in the specific position
on the dialog programmatically.
Look into the documentation for the ActiveX control.
During the creation you can pass the specific liscensing requirement.
PS: Can you tell me what control is it ?
|
|
|
|
|
It's MSChart Control.
Hope I mentioned that, The dialog resource is in a COM DLL. The control loads properly in an EXE just fine.
Thanks.
|
|
|
|
|
I pass a SAFEARRAY through a Variant in VB.
Now i have the Variant and i don't know how to extract the SAFEARRAY from it.
rechi
|
|
|
|
|
STDMETHODIMPL MyCOMClass::VBMethod(VARIANT * vt)
{
SAFEARRAY *psa;
if(vt == NULL)
return E_POINTER;
//assuming safearray consists BSTR. if not change to appropriate sa datatype
if(vt->vt != VT_BSTR | VT_ARRAY)
{
return E_INVALIDARG;
}
psa = vt->parray;
ATLASSERT(psa != NULL);
//use safe array here
return S_OK;
}
Hth,
Ramu
|
|
|
|
|
This is more of a configuration question.
I have a firewall between me and a DCOM component that is only letting allowing DCOM traffic (or more specifically I guess RPC traffic) through ports 135 and 40000-40001.
I have followed instructions on how to achieve this from such entertaining articles such as "Using Distributed COM with Firewalls" (from MSDN) but to no avail. My component is still trying to establish a connection through any random port it likes.
Although I'm well versed in details of TCP and the like I am a bit lost as to how to diagnose the problem here.
A nod in the right direction would really be appreciated. Typically, most of the article I'm coming across are knee deep in most details but then skip quickly over the art of configuring the security aspects.
TIA
JBoy
|
|
|
|
|
I made a COM exe that i create from other applications, but when i close the application that created it, it goes away. How can i make it so that the COM exe stays even when the program that created it closes?
Thanks
|
|
|
|
|
Hi Shadow,
That's the correct implementation, it should go away when the application that creates it
goes away! But if you are looking for a quick and dirty way to do that, look at CExeModule::MonitorShutdown() or comment the SetEvent call in CExeModule::Unlock . I assumed you are using ATL. But why do you want
your server to remain?
Last Article:
Client/Server Socket class
|
|
|
|
|
I added a bool (bOKToShutdown) that gets set to true only if the user closes the app (from a tray icon).
void CExeModule::MonitorShutdown()
{
while (1)
{
WaitForSingleObject(hEventShutdown, INFINITE);
DWORD dwWait=0;
do
{
bActivity = false;
dwWait = WaitForSingleObject(hEventShutdown, dwTimeOut);
} while (dwWait == WAIT_OBJECT_0);
if (!bActivity && m_nLockCnt == 0 && bOKToShutDown)
{
#if _WIN32_WINNT >= 0x0400 & defined(_ATL_FREE_THREADED)
CoSuspendClassObjects();
if (!bActivity && m_nLockCnt == 0)
#endif
break;
}
}
CloseHandle(hEventShutdown);
PostThreadMessage(dwThreadID, WM_QUIT, 0, 0);
}
Jason Henderson quasi-homepage articles "Like it or not, I'm right!"
|
|
|
|
|
Hope this is the right place to ask this question. Does anyone have a good example or link to some C source code on how I can use an ActiveX control? I have a Win32 program in C that I would like to add two controls to. I looked at the articles in this section and did a search on the web and MSDN but it's kind of hard to find something that is for C only. I have books on how to design COM objects and ActiveX controls but no examples on how to use them in C.
|
|
|
|
|
Example how to work with COM in "C":
#inluce "windows.h"
#include "objx\\objx.h"
int main(int argc, char* argv[])
{
IObj *pObj;
HRESULT hr;
BSTR wsIn;
CoInitialize(0);
hr = CoCreateInstance( &CLSID_Obj, 0, CLSCTX_SERVER, &IID_IObj, (void**) &pObj);
if(S_OK == hr)
{
wsIn = SysAllocString(L"Test string.");
hr = pObj->lpVtbl->Test(pObj,wsIn);
pObj->lpVtbl->Release(pObj);
SysFreeString(wsIn);
}
CoUninitialize();
}
must link with "ObjX_i.c" .
This is my test object header file:
#pragma warning( disable: 4049 ) /* more than 64k source lines */
#ifndef __REQUIRED_RPCNDR_H_VERSION__
#define __REQUIRED_RPCNDR_H_VERSION__ 440
#endif
#include "rpc.h"
#include "rpcndr.h"
#ifndef __RPCNDR_H_VERSION__
#error this stub requires an updated version of <rpcndr.h>
#endif // __RPCNDR_H_VERSION__
#ifndef COM_NO_WINDOWS_H
#include "windows.h"
#include "ole2.h"
#endif /*COM_NO_WINDOWS_H*/
#ifndef __objX_h__
#define __objX_h__
#ifndef __IObj_FWD_DEFINED__
#define __IObj_FWD_DEFINED__
typedef interface IObj IObj;
#endif /* __IObj_FWD_DEFINED__ */
#ifndef __Obj_FWD_DEFINED__
#define __Obj_FWD_DEFINED__
#ifdef __cplusplus
typedef class Obj Obj;
#else
typedef struct Obj Obj;
#endif /* __cplusplus */
#endif /* __Obj_FWD_DEFINED__ */
#include "oaidl.h"
#include "ocidl.h"
#ifdef __cplusplus
extern "C"{
#endif
void __RPC_FAR * __RPC_USER MIDL_user_allocate(size_t);
void __RPC_USER MIDL_user_free( void __RPC_FAR * );
#ifndef __IObj_INTERFACE_DEFINED__
#define __IObj_INTERFACE_DEFINED__
EXTERN_C const IID IID_IObj;
#if defined(__cplusplus) && !defined(CINTERFACE)
MIDL_INTERFACE("3257037D-879B-11D6-A117-00B0D0C3D9BD")
IObj : public IDispatch
{
public:
virtual HRESULT STDMETHODCALLTYPE Test(
BSTR wsIn) = 0;
};
#else
^__b style='{ color:blue }'>
typedef struct IObjVtbl
{
BEGIN_INTERFACE
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
IObj __RPC_FAR * This,
REFIID riid,
void __RPC_FAR *__RPC_FAR *ppvObject);
ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
IObj __RPC_FAR * This);
ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
IObj __RPC_FAR * This);
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )(
IObj __RPC_FAR * This,
UINT __RPC_FAR *pctinfo);
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )(
IObj __RPC_FAR * This,
UINT iTInfo,
LCID lcid,
ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )(
IObj __RPC_FAR * This,
REFIID riid,
LPOLESTR __RPC_FAR *rgszNames,
UINT cNames,
LCID lcid,
DISPID __RPC_FAR *rgDispId);
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )(
IObj __RPC_FAR * This,
DISPID dispIdMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS __RPC_FAR *pDispParams,
VARIANT __RPC_FAR *pVarResult,
EXCEPINFO __RPC_FAR *pExcepInfo,
UINT __RPC_FAR *puArgErr);
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Test )(
IObj __RPC_FAR * This,
BSTR wsIn);
END_INTERFACE
} IObjVtbl;
interface IObj
{
CONST_VTBL struct IObjVtbl __RPC_FAR *lpVtbl;
};
#ifdef COBJMACROS
#define IObj_QueryInterface(This,riid,ppvObject) \
(This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
#define IObj_AddRef(This) \
(This)->lpVtbl -> AddRef(This)
#define IObj_Release(This) \
(This)->lpVtbl -> Release(This)
#define IObj_GetTypeInfoCount(This,pctinfo) \
(This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
#define IObj_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
(This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
#define IObj_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
(This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
#define IObj_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
(This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
#define IObj_Test(This,wsIn) \
(This)->lpVtbl -> Test(This,wsIn)
#endif /* COBJMACROS */
#endif /* C style interface */
HRESULT STDMETHODCALLTYPE IObj_Test_Proxy(
IObj __RPC_FAR * This,
BSTR wsIn);
void __RPC_STUB IObj_Test_Stub(
IRpcStubBuffer *This,
IRpcChannelBuffer *_pRpcChannelBuffer,
PRPC_MESSAGE _pRpcMessage,
DWORD *_pdwStubPhase);
#endif /* __IObj_INTERFACE_DEFINED__ */
#ifndef __OBJXLib_LIBRARY_DEFINED__
#define __OBJXLib_LIBRARY_DEFINED__
EXTERN_C const IID LIBID_OBJXLib;
EXTERN_C const CLSID CLSID_Obj;
#ifdef __cplusplus
class DECLSPEC_UUID("3257037E-879B-11D6-A117-00B0D0C3D9BD")
Obj;
#endif
#endif /* __OBJXLib_LIBRARY_DEFINED__ */
unsigned long __RPC_USER BSTR_UserSize( unsigned long __RPC_FAR *, unsigned long , BSTR __RPC_FAR * );
unsigned char __RPC_FAR * __RPC_USER BSTR_UserMarshal( unsigned long __RPC_FAR *, unsigned char __RPC_FAR *, BSTR __RPC_FAR * );
unsigned char __RPC_FAR * __RPC_USER BSTR_UserUnmarshal(unsigned long __RPC_FAR *, unsigned char __RPC_FAR *, BSTR __RPC_FAR * );
void __RPC_USER BSTR_UserFree( unsigned long __RPC_FAR *, BSTR __RPC_FAR * );
#ifdef __cplusplus
}
#endif
#endif
soptest
|
|
|
|
|
Thanks I'm wondering if I'm using say the serial comm port control then I wouldn't need or have that equivalent file for ObjX_i.c, right? Wouldn't I just import the typelib or something? Or, do I still need the MIDL compiler to generate the .c file?
|
|
|
|
|
Yes, you have to use MIDL compiler to generate those files, because #import directive is C++ specific.
soptest
|
|
|
|
|
Could you help with this? If I used VC++ to add the component it generates the .tli and .tlh files but they don't seem usable for C. How do I generate a header file that will have all of the declarations for the mscomm32.ocx control?
Does anyone have an example of how to take one of Microsoft's supplied controls e.g. mscomm32.ocx or msscript.ocx in a Win32 <bold> C program?????
|
|
|
|
|
This is really cool. soptest, you are the man!!
You yard yellow years yieldingly; you yanked your yearning yoke.-Jeremy Falcon-CPite.
Amit Dey
sonork: 100:18407
msn: visualcdev
|
|
|
|
|
Suppose I have an activeX in HTML page with some PARAMs specified. Everytime the page loads IE asks if you want to allow the control to interact with HTML page. Now the question. How can I disable this? I don't want users to press Yes everytime they come to the page! Is there any way without buying an expensive license from VeriSign ($400) and without changing security settings?
Philip Patrick
Web-site: www.stpworks.com
"Two beer or not two beer?" Shakesbeer
|
|
|
|
|
Implement IObjectSafety (or use IObjectSafetyImpl if you're using ATL). Note that you shouldn't do that if your control really is unsafe - that is, it could cause damage to the registry or file system if whacky params are passed in.
--Mike--
Just released - RightClick-Encrypt - Adds fast & easy file encryption to Explorer
My really out-of-date homepage
Sonork-100.19012 Acid_Helm
|
|
|
|
|
hello,
I've built a DCOM-server (with the ATL in VC++6.0)and installed it on machine01. Afterwards I've implemented a client (console-app) and installed it on machine02. Now the client should be able to launch and access the server on the remote machine(01).
so I added the method:
CoInitializeSecurity(NULL,
-1,
NULL,
NULL,
RPC_C_AUTHN_LEVEL_NONE,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE,
NULL);
after calling CoInitialize(NULL); in the server an client. This should turn off security and I should be able to to launch and access the server... This doesn't work. So I have to do some DCOM-configuration with the dcomcnfg.exe (WinNT4).
Is there a way of implementation, so that I don't have to do the configuration with dcomcnfg.exe and still have the possibility to launch and access the server from machine02 on machine01?
(perhaps I have to implement a installation-programm which is writing the wright entries to the registry...?)
Thanx in advance,
bye,
stefan.
|
|
|
|
|
What kind of errors are you getting?
In the appid key in the registry, set the AuthenticationLevel = 1, the RemoteServerName = the server machine name, and RunAs = "Interactive User".
Win9x machines must have the server app running.
Jason Henderson quasi-homepage articles "Like it or not, I'm right!"
|
|
|
|
|