|
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!"
|
|
|
|
|
Thank you for your reply,
but I finally managed it doing it like I was told in the fabolous articel:
Code Project/COM / DCOM / COM+ - DCOM D-Mystified: A DCOM Tutorial, Step 1-7 by Brian Hart
so I think I just have to implement some kind of installation-tool to adjust dcomcnfg.exe, so that I'm able to install the server and config the registry at the same time, so that everything is worling fine (good luck (:oD)).
have a nice day,
bye,
stefan
|
|
|
|
|
Hey, can anyone give any recommendations of good books that I can get that will help with my COM/OLE/ATL woes? I am using COM/OLE (and/or ATL) and trying to incorporate MS Word into an application, add a toolbar button dynamically, and other processing, and I was wondering if anyone knew of any books that might be good, possibly show some examples, etc. I would like to get a couple of books that might be working with Word in them. Any ideas would be appreciated!!!
I have looked at various posts on this website and a few others and they have helped alot. But they just don't seem to work in my application and I am not sure why...
|
|
|
|
|
Hey, I know I posted a message about a problem not too long ago but I am working on a different approach and I ran into some trouble. I am trying to capture the event and I tried to use the Building Office2k Addin as a guide. I had a problem with the last approach so I tried to rework it. No luck, now I am getting the message:
error C2787: '_CommandBarButtonEvents' : no GUID has been associated with this object
My Addin.h file looks like this:
// Addin.h : Declaration of the CAddin
#ifndef __ADDIN_H_
#define __ADDIN_H_
#include "resource.h" // main symbols
#include "mso.h"
#include "msword.h"
#import "C:\Program Files\Common Files\Designer\MSADDNDR.DLL" raw_interfaces_only, raw_native_types, no_namespace, named_guids
/////////////////////////////////////////////////////////////////////////////
// CAddin
extern _ATL_FUNC_INFO OnClickButtonInfo;
class ATL_NO_VTABLE CAddin :
public CComObjectRootEx<ccomsinglethreadmodel>,
public CComCoClass<caddin, &clsid_addin="">,
public ISupportErrorInfo,
public IDispatchImpl<iaddin, &iid_iaddin,="" &libid_autoproject3lib="">,
public IDispatchImpl<_IDTExtensibility2, &IID__IDTExtensibility2, &LIBID_AddInDesignerObjects>,
public IDispEventSimpleImpl<1, CAddin, &__uuidof(Office::_CommandBarButtonEvents)>
{
public:
typedef IDispEventSimpleImpl CommandButton1Events;
CAddin()
{
}
DECLARE_REGISTRY_RESOURCEID(IDR_ADDIN)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CAddin)
COM_INTERFACE_ENTRY(IAddin)
//DEL COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(ISupportErrorInfo)
COM_INTERFACE_ENTRY2(IDispatch, IAddin)
COM_INTERFACE_ENTRY(_IDTExtensibility2)
END_COM_MAP()
BEGIN_SINK_MAP(CAddin)
SINK_ENTRY_INFO(1, __uuidof(Office::_CommandBarButtonEvents), /*dispid*/0x01, OnClickButton, &OnClickButtonInfo)
END_SINK_MAP()
// ISupportsErrorInfo
STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
void __stdcall OnClickButton(IDispatch * /* Office::_CommandBarButton**/ Ctrl, VARIANT_BOOL * CancelDefault);
// IAddin
public:
// _IDTExtensibility2
STDMETHOD(OnConnection)(IDispatch * Application, ext_ConnectMode ConnectMode, IDispatch * AddInInst, SAFEARRAY * * custom)
{
COleVariant covTrue((short) TRUE),
covFalse((short) FALSE),
covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
Word::_Application Wordapp;
Office::_CommandBars oBars = Wordapp.GetCommandBars(); // New CommandBars
// collection object
Office::CommandBar oBar;
Office::CommandBarControls oControls;
Office::_CommandBarButton oButton;
VARIANT vName;
vName.vt = VT_BSTR;
vName.bstrVal = SysAllocString(L"PSI");
VARIANT vPosition;
vPosition.vt = VT_I2;
vPosition.iVal = 1; // 4 = Floating; 0 = top;
// Add new bar to the command bars collection
Office::CommandBar oNewBar = oBars.Add(vName, // const Variant Name
vPosition, // const Variant Position
covFalse, // const Variant (replace)MenuBar
covTrue // const Variant Temporary
);
oNewBar.SetVisible(TRUE);
// Get the collection (now empty) of controls on the new commandbar
Office::CommandBarControls oNewControls = oNewBar.GetControls();
VARIANT vType;
vType.vt = VT_I4;
vType.lVal = (long)1;
Office::_CommandBarButton oNewButton1 = // Office XP - note leading underscore
oNewControls.Add(vType, // Type = msoControlButton
covOptional, // Id
covOptional, // Parameter
covOptional, // Before
covTrue // Temporary
);
oNewButton1.SetStyle(3); // msoButtonIconAndCaption
oNewButton1.SetCaption("PSI Save & Exit");
oNewButton1.SetTooltipText("This is a new button");
oNewButton1.SetVisible(TRUE);
oNewButton1.SetState(0); // msoButtonUp
OpenClipboard(NULL); // Reserve clipboard for this program
CBitmap MyBitmap;
MyBitmap.LoadBitmap(IDB_BITMAP1); // A Bitmap you drew in the
// Resource Editor
HBITMAP MyBitmapHandle = (HBITMAP)MyBitmap; // Cast it to a HBITMAP
SetClipboardData(CF_BITMAP, MyBitmapHandle);
CloseClipboard(); // Free clipboard so PasteFace() can use it
oNewButton1.PasteFace();
hr = CommandButton1Events::DispEventAdvise((IDispatch*)m_spButton);
if(FAILED(hr))
return hr;
bConnected = true;
return S_OK;
}
STDMETHOD(OnDisconnection)(ext_DisconnectMode RemoveMode, SAFEARRAY * * custom)
{
if(bConnected)
{
HRESULT hr = CommandButton1Events::DispEventUnadvise((IDispatch*)m_spButton);
if(FAILED(hr))
return hr;
}
return S_OK;
}
STDMETHOD(OnAddInsUpdate)(SAFEARRAY * * custom)
{
return E_NOTIMPL;
}
STDMETHOD(OnStartupComplete)(SAFEARRAY * * custom)
{
return E_NOTIMPL;
}
STDMETHOD(OnBeginShutdown)(SAFEARRAY * * custom)
{
return E_NOTIMPL;
}
private:
Office::_CommandBarButton m_spButton;
bool bConnected;
// _IDTExtensibility2
};
#endif //__ADDIN_H_
I am new to COM/ATL programming and I am getting confused. Can Anyone Help!!!
|
|
|
|
|
Thanks in advance for any help. I am trying to create an ATL server using the example "Building an Office2K COM addin with VC++/ATL". I am having a problem with the imports. Here is my stdafx.h:
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently,
// but are changed infrequently
#if !defined(AFX_STDAFX_H__613C434D_55D9_45D2_937E_C26FA13D3F22__INCLUDED_)
#define AFX_STDAFX_H__613C434D_55D9_45D2_937E_C26FA13D3F22__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define STRICT
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0400
#endif
#define _ATL_APARTMENT_THREADED
#include
//You may derive a class from CComModule and use it if you want to override
//something, but do not change the name of _Module
extern CComModule _Module;
#include
//{{AFX_INSERT_LOCATION}}
#import "C:\Program Files\Common Files\Microsoft Shared\Office10\mso.dll" rename_namespace("Office") named_guids
using namespace Office;
#import "C:\Program Files\Microsoft Office\Office10\MSWORD.olb" rename("ExitWindows", "WordExitWindows"), named_guids, raw_interfaces_only
using namespace Word;
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__613C434D_55D9_45D2_937E_C26FA13D3F22__INCLUDED)
Unfortunately, I keep getting the error message:
StdAfx.obj : fatal error LNK1179: invalid or corrupt file: duplicate comdat "_IID_CanvasShapes"
Any ideas what I need to do to fix this problem? I am new to ATL but I was thinking the "using namespace Word" should have taken care of any duplicates. I used the article as an example because I am not using Outlook, instead I am using MS Word. Any thoughts?
|
|
|
|
|
How does your stdafx.cpp look. Mail me the code if possible. It happens sometimes if you use Interface refernce in the main project file.
|
|
|
|
|
Any luck on the code? I have been trying different things but nothing has worked yet???
|
|
|
|
|
I can guess that you are using Office XP but are you using VS.NET? the #import statements works fine for me (MSVC6.0 and Office2k), so I really can't say what the problem is. Once you get over your #import, I think the code will work fine.
Anyway, have you tried the exclude keyword to exclude redundant/duplicate IID's/GUID's in #import?
You yard yellow years yieldingly; you yanked your yearning yoke.-Jeremy Falcon-CPite.
Amit Dey
sonork: 100:18407
msn: visualcdev
|
|
|
|
|
No, I am using VC 6.0, I have not used VC.NET yet. I have tried to exclude the duplicate IID's but after the 10th or 15th one, I thought this is not the correct way to do this. It seems that there are several (A LOT) of duplicates, not just the on. I used the example of the Office2K and Outlook and Outlook does not have the same IID's as Office. But apparently, Word does for some reason???
|
|
|
|
|
Yeah, I came across a similar duplicate IID problem while building Word addin. I know how frustrating this is!!
If you already haven't figured out, the solution is to move the #import statement for importing Word typelib(the 2nd #import) to your addins .h file.
e.g. I put the following #imports in my Addin.h file. so it looks like :
#ifndef __ADDIN_H_
#define __ADDIN_H_
#include "resource.h" // main symbols
#import "D:\Program Files\Common Files\designer\MSADDNDR.TLB" raw_interfaces_only, raw_native_types, no_namespace, named_guids
#import "D:\Program Files\Microsoft Office\Office\MSWORD9.olb" rename_namespace("MSWORD"), rename("ExitWindows","WordExitWindows"), named_guids, raw_interfaces_only
using namespace MSWORD;
and then rebuild.
HTH,
'My capacity for happiness', he added, 'you could fit into a matchbox without taking out the matches first'.
- Marvin, the robot.
Amit Dey
sonork: 100:18407
msn: visualcdev
|
|
|
|
|
Thanks, I will try it out!
|
|
|
|
|