|
Home > Software > Internet Explorer IE5 Programming Components Browser Control > How to open Web...
Post 1 of 1
Topic 259 of 260
How to open Web Browser from Outlook Addin
by "devom" <devom@rediffmail.com> Jan 14, 2005 at 02:30 AM
I had created an Outlook Addin using VC++ ATL.There I had created button on
Outlook Toolbar.I
want to open a Web Browser window on clicking on the button.The web
Browser Window could not have any
Buttons,Toolbars etc.eg.I just want to open www.rediff.com in the window
upon initialisation.Next, I want to capture
click events on the rediff page.(Eg. on what picture in the html page did
the user clicked)
How should .I move forward .Plz explain with steps
Thanks in advance
|
|
|
|
|
Hi
You can host the 'Shell.Explorer' ActiveX control - it's in the shdocvw.dll server in ...\windows\system32.
With ATL, you'll be able to use CAxWindow (or derived) and either use the IWebBrowser(2) from the Platform SDK's header files or simply #import shdocvw.dll.
IWebBrowser(2) provides a method to browse, eg. to www.rediff.com, called Navigate(2).
Once you've loaded the page, you can access the HTML Document from the Document property (returns IDispatch interface).
The Doc also implements IHTMLDocument/IHTMLDOMNode(2), which you can find in mshtml.tlb (using #import) or the Platform SDK.
From the IHTMLxxx API you can find the elements in the page itself.
A word of caution though; there is no real way to tell when a page has loaded as the events such as, BeforeNavigate(2), OnDocumentComplete, etc only notifies of progress for individual document elements, and since most pages contain many such elements, you have to 'look out' for the bits you're concerned with - and then there's always the case where the server isn't running (etc) which you'll also want to handle properly.
HTH and good luck
Martin
|
|
|
|
|
This one is for IDL gurus!!
Given a structure similar to the following, defined in IDL
typedef struct
{
long something;
[string]wchar_t * someotherthing;
[string]wchar_t * yetanotherthing;
}SOMESTRUCT
I need my component to return a collection of SOMESTRUCT structures. (The exact number of SOMESTRUCT structures is not known until runtime)
There are two options here
1. Use an open(or whatever) array of SOMESTRUCT structures. Can someone give me the IDL for this?
2. Define IEnumXXX for the SOMESTRUCT structure. Is there some sample code somewhere?
thanks
Man Learns from History that he never learns from History
|
|
|
|
|
Go for the first alternative. The syntax is the same as for basic types IIRC.
--
Komm tu mir langsam weh, leg mir die Ketten an
und zieh die Knoten fest, damit ich lachen kann
I blog too now[^]
|
|
|
|
|
Hi!
It's possible to mark a CoClass as "appobject". This enables VBScript clients to use methods in this object globally. However, I'm not able to use these methods from a C++ client.
The following example tries to invoke the "CentimetersToPoints" method, which is global in the Word-typelib. Just create a Win32 console app with ATL support and paste it in...
What am I doing wrong?
Sincerely
-Broholm
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
#include "stdafx.h"<br />
<br />
#define hrCheck(hr) if(FAILED(##hr)) { return -1;};<br />
<br />
int _tmain(int argc, _TCHAR* argv[])<br />
{<br />
::CoInitialize(NULL);<br />
{
CComBSTR ProgId("Word.Application");<br />
HRESULT hr; <br />
<br />
CComPtr<IUnknown> pUnk;<br />
hr = pUnk.CoCreateInstance(ProgId,NULL,CLSCTX_SERVER);<br />
hrCheck(hr);<br />
<br />
CComQIPtr<IDispatch> pDisp;<br />
hr = pUnk.QueryInterface(&pDisp);<br />
hrCheck(hr);<br />
<br />
DISPID dispIdClass;<br />
CComBSTR MethodName("CentimetersToPoints");<br />
hr = pDisp->GetIDsOfNames(IID_NULL,&MethodName,1,LOCALE_USER_DEFAULT,&dispIdClass);<br />
hrCheck(hr);<br />
<br />
CComVariant vArg(0.5);<br />
hr = vArg.ChangeType(VT_R4);
hrCheck(hr);<br />
DISPID dispidNamedArgs = -1;<br />
<br />
DISPPARAMS dpArgs;<br />
dpArgs.cArgs = 1;<br />
dpArgs.cNamedArgs = 0;<br />
dpArgs.rgvarg = &vArg;<br />
dpArgs.rgdispidNamedArgs = &dispidNamedArgs;<br />
<br />
EXCEPINFO e;<br />
CComVariant vResult;<br />
UINT puArgErr(0);<br />
<br />
hr = pDisp->Invoke(dispIdClass,IID_NULL,LOCALE_USER_DEFAULT,DISPATCH_METHOD,&dpArgs,&vResult,&e,&puArgErr);
if(FAILED(hr))<br />
std::cout << "Invoke failed" << std::endl;<br />
CComPtr<ITypeInfo> pTI;<br />
hr = pDisp->GetTypeInfo(0,LOCALE_USER_DEFAULT,&pTI);<br />
CComQIPtr<ITypeLib> pTypeLib;<br />
UINT TLindex(0);<br />
hr = pTI->GetContainingTypeLib(&pTypeLib,&TLindex);<br />
hrCheck(hr);<br />
<br />
UINT iTypeInfoCount = pTypeLib->GetTypeInfoCount(); <br />
for(UINT i(0); i < iTypeInfoCount; ++i) <br />
{<br />
TYPEKIND typeKind; <br />
hr = pTypeLib->GetTypeInfoType(i, &typeKind);<br />
hrCheck(hr);<br />
if(typeKind != TKIND_COCLASS) <br />
continue;<br />
<br />
CComQIPtr<ITypeInfo> pAOTypeInfo;<br />
hr = pTypeLib->GetTypeInfo(i, &pAOTypeInfo);<br />
hrCheck(hr);<br />
<br />
TYPEATTR* pAOTypeAttr;<br />
hr = pAOTypeInfo->GetTypeAttr(&pAOTypeAttr);<br />
hrCheck(hr);<br />
if((pAOTypeAttr->wTypeFlags & TYPEFLAG_FAPPOBJECT) != TYPEFLAG_FAPPOBJECT)<br />
{<br />
pAOTypeInfo->ReleaseTypeAttr(pAOTypeAttr);<br />
continue;<br />
};<br />
<br />
CComBSTR name;<br />
hr = pTypeLib->GetDocumentation(i, &name, 0, 0, 0);<br />
hrCheck(hr);<br />
<br />
for(int j(0); j < pAOTypeAttr->cImplTypes; ++j)<br />
{<br />
CComQIPtr<ITypeInfo> pAOTypeInfoImpl;<br />
HREFTYPE hRefType;<br />
hr = pAOTypeInfo->GetRefTypeOfImplType(j,&hRefType);<br />
hrCheck(hr);<br />
hr = pAOTypeInfo->GetRefTypeInfo(hRefType,&pAOTypeInfoImpl);<br />
hrCheck(hr);<br />
TYPEATTR* pAOTypeAttrImpl;<br />
hr = pAOTypeInfoImpl->GetTypeAttr(&pAOTypeAttrImpl);<br />
hrCheck(hr);<br />
<br />
CComPtr<IDispatch> pAODisp;<br />
hr = pAOTypeInfo->CreateInstance(NULL,pAOTypeAttrImpl->guid,(void**)&pAODisp);<br />
pAOTypeInfoImpl->ReleaseTypeAttr(pAOTypeAttrImpl);<br />
hrCheck(hr);<br />
<br />
hr = pAODisp->GetIDsOfNames(IID_NULL,&MethodName,1,LOCALE_USER_DEFAULT,&dispIdClass);<br />
hrCheck(hr);<br />
hr = pAODisp->Invoke(dispIdClass,IID_NULL,LOCALE_USER_DEFAULT,DISPATCH_METHOD,&dpArgs,&vResult,&e,&puArgErr);<br />
hrCheck(hr);
<br />
};<br />
pAOTypeInfo->ReleaseTypeAttr(pAOTypeAttr);<br />
};<br />
};<br />
::CoUninitialize();<br />
return 0;<br />
}<br />
|
|
|
|
|
I think that your problem doesn't associate with [appobject] keyword of MIDL. Because the CentimetersToPoints is a member of _Application interface of Application coclass which doesn't have [appobject] tag.
Try to make the initialization of the "EXCEPINFO e". May be it helps you.
With best wishes,
Vita
|
|
|
|
|
I've already tried that, with no luck... It's just that I'm able to create, write and print Word documents, and use the SAPI interface to make the computer speak with this code already. But a simple function call to convert a number fails?
|
|
|
|
|
Unfortunately, I don't have the Word installed now. But your code should be work.
Try also change the dwClsContext parameter of CoCreateInstance to:
pUnk.CoCreateInstance(ProgId,NULL,CLSCTX_LOCAL_SERVER)
With best wishes,
Vita
|
|
|
|
|
I found the error:
Apparently it's neccesary to specify DISPATCH_METHOD|DISPATCH_PROPERTYGET in the Invoke-statement. Neither DISPATCH_METHOD or DISPATCH_PROPERTYGET alone will do the trick...
But thx for replying anyway...
Sincerely
Broholm
|
|
|
|
|
Hi
Would you say it is better to learn COM using straight COM or use ATL to do the donkey work? I appreciate this could be horses for courses, but for example, if you needed a component that connected to a server to retrieve docs / images etc and serve them to the client, no GUI, would straight COM be just as good?
The main reason for asking is I am struggling to understand the basics of ATL but the straight COM seems easier, i.e. derive from IDespatch, derive from IUnknown, whereas ATL does all that for you and I can't really work out what it happening.
Also WTL fits nicely with ATL so a GUI COM would be better built using ATL?
I suppose it's like MFC, hides all the Window Procs from you etc...I started out using the Windows SDK so I know what's happening in the background and could appreciate what MFC was doing under the covers.
Just rambling really.....
Regards
Angel
*********************************************
The sooner you fall behind, the longer you have to catch up.
|
|
|
|
|
Hi
You would do good to at least create a basic DLL (inproc) server using just straight C++, to understand the principles. From there on, move to ATL as it's the best framework for COM with C++ available today (.. says he, bracing for the flack..).
It is the same as doing a basic Win32-only app to understand MFC better.
When I looked at it last, MFC was much richer than WTL for GUI work, but WTL certainly complements ATL well if you're aiming to build light-weight ATL COM servers with some basic GUI bits, such as a dialog or 2.
Before VC7, MFC used to be imported into ATL projects only to use the utility classes, such as CString, but with ATL 7 that's not necessary anymore as these are now better de-coupled.
HTH
Martin
|
|
|
|
|
I started with ATL. I did however read a lot of books, and my background in C++ is quite strong, so I didn't have any problems grasping the core concepts of COM.
What was tricky at first were concepts such as apartments, and other concepts which were more in the language neutral aspect of COM.
--
Komm tu mir langsam weh, leg mir die Ketten an
und zieh die Knoten fest, damit ich lachen kann
I blog too now[^]
|
|
|
|
|
hello friends,
i just want to know wheather their is any api in .Net,com etc for geting the open with dialog,as like we get in windows when we try to open any of the files with no extentions.
if there is any other implementation other than reading from the registry ,plz let me know.
regards
Deepak
deepak
|
|
|
|
|
In Visual C++, you can call release on a COM object and make sure the
library gets freed by calling CoFreeAllLibraries. I need to do
something similar in Visual Basic. I need to be able to load the
library I need dynamically when I need to use it and release the dll
when I'm done using the object. Does anyone know how this is done in
Visual Basic?
Thanks.
|
|
|
|
|
Hi
I believe you can set the VB object reference to Nothing (or it might be Null) - that'll be equivalent to calling Release.
As for CoFreeAllLibraries, you can import that as a standard Win32 API call, in case VB doesn't supply a friendly version.
HTH
Martin
|
|
|
|
|
You realize that CoFreeAllLibraries unloads _all_ dlls loaded by the COM runtime whether they are in use or not?
Quote from MSDN:
Frees all the DLLs that have been loaded with the CoLoadLibrary function (called internally by CoGetClassObject), regardless of whether they are currently in use.
This is a rather drastic thing to do and it can certainly leads to access violations and other undefined behavior.
Perhaps you intended CoFreeUnusedLibraries? I'm no VB expert but this should do the trick:
Private Declare Sub CoFreeUnusedLibraries Lib "ole32" ()
Now you should be able to call CoFreeUnusedLibraries from VB
|
|
|
|
|
just a note - CoFreeUnusedLibraries takes about 10 minutes before actually releasing the dll. That got me some time ago
|
|
|
|
|
Thanks for the replies! I got it working with CoFreeUnusedLibraries after setting th e object to Nothing. Yes, you are right that it normally takes 10 minutes for the library to actually get unloaded. There are work arounds to this though: http://support.microsoft.com/kb/q301357/
I reload and unload the dll multiple times throughout the life of the program, and to do this more often than 10 minute intervals, I have a function to load the object, a function to set the object to Nothing for when I'm not using it, and a timer that calls CoFreeUnusedLibraries ever minute or so.
|
|
|
|
|
|
Yes moron, the boards work!
--
I got nasty habits. I take tea at three.
-- Mick Jagger
I blog too now[^]
|
|
|
|
|
you got a good sense of humour
modified 21-Apr-21 21:01pm.
|
|
|
|
|
Thanks for recognizing it :->
--
Komm tu mir langsam weh, leg mir die Ketten an
und zieh die Knoten fest, damit ich lachen kann
I blog too now[^]
|
|
|
|
|
Hi friends i was wondering if any of u would know the answer to these questions :
1. When deploying new versions of COM objects in Visual Basic, or Visual C++, often times IIS will lock the object on the application server. How do you free the object so that a new version of a component can be deployed?
A. Restart the web publishing service on the IIS server
B. Reboot your desktop
C. Recompile the COM object using binary compatibility
D. Shut down the package
E. None of the above
2. After deploying a new version of a custom VB COM object, if you see the message "Server.CreateObject Failed" which of theses choices is most likely the problem?
A. IIS is locking the object
B. The Visual Basic runtime library is locking the object and IIS cannot instantiate the object
C. Binary compatibility is not set on the server
D. The component was recompiled without binary compatibility
E. B & D
F. None of the above
|
|
|
|
|
|
I have been trying to receive event from a COM object in C++ with no success, I think I have no found the correct way to go about it (I have never used COM before), here's what I've done:
I have created a new project as an 'ATL Project', I then used the 'Implement Interface' function to add all parts of the COM object I need which generated a ton of code but in the code was the event I am trying to receive.
Firstly, am I going about this the right way now? And if I am, how do I use this new object in my application instead of the existing object?
I'm sorry if this is a stupid question but I have read about COM and searched the net etc but I just can't figure it out, I'm having real trouble understanding COM, any help is greatly appreciated.
Thanks in advance,
Dan.
|
|
|
|
|