|
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 ?
|
|
|
|
|
Look in the module MSComm32.dep. It require comcat.dll and also optionally other components for support of languages other than english.
Since you are using the control in VB.NET you must also insure that the Interop assembly(s) for the control are also installed!
Hope this helps,
Robert
|
|
|
|
|
The version without popup window?
Thanks!
|
|
|
|
|
I want to write a simple XML editor with the help of MSXML. I'm using the library with smart pointers. I can read out the xml file and can display its structure within a treectrl, but I want to store a pointer to the specific element in the ItemData (DWORD) of the according treectrl item. What do I have to store (Interface*, IXMLDOMElementPtr) and how do I create the IXMLDomElement from that pointer? Do I have to care about releasing/allocating memory? Sorry for that silly question, but I don't have much experience with COM.
Thank you very much in advance,
Konrad
|
|
|
|
|
Does anyone know if it is possible to store a custom object inside a word document?
Let's say for example that I would like to save inside a word document the ID of the machine the document was created on. That information would be hidden from the user but stored inside the word document and could be retrieved programatically.
Help... Anyone?
Thanks,
Merlinos
|
|
|
|
|
Hi,
I hope this post belongs here...it seems to me to be some sort of COM issue, so here goes...
I have been working on a .NET add-in for Word 2003. I have created the project as a "Shared Add-in" according to this tutorial:
http://support.microsoft.com/kb/302896/EN-US/
My problem is that when I run the installer for this add-in on a machine other than the development machine it doesn't show up in Word.
The generated MyAddinSetup project doesn't seem to install the add-in correctly. I've tried both "For everyone" and "For this user only" to no avail.
I've also tried using regasm to register the .dll in the registry on the test machines, but nothing seems to work.
I've verified that both the Addin and the AddinSetup projects reference the Office 2003 PIAs; basically everything I've been able to pull up on the subject.
I've still yet to get this thing to run on any machine that doesn't have Visual Studio .NET 2003 installed. I have ensured that my test machines do have the .NET framework v1.1 installed, and that Office 2003 was installed with the .NET programmability feature enabled.
Has anyone had similar problems? Am I missing something obvious?
Any help is appreciated.
Thanks.
|
|
|
|
|
Hi m6reid,
Are you registering this add-in in restricted user mode on Win2K ?
Cheers,
Vishal
|
|
|
|
|
get the picture of the first page of MS Word doc, and save it to bmp?
|
|
|
|
|
The snapshot of the every office file's first page is stored in the form
of metafile inside some interface. Check IViewObject interface or search
the following newsgroup for extracting the metafile from the interface.
microsoft.public.win32.programmer.ole
Cheers,
Vishal
|
|
|
|
|
Hello , iam a new vc++ programmer,
I want to creaet an xml file using mxxml3.0
I had used every possible way 2 do that , every time
the functionc
CreateProcessingInstruction
&
raw_CreateProcessingInstruction
are throughing the run time exception.
plz help me i am trying 4 that since last 6 days. any sugestion would be helpful.
any place 2 find the proper code rather than msdn ,
i don't want 2use wrapper class 4 this.
Rahul Agarwal
|
|
|
|
|
I have a com server that mainly runs as embedded in main application. My main application is basically a mapping application that 'contains' these embedded servers. The servers basically manipulate the mapping data in their respective way. I am having a resource problem between my main application exe and one of my server exes during mouse movements. It seems that this particular server CPU starves my main application more than any other server during mouse movements. I came across the GetActivationPolicy on the IPointerInactive interface and COleControl class. Is there a way that I can modify the server to not utilize the CPU as much during mousemovements?
Any help is greatly appreciated -
|
|
|
|
|
You have meant to put this in, but where is CoInitialize()?
|
|
|
|
|
I have data in the form of an array, i want to display it to the user in tabular form in excel, allow the user to make modifications to it and again get the modified data back into the the original array in c++. i want some guidance on this, how to deal with the exporting to excel and how to import the data back to c++. i will highly appreciate your help if you provide me some snippets of code also,
Thanks a lot
|
|
|
|
|
Hello,
I´ve to transfer some VB code to C++. Now there is the following problem:
------------
Dim MediaEvent as HiPathProCenterLibrary.MediaEvent
Dim DeliveredEvent As HiPathProCenterLibrary.DeliveredEvent
...
<calling some="" methods="" of="" mediaevent="">
...
Set DeliveredEvent = MediaEvent
...
<calling some="" methods="" of="" deliveredevent="">
-------------
My problem is that I´ve no idea on how to cast (?) the MediaEvent to the DeliveredEvent (interfaces are not the same and none of them inherits it´s functionality of the other).
What is VB doing in this "Set Command"? What is the equal source code in C++?
Thank you for any help,
Stefan
|
|
|
|
|
I assume that MediaEvent and DeliveredEvent are COM interfaces.
To cast a COM interface from one interface into another use QueryInterface.
I.e.
void f(IMediaEvent * p)
{
if( p != NULL )
{
IDeliveredEvent * l_p(NULL);
HRESULT const l_hr(p->QueryInterface(
IID_IDeliveredEvent,
reinterpret_cast<void**>(&l_p)));
if( SUCCEEDED(l_hr) )
{
l_p->Release();
}
}
}
Using some sort of smart pointer (for instance CComQIPtr) is preferrable.
|
|
|
|
|
Thank you very much. It seems to work fine!
Stefan
|
|
|
|
|