|
Thank u for help.
Jim
|
|
|
|
|
Why doesn't this outgoing interface have an onclick event? I need to catch that event? Can anyone tell me how??? Is this a bug with MSHTML?? Thank you.
|
|
|
|
|
Try the IHTMLEditDesigner interface. There's an article here on CP about it
Rob Manderson
I'm working on a version for Visual Lisp++
|
|
|
|
|
I tried with IHTMLEditDesigner but it doesn't work. Any clicks on an Object on a web page(I tried with www.ultrastar.com) do not go thru PreHandleEvent() and PostHandleEvent() of IHTMLEditDesigner. However clicks on other elements on the web page do invoke PreHandleEvent() and PostHandleEvent(). But my problem is to catch the clicks on Objects/Applets on a web page. All events sets like HTMLLinkElementEvents, HTMLElementEvents, HTMLButtonElementEvents etc have onclick events but this HTMLObjectElementEvents only doesn't have onclick, mouseup and mousedown events. Please help.
|
|
|
|
|
Hi,
Is there a way to tap data passing over pipe in RPC..?
I am using RPC between two applications within the same system using pipes(windows). For some other reason i have to tap the data communicaing b/w server and client in RPC. I tried this way but unfortunately this is not working.
opened server & client with protocol sequence using named pipes. server connected to pipe "pipe_server" and client connect to pipe "pipe_client". I created a stub code opening the other ends of pipe_client & pipe_server. I coded such that, after storing this data to file then i can sending the received data to the other pipe. and this way i can make RPC alive. but when i run this stub, i couldn't able to get any data from both pipe.
Is this way correct. could u suggest the best way to tap the data.
thanks,
pramod.
|
|
|
|
|
Hello,
I have a COM object which acts as a server to several clients. One of the clients needs to have access to all the methods the COM object provides while all the others only have access to a subset of the available methods.
I have thought of providing two interfaces but how can I be sure one of the less important clients can't "discover" the interface and then the methods it should not have access to?
Thank you for any help you can provide
|
|
|
|
|
Hello,
You can discover client identity during the call.
Get call context's IServerSecurity interface (CoGetCallContext), then impersonate the client IServerSecurity::ImpersonateClient and do the ACL check using the thread token (OpenThreadToken). To make it more managable I'd probably create some kind of "access" file(s), set the desired access rights and use it to do the check at runtime. And if it's ok for the client to use impersonatation level RPC_C_IMP_LEVEL_IMPERSONATE or higher, the Windows can do that check using this file (CreateFile), no need to do it manually.
HTH,
Edward
|
|
|
|
|
Can anyone tell me why there is no onclick() event for HTMLObjectElementEvents2? or how can I catch the onclick() event from C++ code after a mouse click on an Object on a web page? I am using the WebBrowser activeX control.
|
|
|
|
|
Hi,
This is the way I do what you are trying to achieve:
Create an IDispatch object in your C++ code - this is what IE is going to call on a document click event...
class CEvent_OnClick : public IDispatch
{
private:
CWebTest1Dlg* m_pParent;
protected:
ULONG m_cRef;
public:
CEvent_OnClick(CWebTest1Dlg* pParent);
~CEvent_OnClick(void);
STDMETHODIMP QueryInterface(REFIID, void **);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
STDMETHODIMP GetTypeInfoCount(UINT* pctinfo);
STDMETHODIMP GetTypeInfo( UINT iTInfo,
LCID lcid,
ITypeInfo** ppTInfo);
STDMETHODIMP GetIDsOfNames(
REFIID riid,
LPOLESTR *rgszNames,
UINT cNames,
LCID lcid,
DISPID *rgDispId);
STDMETHODIMP Invoke(
DISPID dispIdMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS *pDispParams,
VARIANT *pVarResult,
EXCEPINFO *pExcepInfo,
UINT *puArgErr);
};
Here's the implementation...
CEvent_OnClick::CEvent_OnClick(CWebTest1Dlg* pParent)
{
m_pParent = pParent;
m_cRef = 0;
}
CEvent_OnClick::~CEvent_OnClick(void)
{
ASSERT( m_cRef == 0 );
}
STDMETHODIMP CEvent_OnClick::QueryInterface(REFIID riid, void **ppv)
{
*ppv = NULL;
if (IID_IDispatch == riid)
*ppv = this;
if (*ppv != NULL)
{
((LPUNKNOWN)*ppv)->AddRef();
return NOERROR;
}
return E_NOINTERFACE;
}
STDMETHODIMP_(ULONG) CEvent_OnClick::AddRef(void)
{
return ++m_cRef;
}
STDMETHODIMP_(ULONG) CEvent_OnClick::Release(void)
{
return --m_cRef;
}
STDMETHODIMP CEvent_OnClick::GetTypeInfoCount(UINT* )
{
return E_NOTIMPL;
}
STDMETHODIMP CEvent_OnClick::GetTypeInfo(
UINT ,
LCID ,
ITypeInfo** )
{
return E_NOTIMPL;
}
STDMETHODIMP CEvent_OnClick::GetIDsOfNames(
REFIID riid,
OLECHAR** rgszNames,
UINT cNames,
LCID lcid,
DISPID* rgDispId)
{
return ResultFromScode(DISP_E_UNKNOWNNAME);
}
STDMETHODIMP CEvent_OnClick::Invoke(
DISPID dispIdMember,
REFIID ,
LCID ,
WORD wFlags,
DISPPARAMS* pDispParams,
VARIANT* pVarResult,
EXCEPINFO* ,
UINT* puArgErr)
{
if (m_pParent) m_pParent->OnHTMLClick();
return S_OK;
}
Standard IDispatch stuff really, notice the Invoke above will call a function in your view/dialog that holds the web control.
Now, in your view/dialog we need to hook this in....
First, create the CEvent_OnClick object, eg
CWebTest1Dlg::CWebTest1Dlg(CWnd* pParent )
: CDialog(CWebTest1Dlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_pEvent_OnClick = new CEvent_OnClick(this);
}
Not forgetting, of course, to release it when were done...
CWebTest1Dlg::~CWebTest1Dlg(void)
{
if (m_pEvent_OnClick)
{
m_pEvent_OnClick->Release();
delete m_pEvent_OnClick;
m_pEvent_OnClick = NULL;
}
}
Okay, so now when we receive the DocumentComplete event, we need to inject this handler in...
void CWebTest1Dlg::OnDocumentCompleteExplorer1(LPDISPATCH pDisp, VARIANT FAR* URL)
{
MSHTML::IHTMLDocument2Ptr spDoc(m_ctlWeb1.GetDocument());
if (spDoc)
{
VARIANT v;
v.vt = VT_DISPATCH;
v.pdispVal = m_pEvent_OnClick;
spDoc->put_onclick(v);
}
}
And now all we do is implement the OnClick functionality...here I've done an example that looks at the element that raised the onclick event (activeElement) an determines if it is a hyperlink
void CWebTest1Dlg::OnHTMLClick()
{
MSHTML::IHTMLDocument2Ptr spDoc(m_ctlWeb1.GetDocument());
if (spDoc)
{
MSHTML::IHTMLElementPtr spElem = spDoc->activeElement;
if (spElem)
{
CString strTag = (LPCTSTR)spElem->tagName;
if (strTag == _T("A"))
{
MSHTML::IHTMLAnchorElementPtr pAnchor = spElem;
if (pAnchor)
{
CString strHREF = (LPCTSTR)pAnchor->href;
AfxMessageBox("You clicked a LINK!!! We are off to " + strHREF);
}
}
}
}
}
Hope this helps, any questions I'll be happy to answer
Regards,
Andy
|
|
|
|
|
Thank you very much for your reply.I have been waiting for a response for a long time.But my problem was with OBJECT elements on a web page.Your code will surely work for elements like anchor,link,button etc.On a web page, the OBJECT tag can be used to insert Macromedia Flash elements, applets etc. Macromedia Flash is an activeX control.When I click on a Flash element, I think the click event goes to the ActiveX control which in turn looks for the handler in the Flash element code.I would like to catch this event in my C++ code(which hosts the web browser control).I will try with the code that you gave here.If you have any more input based on what I said, Please let me know. Thank you again.
|
|
|
|
|
Yaa, as I said earlier, the code that you gave does not work for OBJECT elements on the web page. I cannot catch click events on OBJECT elements. Please let me know if you have more input. Thank you.
|
|
|
|
|
Yaa, as I said earlier, the code that you gave does not work for OBJECT elements on the web page. I cannot catch click events on OBJECT elements. Please let me know if you have more input. Thank you.
|
|
|
|
|
You can try by going to www.ultrastar.com. Clicks on this web page cannot be caught by this code.Thank you.
|
|
|
|
|
Hi again,
Right, I have a solution - now I don't profess to being anything but an amateur when it comes to Flash so there may be a better way. But this works so here goes:
Firstly, I created a button in my test flash movie and entered this for the onclick handler:
on (click) {
fscommand("button1","");
}
See the help files for more info on the fscommand() script command
Now, in the HTML page we need the following:
1. Include a hidden INPUT field, e.g.
<OBJECT CLASSID="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" ID="mc" WIDTH=300 HEIGHT=300 CODEBASE="http://active.macromedia.com/flash2/cabs/swflash.cab#version=2,0,0,11">
< PARAM NAME="Movie" VALUE="try1.swf">
<EMBED NAME="mc" SRC="try1.swf" WIDTH=100 HEIGHT=100 PLUGINSPAGE="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash">
</OBJECT>
<input type='hidden' id='idClickFlashEvent' value=''>
2. Add Script handlers in the page - NOTE!!!!!!! the id/name of the OBJECT and EMBED must be the same as the prefix to the _FSCommand !!!!!!:
<SCRIPT LANGUAGE="JavaScript">
<!--
function mc_DoFSCommand(command, args) {
var oFS = document.getElementById("mc");
if (oFS) {
var oHidden = document.getElementById("idClickFlashEvent");
if (oHidden) {
oHidden.value = command;
oHidden.fireEvent("onclick");
}
}
}
</SCRIPT>
<SCRIPT LANGUAGE="VBScript">
<!--
Sub mc_FSCommand(ByVal command, ByVal args)
call mc_DoFSCommand(command, args)
end sub
-->
</SCRIPT>
So when you click in the Flash Player, it runs the ActionScript which then calls out to FSCommand externally, the external object (the web page) has to implement this by creating a function in VBScript (for IE at least) which MUST be named ID of object_FSCommand.
I've then called into the mc_DoFSCommand in JScript (my preferred scripting language) which looks for the hidden input field. Once we've got the object, I do two things:
1. Set the value of it to one of the params passed through (in this case it was just the word "button1"). I've done this as I presume you want to do more than just know a click was performed - so this gives the option to pass through what was clicked.
2. We fire an OnClick event.
Now the INPUT element doesn't have a onclick event as such, but the DOM fires this event through the active element (which in this case is the OBJECT element) - Hey presto the code I gave previously in this thread will now handle that onclick event
If you want to gain access to the value we set above, they you can use the following code in your onclick event handler in C++:
void CWebTest1Dlg::OnHTMLClick()
{
MSHTML::IHTMLDocument2Ptr spDoc(m_ctlWeb1.GetDocument());
if (spDoc)
{
MSHTML::IHTMLElementPtr spElem = spDoc->activeElement;
if (spElem)
{
CString strTag = (LPCTSTR)spElem->tagName;
if (strTag == _T("OBJECT"))
{
MSHTML::IHTMLDocument3Ptr spDoc3 = spDoc;
if (spDoc3)
{
MSHTML::IHTMLElementPtr spElem2 = spDoc3->getElementById(_bstr_t("idClickFlashEvent"));
if (spElem2)
{
MSHTML::IHTMLInputElementPtr spElemHidden = spElem2;
if (spElemHidden)
{
AfxMessageBox(spElemHidden->value);
}
}
}
}
}
}
}
So there we have it. If you need any help or have more questions, I'll be happy to help
BTW, it does not have to be a HIDDEN input field, you could do it with say a BUTTON input field but then you'd have to have the display style attribute set to none to stop it being displayed, it would also influence your C++ onclick handler because now when the JScript fireEvent method is called, it will no longer be the OBJECT that fires the onclick, but the button has this DOES have a valid onclick event (phew). So I thought it easier to use the HIDDEN input element
Cheers,
Andy
|
|
|
|
|
I have a com objet which works fine until i add it to the component services, once i have done this when i call CoCreateInstance i get "class not reistered" can anyone help??
Thanks in advance
|
|
|
|
|
Hi!
I am playing with that piece of code (C#):
Environment.CurrentDirectory=@"C:\Program Files\CDN OPT!MA\";<br />
<br />
CDNBase.ApplicationClass app=new CDNBase.ApplicationClass();<br />
<br />
CDNBase.ILogin l=app.LockApp(255,100,null);<br />
CDNBase.AdoSession sesja=l.CreateSession();<br />
<br />
CDNBase.IAdoCollection collection=(CDNBase.IAdoCollection)sesja.CreateObject("CDN.DokumentyHaMag",null);<br />
<br />
object obj=collection.AddNew(null);
Everything works well right now. All CDNBase.* are declared in interop modules. I need to cast object obj to its interface. so:
<br />
CDNAX.IDokumentHaMag doc=(CDNAX.IDokumentHaMag)obj;<br />
(CDNAX is interop module) here the InvalidCastException comes. The obj exposes this interface - i am sure
I've tried to use InvokeMethod on this object using methods and properties from IDokumentHaMag, and it works well. What am I doing wrong?
|
|
|
|
|
..::Hubert::.. wrote:
The obj exposes this interface - i am sure
But are you 100% sure that CDNAX.IDokumentHaMag is what you think it is?
Run the code using COM Trace[^]. It might provide you with some insight on what's wrong. Also, if you are writing your (or have the source for) COM stuff with ATL, try compiling it with by defining ATL_DEBUG_QI in your stdafx.h. It'll output a debug trace for each QueryInterface calls made on objects in that server.
--
Booohoo!
|
|
|
|
|
Hi
I think, the problem is inside COM - maybe something is missed or incorectly declared, but I have no access to the source .
There are also more types in this namespace: DokumentHaMag (interface derived from IDokumentHaMag) and DokumentHaMagClass (derived from DokumentHaMag interface). When I try to create new object of class DocumentHaMagClass, another interesting exception is thrown: "Query Interface failed for object x" (I don't remember exact text of this exception - I have no access to the compiler right now).
Another interesting thing is creating RCW. I've tried to create RCW based on tlbs and dlls. Doing this in Visual Studio works well, but when I try to use tlbimp on CDNAX tlb, exception is thrown: "An element with the same key already exists in the Hashtable." with some GUID value.
I'm gona try the tool you linked, it may help me to find the problem.
thanks for your reply
h.
|
|
|
|
|
|
Why are you crossposting ancient stuff?
--
Booohoo!
|
|
|
|
|
Hi,
I am trying to return an object from a COM interface method. The method returns a _variant_t. I know how to retrieve int, short, dispatch, etc etc, but how do I simply retrieve an object from the _variant_t?
Thanks,
Ben
|
|
|
|
|
Hi Ben,
Sorry I didn't get your problem, do you want to return an object on a method through a variant or you want to retrieve the object fron the variant?
Can you refrase your question?
Fabian
|
|
|
|
|
Hi Fabian,
The method I am calling returns an object (a NOTESDOCUMENT to be specific). But it is returned as a _variant_t. I need to get it back to a NOTESDOCUMENT before I can perform any operations on it.
Thanks, Ben
|
|
|
|
|
You need to know how the object is encoded into the variant. Usually, a safearray of bytes can be used to encode an object (VT_ARRAY|VT_UI1) - in this case, you could simply extract the bytes and cast it to the relevant object structure.
|
|
|
|
|
Hi Ben,
Ok then, what you have to do to get the object is first to check the vt member of the _variant_t variable and see if it is an VT_UNKNOWN or VT_DISPATCH, according to that you will use the appropriated member to QI and get your object back.
Something like this
<br />
INotesDocument *pNtsDoc; <br />
HRESULT hr;<br />
if(vtReturned.vt & VT_UNKNOWN)<br />
hr = vtReturned.punkVal->QueryInterface(&pNtsDoc);<br />
else (vtReturned.vt & VT_DISPATCH)<br />
hr = vtReturned.pdispVal->QueryInterface(&pNtsDoc);<br />
else<br />
hr = E_INVALIDARG;
Don't forget to release the object once you finished using it.
Regards,
Fabian
|
|
|
|
|