|
hi
i am new to COM and want to know the difference b/w COM component and ActiveX control.
thanks in anticipations
Muhammad Azam
|
|
|
|
|
|
Thanks a lot, i got it but one thing is still ambiguous........then why do we need ActiveX controls when we have COM ?
thanks in anticipation
Azam
|
|
|
|
|
Hello Azam,
Let take a example for understanding difference between COM DLL and ActiveX Control .
if you are done some Windows Programming, you must have use CreateWindow() (which help in creating window) api, this api is just a function with no user interface but when you use BUTTON on the Dialog box it have UI to interact with it.
same is difference betwwen COM DLL and ActiveX Control . COM Dll proviode you with backward functionality like CreateWindow and ACTIVE X Control provide you BOTH backward Functionality and UI (depend on your need) like BUTTON.
Hope you somewhat grasp the difference between COM DLL and ActiveX Control
"I Think this Will Help"
[Vote One Here,.....]
<h5
alok gupta="" <br=""> visit me at http://www.thisisalok.tk
|
|
|
|
|
thanks Sir........ now i got it clearly. thaks once again for making it clear to me
Azam
|
|
|
|
|
I have written a C++ COM object and I now wish to make some alterations to it.
My current understanding of COM is:
- You can't add or remove methods/properties from an interface, nor can you change parameters on existing methods.
Can someone give me a simple explanation (or point me to one) of why I can't add new methods/properties to an interface? I would have thought that as long as I don't change what's already there, it wouldn’t break binary compatibility. I wrote a small test DLL, built a C++ test app based on it, then added new methods to the interface without rebuilding the test app and it didn't break at runtime. Was I just lucky? Are some languages more/less forgiving about this than others?
- Am I allowed to add new values to an enum that is defined in my IDL?
- What if I have a situation like this:
interface MyInterface
{
[id(1)] HRESULT CreateVideo([out, retval] IVideo** p);
}
I now want to add IVideo2 which implements IVideo.
Assuming that it's illegal for me to simply add CreateVideo2([out, retval] IVideo2** p) to MyInterface, the alternative is to create a whole new MyInterface2 just for CreateVideo2(). But if MyInterface is referenced from another interface then I'd have to create a new version of that interface, except it would reference MyInterface2. And what if *that* interface is referenced by yet another interface? I could suddenly find myself doubling the number of interfaces just to accommodate one small change.
Can I instead change the CreateVideo() code to internally create an IVideo2 object but cast it back as IVideo? That way existing clients can still use the unchanged CreateVideo() interface, while newer clients can then cast the returned object back to IVideo2 and get all the new functionality. Or will this break binary compatibility anyway?
I realise that this is kind of ugly because it requires newer developers to know that they can cast the returned IVideo to IVideo2, but it would sure save a lot of my time as well as cut down on interface bloat.
Any thoughts or advice would be much appreciated!
Gary
|
|
|
|
|
Sir Garence wrote:
why I can't add new methods/properties to an interface?
If you add new methods, and keep the same GUID, you'll write code that starts up a COM object, based on that GUID, and will assume that method is there. for anyone who has your old component, the object will spin up, and blow up when that method is not there.
Christian
I have several lifelong friends that are New Yorkers but I have always gravitated toward the weirdo's. - Richard Stringer
|
|
|
|
|
Hi Christian,
Thanks for responding.
My main concern - and this is the most likely scenario - is older apps running against the newer component. If I add new methods or properties to existing interfaces (but don't remove or change what was already there), will this cause any runtime issues?
Thanks again,
Gary
|
|
|
|
|
On that front, you should be fine. But murphys law states that the reverse scenario will bite you at some point.
Christian
I have several lifelong friends that are New Yorkers but I have always gravitated toward the weirdo's. - Richard Stringer
|
|
|
|
|
Hi,
I'm discovering COM programmation. I've created a client - server application in .Net.
It works fine but for each client, a new server instance is created.
I would like to create only one instance of a server on a remote machine on which clientS could connect to it.
This is the site who helps me to create my client - server : http://my.execpc.com/~gopalan/dotnet/classic_com/com.net_quoteserver.html
Thks a lot
Denis
|
|
|
|
|
Hi sokettepower,
ur COM components appartment should be MTA (Multi-Threaded Appartment), I suppose !
Look out for more info. on STA, MTA and Proxy Stub.
Cheers,
Vishal
|
|
|
|
|
in the SetWindowsHookEx function, I set the _pModule->get_m_hInst() as the HINSTANCE parameter.
The relust of this code is a local hook on the procedure.
"Global hook procedures should be placed in a separate DLL". is com is a separate DLL
hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL,
LowLevelKeyboardProc,
_pModule->get_m_hInst(),
0);
a related article is talking about the subject in a standart DLL (not COM).
http://www.codeproject.com/win32/AntonioWinLock.asp
|
|
|
|
|
I don't see why it couldn't work. Why don't you just try it?
--
My name in Katakana is ヨルゲン.
My name in German is Jörgen.
My name in Mandarin/Kanji is 乔尔根 西格瓦德森.
I blog too now[^]
|
|
|
|
|
Hi nadzzz,
Is ur com object a dll ?
- If it is then u can't install global hook, to install global hook ur application must be an exe (rather than dll)
See the global hook docs for more info.
Cheers,
Vishal
|
|
|
|
|
My COM server should fire the event of a VB client. The code (generated by the Wizard) is as follows
HRESULT Fire_GetResult(VARIANT retResult)
{
CComVariant varResult;
T* pT = static_cast<t*>(this);
int nConnectionIndex;
CComVariant* pvars = new CComVariant[1];
int nConnections = m_vec.GetSize();
...
...
The problem here is that m_vec.GetSize returns 0 and hence the for loop to fire the event is not called and return value is 0xCCCCCCCC
However firing the event works intially and after a few function calls, it stops working!
I am totally confused what could the problem be. Is it because of some memory leak or anything else. Please comment on possible problems.
Also I would like someone to tell me whose responsibility it is to free the BSTR or VARIANT arguments in interface method, server or clients? for both by value and by reference type.
Thank You
Mayur Mahajan
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
I have a problem. I need a COM dll, which takes a string as a filename and has to return a IPropertyBag by reading the file. The file may be simple text file, that consists a name value pairs. Once the file is read, the name value pair has to be added to the IPropertyBag. From the client I should be able to retrieve the name value information from the IPropertyBag.
The interface is defined like this
__interface IMetadataParser : IDispatch
{
[id(0), helpstring("method ParseMetadata")]
HRESULT ParseMetadata( [in] BSTR bstrXMLFilePath, [in,out] IPropertyBag** ppPropMetadataBag );
};
The client code looks like this.
hr = CoCreateInstance( CLSID_CMetadataParser, NULL, CLSCTX_INPROC_SERVER,
IID_IUnknown, (void**)&m_oMetadataParser );
CComObject<csubcomppropertybag> *pIOCRPropBag;
hr = CComObject<csubcomppropertybag>::CreateInstance(&pIOCRPropBag);
CComPtr<ipropertybag> pPropBg = NULL;
HRESULT hResStack = pIOCRPropBag->QueryInterface(IID_IPropertyBag, (void**)&pPropBg);
CComQIPtr<ipersistpropertybag> pISubPPB(m_oMetadataParser);
m_oMetadataParser->ParseMetadata(bstrXMLFilePath, &pPropBg1);
The definition of the class CSubCompPropertyBag is as follows:
typedef std::map<std::string, variant=""> PropBag;
typedef PropBag::iterator PropBag_IT;
typedef std::pair<std::string, variant=""> MapEntryPair;
CComModule _Module; //this should be in client
class ATL_NO_VTABLE CSubCompPropertyBag :
public CComObjectRootEx<ccomsinglethreadmodel>,
public IPropertyBag
{
public:
CSubCompPropertyBag()
{
ATLTRACE(_T("CSubCompPropertyBag is constructed \n"));
}
~CSubCompPropertyBag()
{
PropBag_IT bagIt = m_propBagMap.begin();
while(bagIt != m_propBagMap.end())
{
VARIANT varDel = bagIt->second;
if(VT_BSTR == varDel.vt)
::SysFreeString(varDel.bstrVal);
bagIt++;
}
m_propBagMap.erase(m_propBagMap.begin(), m_propBagMap.end());
ATLTRACE(_T("CSubCompPropertyBag is destructed \n"));
}
DECLARE_PROTECT_FINAL_CONSTRUCT()
DECLARE_NO_REGISTRY()
BEGIN_COM_MAP(CSubCompPropertyBag)
COM_INTERFACE_ENTRY(IPropertyBag)
END_COM_MAP()
//Method implement the IPropertyBag::Read() function
// move property value from private map to *pVar based on pVar->vt
//this function will be called from IPersistPropertyBag::Load() method
// for each property in ATL property map
STDMETHOD(Read)(LPCOLESTR pszPropName, VARIANT *pVar, IErrorLog *pErrorLog)
{
USES_CONVERSION;
if ((pVar == NULL) || (pszPropName == NULL))
return E_INVALIDARG;
std::string sPropName(W2A(pszPropName));
ATLTRACE("CFlowPropertyBag::Read() get called for property %s \n", sPropName.c_str() );
PropBag_IT bagIt = m_propBagMap.find(sPropName);
if (bagIt == m_propBagMap.end())
{
ATLTRACE("Fail to find the property %s in property bag\n", sPropName.c_str());
return E_FAIL;
}
else
{
try
{
VARIANT varValue = bagIt->second;
::VariantInit(pVar);
if(VT_ARRAY != varValue.vt)
{
HRESULT hr = ::VariantCopy(pVar,&varValue);
if(FAILED(hr))
throw E_FAIL;
}
else
{
SAFEARRAY *psaLanguage = varValue.parray;
pVar->vt = VT_ARRAY;
pVar->parray = psaLanguage;
}
ATLTRACE("Set property value from property bag completed\n");
return S_OK;
}
catch(...)
{
return E_FAIL;
}
}
}
//Method implement the IPropertyBag::Write() function
// move property value from *pVar to private map
//this function will be called from IPersistPropertyBag::Save() method
// for each property in ATL property map
STDMETHOD(Write)(LPCOLESTR pszPropName, VARIANT *pVar)
{
USES_CONVERSION;
if ((pVar == NULL) || (pszPropName == NULL))
return E_INVALIDARG;
std::string sPropName(W2A(pszPropName));
ATLTRACE("CFlowPropertyBag::Write() get called for property %s \n", sPropName.c_str() );
try
{
PropBag_IT bagIt = m_propBagMap.find(sPropName);
if (bagIt != m_propBagMap.end())
{
m_propBagMap.erase(bagIt);
}
VARIANT varVal;
::VariantInit(&varVal);
if(VT_ARRAY != pVar->vt)
{
HRESULT hr = ::VariantCopy( &varVal,pVar);
if(FAILED(hr))
throw E_FAIL;
}
else
{
SAFEARRAY *psaLanguage = pVar->parray;
varVal.vt = VT_ARRAY;
varVal.parray = psaLanguage;
}
std::pair<propbag_it, bool=""> ret =
m_propBagMap.insert(MapEntryPair(sPropName, varVal));
if (ret.second != TRUE)
throw E_FAIL;
ATLTRACE(_T("Write property into property bag completed\n"));
return S_OK;
}
catch(...)
{
return E_FAIL;
}
}
PropBag m_propBagMap;
};
Thanks in advance for the help.
|
|
|
|
|
Hi,
I have a COM service running under a W2000 machine.
I know the service starts when I turn the machine on, before I log on, but I would like to know how to get a notification that the user has logged on/off the machine.
Thanks in advance,
Vinicius
|
|
|
|
|
Here you answer again
For that you have to write Winlogon Notification Package.
look for example here
http://www.codeproject.com/system/winlogon_notification_package.asp
"I Think this Will Help"
[Vote One Here,.....]
<h5
alok="" gupta="" <br=""> visit me at http://www.thisisalok.tk
|
|
|
|
|
|
|
Hello,
i develop a printerui dll, that based on the com-interface. My problem is, that the com-object the threat, that i startet, terminated.
What can i do, that this problem is gone.
Thanks.
- Sorry for my bad english.
|
|
|
|
|
I'm trying to use some Excel COM from Visual C++, but am having difficulty calling certain functions. For example, take the WorkSheets.Add method. The function declaration is as follows:
LPDISPATCH Add(const VARIANT& Before, const VARIANT& After, const VARIANT& Count, const VARIANT& Type);
By looking in the Excel VBA Help, I can get documentation for this method:
Add Method (Worksheets Collection)
Creates a new worksheet. The new worksheet becomes the active sheet. Returns a Worksheet object.
Syntax
expression.Add(Before, After, Count, Type)
expression Required. An expression that returns a Worksheets object.
Before Optional Variant. An object that specifies the sheet before which the new sheet is added.
After Optional Variant. An object that specifies the sheet after which the new sheet is added.
Count Optional Variant. The number of sheets to be added. The default value is one.
Type Optional Variant. The sheet type. Can be one of the following XlSheetType constants: xlWorksheet, xlExcel4MacroSheet, or xlExcel4IntlMacroSheet. The default value is xlWorksheet.
Remarks
If Before and After are both omitted, the new sheet is inserted before the active sheet.
OK, now for some example code. I can add a new worksheet quite easily using the following code:
COleVariant VOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);<br />
ws.Add(VOptional, VOptional, VOptional, VOptional
The problem is that this default usage inserts the sheet before all current sheets in my workbook, but I want to insert it after all the other sheets. In Excel VBA, I can do this by simply running:
Worksheets.Add.Move after:=Worksheets(Worksheets.Count)
However, I'm having real trouble finding what the data type of the 'After' argument needs to be in C++ and I can't find any sample code anywhere! I have found hundreds of examples passing numbers or strings, but not objects! Can anyone supply some sample code?
Using the _Worksheet.Move method would also accomplish the same thing, but I have the same problem, so any help would be greatly appreciated!
|
|
|
|
|
Just in case anyone needs to do this, I figured out how to do it. The 'after' parameter needs to represent the IDispatch pointer of the worksheet you want to add the new sheet after. So you have to do something like this:
COleVariant var;<br />
var.vt = VT_DISPATCH | VT_BYREF;<br />
var.ppdispVal = &(objSheet.m_lpDispatch);<br />
<br />
sheet = objSheets.Add(VOptional, var, VOptional, VOptional);
In the above, objSheets is of type Workbooks and objsheet and sheet are of type _Worksheet
|
|
|
|
|
I have a windows service which creates another process after it is started. Now in the process that is created i create a COM object with an interface and few methods on it. Now if I run the Service with a Login I can access the interface of the COM object by regisrtering the interface in running object table and then getting it from there in the main service.
How ever if I run the servcie with LocalSystem account I cannot get the Interface pointer from the Running object table
What could be the problem? Is there another way of doing this
Thanks
Ravi
|
|
|
|
|
Hi !
(Excuse-me, I hope that this message, will not be inserted inside the current discussion . I want to post a new message, a new discussion, but I don't know how to do.Here is my purpose)
I have developped a software which manage modem through serial
communications. That is why, I have imported the component MSComm32.ocx
in my application.
I have used .NET for my purpose . The installer application is
defined to register the component MScomm32 into the computer (A) on
which we make the installation. At this stage, there is no problem, the
installation of my application is successful. But when I launch my
application, there is a fail;
N.B. : The component MSComm32.ocx is inside the environnement Visal
Basic 6.0 , but not inside Visual Basic .NET developpement environment.
After the fail, I have installed VB 6.0 on the computer (A). And
now, the launch is successful. I have realized that, at run, the
component MSComm32.ocx refers another components (DLL), inside VB 6.0
So , my probelm I want to figure out is this : what are the satellite
components of MsComm32.ocx ? What am I going to do, to list all thise
components ?
|
|
|
|
|