|
FriendOfAsherah wrote: In c++ I could overload the class which implements the calls to the COM / Active X object I used and add additionally member functions in the overloaded class.
How do that in c# with NET ? The "object" I get is only an interface with a CoClass. Deriving from the interface without implementation of all functions of the CoClass is not possible ... I dont have any dispatch pointer etc...
The member function should access a static Hashtable which returns some values.
Any Idea ?
In C#, I think you're reduced to writing a class that contains the COM object. Your class could implement the interface by just passing the calls on to the contained object, but it's still a lot more work than you'd need in C++.
Nathan
|
|
|
|
|
Yes, but away from defining about 40 properties,functions get/set I dont know how to write them becouse:
The Interface class shows only the definitions like:
[DispId(0)]
string _Name { get; set; }
The CoClass similar like:
[DispId(0)]
public virtual string _Name { get; set; }
Which code to write into the class which inherits from the Interface ???
public class CMyClass : ICOMClass
{
public virtual string _Name { get { ??? }; set{ ??? }; }
....
I cannot leave the get/set empty but I dont have any parameters
Or how can I put something like a DispatchId and a dispatch pointer there ??
|
|
|
|
|
FriendOfAsherah wrote: Yes, but away from defining about 40 properties,functions get/set I dont know how to write them becouse:
The Interface class shows only the definitions like:
[DispId(0)]
string _Name { get; set; }
The CoClass similar like:
[DispId(0)]
public virtual string _Name { get; set; }
Which code to write into the class which inherits from the Interface ???
public class CMyClass : ICOMClass
{
public virtual string _Name { get { ??? }; set{ ??? }; }
....
I cannot leave the get/set empty but I dont have any parameters
Or how can I put something like a DispatchId and a dispatch pointer there ??
My guess is it would be:
public class CMyClass : IComClass
{
private IComClass m_Inner;
public virtual string _Name
{
get {return m_Inner._Name;}
set{m_Inner._Name = value}
}
...
and the constructor would set m_Inner to a new instance of ComClass, or use one provided to it.
Nathan
|
|
|
|
|
How easy ... by containment ...
This works !!
I spend hours trying to use typecasting and calling base.Function() and base.Property=...
This is the COM Interface I have:
[CoClass CCOMClass]<br />
...<br />
public interface ICOMOuter : ICOMInner<br />
{
}<br />
<br />
public interface ICOMInner<br />
{<br />
[DispId1]<br />
public string Property1 { get; set; }<br />
... etc.<br />
}<br />
And I tried derive, inherit with:
public class MyClass : ICOMOuter<br />
{ ....<br />
}<br />
And
public class MyClass : ICOMOuter , ICOMInner<br />
{ ...<br />
}<br />
both never compiled ....
Dont know why until now
Thanks a lot :-Dfor the idea !
|
|
|
|
|
Creating a COM dll -module that fires events is simple enough (ATL -project -> add ATL simple object with Connection point -support -> Add a couple methods etc.), but:
What flags are needed for multiple instances to catch the same event when it is fired? I.e. when I CoCreateInstanceEx a connection to module from let's say 2 separate exe's, both can receive the same event. Tried quite a few combinations so far and yet no success.
|
|
|
|
|
You need another Class Factory. Use the DECLARE_CLASSFACTORY_SINGLETON macro. In this case all COM-clients get the same instance. In this case your COM-Object must be threadsafe !
Greetings
|
|
|
|
|
Even with singleton COM objects if it is an in-process component then you'd still get separate notifications from multiple EXE clients. You would either have to make the component out-process or CoCreateInstance it from one EXE and load it up into the Running Object Table (ROT) using RegisterActiveObject and grab a reference to it from the second EXE using GetActiveObject .
|
|
|
|
|
That did the trick. Thanks a lot!
|
|
|
|
|
Quesiton:
i encounter the trouble when i invoke execmthod.(wmi)
the return error is WBEM_E_INVALID_METHOD_PARAMETERS.
I have a specail situation than standard one.
that is the method's input parameter is also an wmi class.(it is defined by my bios)
therefore, when i invoke getmethod() to get input param object, I can't direct put data into property by put() method.
(because the property is defined inside the wmi class)
so i invoke the getobject to get the new input param object.
And i put the data into the property.
Final, i use the new input param object for the execmethod's input param.
And the error appears.
Who can help me to sovle such problem?
thanks
|
|
|
|
|
What is TLB file? What Regtlib does? Does it create any specific kind of structure in the Registry under HKEY_CLASS_ROOT while registring the TLB file?
Ajay kumar, Sr System Analyst
Satyam Computers, Banglore
India
ajay.kumar.ind@gmail.com
|
|
|
|
|
TLB[^]
From MSDN -
RegTLib is used for .tlb registration for stdole2.tlb. Regtlib.exe calls the LoadTypeLib and RegisterTypeLib application program interfaces (APIs) on the type library (.tlb or .olb) file that is passed in.
hiajay wrote: Does it create any specific kind of structure in the Registry under HKEY_CLASS_ROOT while registring the TLB file?
Yes, TLB registration is done under HKEY_CLASSES_ROOT\TypeLib.
FYI, if you are working with COM Interop in .NET, then you may want to look at
tlbimp.exe[^]
tlbexp.exe[^]
Sohail
modified 21-Apr-21 21:01pm.
|
|
|
|
|
What about C++ based TLB.What are the subkey created inside HKEY_CLASSES_ROOT\TypeLib
Thanks
Ajay
|
|
|
|
|
hiajay wrote: C++ based TLB
TypeLibrary is independent of C++
I would suggest going through the following link to understand TypeLibrary
http://msdn2.microsoft.com/en-us/library/aa366757.aspx[^]
Also, reading "Essential COM" or "Inside COM" book will be helpful.
Sohail
modified 21-Apr-21 21:01pm.
|
|
|
|
|
Hello
What are the best resources / books to start learning COM?
Thanx
|
|
|
|
|
There are a lot of good articles here at CP.
go into All Topics, MFC/C++ >> COM/DCOM/COM+ section, check out, for instance the beginners articles.
There are, of course, a pletora of good books about COM. A nice one is Don Box's Essential COM [^]
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
I can advise the Microsoft author "Beck Zaratian"... Book names is "Programmer's Guide". I can sale mine? if you want?
What is this¿
|
|
|
|
|
And so you suggest a title you're selling out?
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
50$ + cargo expenses!
What is this¿
|
|
|
|
|
|
So.. Might i leaving the preference to you... Actually, there is 1 sample in this book care about COM. Maybe you know, have only "TowerCtrl" sample. When I saw ur forum msg.. i acted without thought... But this book explaining all about the ActiveX programming using ATL or MFC of course as introduction. Sorry friend. Actually this is a development kid what about the Microsoft System Engineering. I'd like to sale it. If you want to build a career on the Software Development I can sale to all of them as development kid.(50$) Because I am feeling sorry with buying it. If you obstinate for COM pls take a look at the http://www.amazon.com by searching as "developers workshop ATL/COM"... You will be able to see many section care about ATL/COM..
Yours sincerely.
-- modified at 14:41 Friday 2nd November, 2007
What is this¿
|
|
|
|
|
Hi all.
How can I get the coordinates IHTMLLIElement (Highlights, Latest releases, Using your computer, ..) at www.microsoft.com
code:
pDoc2 - pointer to the document frame containing element
pElement - pointer at the element
Text - text links
void CExplorerWindow::GetLinkRect(CComPtr<ihtmldocument2> pDoc2, CComQIPtr<ihtmlelement,&iid_ihtmlelement> pElement, BSTR Text, LPRECT Rect)
{
long Top = 0;
long Hight = 0;
long Left = 0;
long Width = 0;
CComPtr<idispatch> pDisp = NULL;
if (pWebBrowser2)
{
pWebBrowser2->get_Document (&pDisp);
if (pDisp)
{
CComPtr<ihtmldocument2> pDoc = NULL;
pDisp->QueryInterface (IID_IHTMLDocument2, (void **) &pDoc);
if (pDoc)
{
CComPtr<ihtmlframescollection2> m_frame = NULL;
pDoc->get_frames(&m_frame);
if (m_frame)
{
long len = 0;
m_frame->get_length (&len);
if (len)
{
CComQIPtr<ihtmlelement> pEl ;
if (SUCCEEDED(pDoc2->get_body(&pEl)))
{
CComQIPtr<ihtmlbodyelement> pBodyElement ;
pBodyElement = pEl;
if (pBodyElement)
{
CComQIPtr<ihtmltxtrange> pTxtRange;
pBodyElement->createTextRange(&pTxtRange);
if (pTxtRange)
{
if (pTxtRange->moveToElementText(pElement) == S_OK)
{
VARIANT_BOOL ok;
if (pTxtRange->findText(Text,wcslen(Text),0,&ok) == S_OK)
{
CComQIPtr<ihtmltextrangemetrics2> pTextRangeMetrics2;
pTextRangeMetrics2 = pTxtRange;
CComQIPtr<ihtmlrectcollection> ptrRectColl;
CComQIPtr<ihtmlrect> ptrHTMLRect;
if (pTextRangeMetrics2->getClientRects(&ptrRectColl) == S_OK)
{
long Len;
ptrRectColl->get_length(&Len);
if (Len)
{
VARIANT VarInd, VarDisp;
VarInd.vt = VT_I4;
for(int i = 0; i < Len;i++)
{
VarInd.lVal = i;
ptrRectColl->item (&VarInd, &VarDisp);
ptrHTMLRect = VarDisp.pdispVal;
long Top = 0;
long Right = 0;
long Left = 0;
long Bottom = 0;
if (ptrHTMLRect)
{
ptrHTMLRect->get_left (&Left);
ptrHTMLRect->get_top (&Top);
ptrHTMLRect->get_right (&Right);
ptrHTMLRect->get_bottom(&Bottom);
//!!! Left, Top, Right, Bottom - 0
}
SetRect(Rect, Left, Top, Right, Bottom);
}
}
else
{
pElement->get_offsetHeight(&Hight);
pElement->get_offsetWidth(&Width);
pElement->get_offsetTop(&Top);
pElement->get_offsetLeft(&Left);
IHTMLElement* pParentElement = NULL;
while (SUCCEEDED(pElement->get_offsetParent(&pParentElement)))
{
if (!pParentElement) break;
long ParentLeft, ParentTop;
pParentElement->get_offsetTop(&ParentTop);
pParentElement->get_offsetLeft(&ParentLeft);
Top += ParentTop;
Left +=ParentLeft;
pElement = pParentElement;
pParentElement->Release();
}
}
ptrRectColl.Detach();
}
}
}
}
}
}
}
else // no frames
{
CComQIPtr<ihtmlelement2> pElement2(pElement);
CComPtr<ihtmlrect> BoundingRect;
if (pElement2)
{
if (SUCCEEDED(pElement2->getBoundingClientRect(&BoundingRect)) && BoundingRect)
{
BoundingRect->get_top(&Top);
BoundingRect->get_left(&Left);
}
else
{
Top = 0; Left = 0;
}
}
pElement->get_offsetHeight(&Hight);
pElement->get_offsetWidth(&Width);
SetRect(Rect, Left, Top, Left + Width, Top + Hight);
}
}
else //m_frame == 0
{
CComQIPtr<ihtmlelement2> pElement2(pElement);
CComPtr<ihtmlrect> BoundingRect;
if (pElement2)
{
if (SUCCEEDED(pElement2->getBoundingClientRect(&BoundingRect)) && BoundingRect)
{
BoundingRect->get_top(&Top);
BoundingRect->get_left(&Left);
}
else
{
Top = 0; Left = 0;
}
}
pElement->get_offsetHeight(&Hight);
pElement->get_offsetWidth(&Width);
SetRect(Rect, Left, Top, Left + Width, Top + Hight);
}
}
}
}
if (IsRectEmpty(Rect)) Beep(200,100); - only if pElement == Highlights, Latest releases, Using your computer, ..
}
|
|
|
|
|
I am trying to extract the words and punctuation from a word document. I am having a heck of a time finding thorough documentation on the strings to pass (Ex: L"Document", L"Words", L”Open”, etc.) and the patterns to use in the calls. The code I am using has been extracted and tweaked from the MS support site examples. What I have found is a good start except it all stops short of showing how to grab the words from the file. This code runs but it does not actually pull the words from the file in the line:
AutoWrap(DISPATCH_PROPERTYGET|DISPATCH_METHOD, &rVal, pDoc.pdispVal, L"Words", 1, parm[0]);
The Code:
HRESULT AutoWrap(int autoType, VARIANT *pvResult, IDispatch *pDisp, LPOLESTR ptName, int cArgs...) {
// Reduced code...
// Get DISPID for name passed...
hr = pDisp->GetIDsOfNames(IID_NULL, &ptName, 1, LOCALE_USER_DEFAULT, &dispID);
// Handle special-case for property-puts!
if(autoType & DISPATCH_PROPERTYPUT) {
dp.cNamedArgs = 1;
dp.rgdispidNamedArgs = &dispidNamed;
}
// Make the call!
hr = pDisp->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, autoType, &dp, pvResult, NULL, NULL);
return hr;
}
int main(int argc, char* argv[]){
// Initialize the OLE Library...
OleInitialize(NULL);
// Set WordApp = CreateObject Word.Application
{
CLSID clsid;
CLSIDFromProgID(L"Word.Application", &clsid);
HRESULT hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER|CLSCTX_INPROC_SERVER, IID_IDispatch, (void **)&rVal.pdispVal);
// WordApp . DisplayAlerts = 0
rVal.vt = VT_I4;
rVal.lVal = 0;
AutoWrap(DISPATCH_PROPERTYPUT, NULL, pWordApp.pdispVal, L"DisplayAlerts", 1, rVal);
VariantClear(&rVal);
// WordApp . Documents . Open wordPath , 0 , 1
AutoWrap(DISPATCH_PROPERTYGET|DISPATCH_METHOD, &pDoc, pWordApp.pdispVal,
L"Documents", 0);
parm[1].vt = VT_I4;
parm[1].lVal = 0;
parm[2].vt = VT_I4;
parm[2].lVal = 1;
AutoWrap(DISPATCH_METHOD, NULL, pDoc.pdispVal, L"Open", 3, parm[2], parm[1], parm[0]);
// Set pDoc = WordApp . Documents 1
parm[0].vt = VT_I4;
parm[0].lVal = 1;
AutoWrap(DISPATCH_PROPERTYGET|DISPATCH_METHOD, &pDoc, pWordApp.pdispVal, L"Documents", 1, parm[0]);
// Get count of words in document
AutoWrap(DISPATCH_PROPERTYGET|DISPATCH_METHOD, &pWords, pDoc.pdispVal, L"Words", 0);
AutoWrap(DISPATCH_PROPERTYGET|DISPATCH_METHOD, &rVal, pWords.pdispVal, "count", 0);
long endVali = rVal.lVal;
i.vt = VT_I4;
for(i.lVal=1; i.lVal<=endVali; i.lVal++) {
VariantCopy(&parm[1], &i);
parm[0].vt = VT_I4;
parm[0].lVal = 1;
AutoWrap(DISPATCH_PROPERTYGET|DISPATCH_METHOD, &rVal, pDoc.pdispVal, L"Words", 1, parm[0]);
wcstombs_s(0, buf, 5, rVal.bstrVal, 512);
::MessageBoxA(NULL, buf, "Word ", 0x10000);
VariantClear(&rVal);
}
}
AutoWrap(DISPATCH_METHOD, NULL, pDoc.pdispVal, L"Close", 0);
AutoWrap(DISPATCH_METHOD, NULL, pWordApp.pdispVal, L"Quit", 0);
// Close the OLE Library...
OleUninitialize();
}
Can someone help debug this code or at least tell me where I can find documentation that show the hierarchy of calls/strings to pass in order to get the information needed from the Word2003 document? Thanks in advance for your help!
wtg3
|
|
|
|
|
I have an ActiveX control for embeding in web page with opbject tag.
Now two problems:
1. I want to load data from internet location(like http://myserver/data.txt) from within ActiveX.
2. Get an IStream object of the data stream
Thanks
|
|
|
|
|
Try to use IBindStatusCallback interface.
|
|
|
|
|
Hai all
I'm using the active desktop Interface to get the current destop item count using the function GetDesktopItemCount(&count,0);
But on my desktop there is more than 10 things and the count value got by GetDesktopItemCount() is '1'.Why is it so.
Please reply.
My OS is XP.
Thanks in Advance
Robs
|
|
|
|
|