|
I want to use the internet explorer inside my application. This works fine:
AtlAxWinInit();
HWND hwndChild=::CreateWindow( "AtlAxWin",
"Shell.Explorer.1",
WS_CHILD|WS_VISIBLE,
0,0,0,0,
hwnd,NULL,
::GetModuleHandle(NULL),
NULL);
IUnknown *pUnk=NULL;
AtlAxGetControl(hwndChild,&pUnk);
CComPtr<IWebBrowser2> spBrowser;
pUnk->QueryInterface(IID_IWebBrowser2,(void**)&spBrowser);
if(spBrowser)
spBrowser->put_Visible(VARIANT_TRUE);
But, I want this to be more abstract. How can I use the interface IDispatch instead.
My attempt to abstract it, returned a DISP_E_UNKNOWNNAME while calling GetIDsOfNames with "Visible" (it IS a member of IWebBrowser2). It has to be something like that...
using: [VISUAL STUDIO 6.0] [WIN98/2]
using: [VISUAL STUDIO 6.0] [WIN98/2]
|
|
|
|
|
It is easily possible. I never tried it on IWebBrowser2 , but it should work on any IDispatch derived interface.
For your GetIDsOfNames , you have to check, if all flags was set properly.
Anyway, there is a helper classes in ATL to doing dispatch calls, if you don't want to program it yourself as a mental excersise.
CComDispatchDriver dispDrv( ipDispInterface );<br />
<br />
dispDrv.PutPropertyByName( bstrName, &variantValue );<br />
dispDrv.Invoke0( bstrName, NULL );
etc...
|
|
|
|
|
I've tried that CComDispatchDriver. <<atlcom.h>> is needed for that.
Now, during compilation, I receive errors from atlcom.h. like these:
VC98\ATL\INCLUDE\atlcom.h(2945) : error C2065: '_Module' : undeclared identifier
VC98\ATL\INCLUDE\atlcom.h(2945) : error C2228: left of '.Lock' must have class/struct/union type
...
My includes are like these:
#pragma comment(lib,"atl.lib")
#include <<atldef.h>>
#include <<atlbase.h>>
#define _ATL_DLL_IMPL
#include <<atliface.h>>
#include <<exdisp.h>>
#include <<atlcom.h>>
What have I done now?
But, frankly, all of the params in my call to getidsfromnames are valid (used it already to control an excel application). IWebBrowser2 doesn't seem to have "Visible", "Quit", ... but I saw it using the typeview tool.
using: [VISUAL STUDIO 6.0] [WIN98/2]
|
|
|
|
|
the _Module refers to the current DLL (module). I no way how to test the include stuff on my compiler now, but generally somewhere in your code is extern CComModule _Module;
and the #include <atlcom.h> must stay behind that definition from the point of view of compiler (this is for VC6, I assume you have)
But the second part is really weird. Fortunatelly I had some project with WebBrowser manipulation, so I fired it up and tested the following code:
CComPtr<IWebBrowser2> m_spBrowser;<br />
CComDispatchDriver drva( m_spBrowser );<br />
_variant_t vtOut;<br />
drva.GetPropertyByName( L"visible", &vtOut );
on the end I had in vtOut vt=VT_BOOL value=VARIANT_TRUE
then at least on my IE6 the property is included = the way you are trying to go is right.
I would suggest to play with the headers a bit, or if it will take more than 10 minutes look to the srcs of the CComDispatchDriver and cut only the parts you need (but duplicating code is really the last chance solution )
|
|
|
|
|
I've included the atlcom.h just above my function and it works now. BIG TNX
Two remarks however...
1: you used L"visible" instead of L"Visible". Aren't those parameters case sensitive?
2: I've found a page on msdn about CComDispatchDriver, but it's not the dispatcher you showed me. It has GetProperty(), PutProperty() and Release(). That's all. So, which one are you talking about? Is it an extended dispatcher or what?
This is the link I've found http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmfc98/html/_atl_ccomdispatchdriver.asp[^]
... and one again, thank you. (but the failure in getIdsFromNames(...) remains very strange )
using: [VISUAL STUDIO 6.0] [WIN98/2]
|
|
|
|
|
1. these should not be case sensitive, at least the IDispatch requires that (else the VB Script will be also case sensitive). In fact developer can change it while implementing the IDispatch in his object, but I don't believe that Microsoft will break it's own rulez.
2. probably this is some older version than my, I am using the ATL7, so might be that this class is updated.
|
|
|
|
|
My euphoria came to quick. It still doesn't work.
the 0x80020006 error is still there...
using: [VISUAL STUDIO 6.0] [WIN98/2]
|
|
|
|
|
I've tried some things, and this is the problem:
this works:
CComPtr<IWebBrowser2> m_spBrowser;<br />
pUnk->QueryInterface(IID_IWebBrowser2,(void**)&m_spBrowser);<br />
m_spBrowser->put_Visible(VARIANT_TRUE);
but this doesn't work:
CComPtr<IWebBrowser2> m_spBrowser;<br />
pUnk->QueryInterface(IID_IWebBrowser2,(void**)&m_spBrowser);<br />
CComDispatchDriver dispDrv(m_spBrowser);<br />
VARIANT x;<br />
VariantInit(&x);<br />
x.vt=VT_BOOL;<br />
x.boolVal=VARIANT_TRUE;<br />
hr=dispDrv.SetPropertyByName(L"Visible",&x);
using: [VISUAL STUDIO 6.0] [WIN98/2]
|
|
|
|
|
Well, honestly I have nearly no idea, where the problem can be. Theoretically there can be problems with defining the LOCALE_USER_DEFAULT in the GetIDsOfNames selecting some other language for dispatch, but I do not believe, that someone uses that in real work , therefore I would assume this parameter is normally ignored.
Also I would check the code on another machine, if there is not a problem with instalation.
Anyway for your reference - in my project, where the get/put visible works, I am inicializing the WebBrowser control by following sequence:
HWND hWT = m_iewnd.Create( m_hWnd, rc, NULL, WS_CHILD + WS_VISIBLE );<br />
<br />
m_iewnd.CreateControl( "file://somewhere.htm" );<br />
<br />
m_iewnd.QueryControl( &m_spBrowser );<br />
m_iewnd.SetExternalDispatch( (IDispatch*)this );<br />
<br />
CComDispatchDriver drv( m_spBrowser );<br />
_variant_t vtOut;<br />
drv.GetPropertyByName( L"visible", &vtOut );<br />
<br />
|
|
|
|
|
Hi, everyone!
My STL tutorial said,
--------
A raw_storage_iterator enables algorithms to
store results into uninitialized memory.
--------
But I do not know what means uninitialized memory.
Who can give me an explanation of what means
uninitialized memory? Here are two examples given
by the tutorial. Please give me the explanation through
the following examples.
Example 1:
--------
vector<int> a (2, 5);
vector<int> b (2, 7);
int *c = allocate((ptrdiff_t) a.size(), (int*)0 );
transform (a.begin(), a.end(), b.begin(),
raw_storage_iterator<int*, int> (c), plus<int>() );
copy (&c[0], &c[2], ostream_iterator<int> (cout, " ") );
--------
Example 2:
--------
template <class T1, class T2>
inline void construct(T1* p, const T2& value) {
new (p) T1(value);
}
int a[10] = {1, 2, 3, 4, 5};
copy (&a[0], &a[5], raw_storage_iterator<int*, int> (&a[5]) );
--------
Thanks in advance,
George
|
|
|
|
|
Uninitialized storage is basically storage that has been allocated but not initialized. Imagine doing a "new [n] char". You have allocated char array, but the contents of the array is uninitialized.
Tim Smith
I'm going to patent thought. I have yet to see any prior art.
|
|
|
|
|
Hi, Tim buddie!
In my first example, I do not understand why the
storage that has been allocated but not initialized.
Can you give me an explanation?
Thanks in advance,
George
|
|
|
|
|
The allocate method is just a fancy malloc. All it does is reserve the space, it doesn't actually do anything to the memory.
It is sort of like building a road. First you must acquire the land to build the road. This is the allocation step. But just because you have acquired the land doesn't mean you have a road. The land is still "uninitialized". It isn't until you actually build the road that you have a fully "initialized" road.
Tim Smith
I'm going to patent thought. I have yet to see any prior art.
|
|
|
|
|
Hi, Tim buddie!
I do not understand why in example 1, (int*)0 is
used as the second parameter of allocate. What is the
meaning of (int*)0 here?
Thanks in advance,
George
|
|
|
|
|
First of all, a remark: the tutorial you're using is grossly outdated, there is no global allocate function, since C++ 98' standard this function is a member of std::allocator .
Now, the second parameter is a hint pointer, optionally used by the allocation engine to improve performance. If no hint is to be provided, the null pointer (0) can be passed. Now, consider the situation:
allocate(1,0); This cannot work because allocate does not know which kind of type you're allocating memory for. The ambiguity can be solved in one of these two forms:
allocate<int>(1,0);
allocate(1,(int*)0);
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
For specialized allocation systems, the address could be used to tell which heap to use as the source of the allocation.
Tim Smith
I'm going to patent thought. I have yet to see any prior art.
|
|
|
|
|
Thanks, Tim buddie!
George
|
|
|
|
|
Thanks, Joaquín buddie!
George
|
|
|
|
|
I'm trying to advise to HTMLElementEvents2
class declaration has the folowing line:
public IDispEventImpl<2,CTBar,&__uuidof(HTMLElementEvents2),&LIBID_MSHTML, 1, 0>
Here's body of OnDocumentComlete:
HRESULT __stdcall CTBar::OnDocumentComplete(IDispatch* pDisp, VARIANT* URL)<br />
{<br />
IDispatch* dispdoc;<br />
IWebBrowser2* wb;<br />
pDisp->QueryInterface(IID_IWebBrowser2,(LPVOID*)&wb);<br />
wb->get_Document(&dispdoc);<br />
dispdoc->QueryInterface(IID_IHTMLDocument2,(LPVOID*)&hDoc);<br />
hDoc->get_body(&hBody);<br />
HRESULT hr=_IDispEventLocator<2, &__uuidof(HTMLElementEvents2)>::DispEventAdvise( hBody, &__uuidof(HTMLElementEvents2));<br />
return S_OK;<br />
}
As a result i'm getting E_NOINTERFACE in hr. Why? Where's error?
|
|
|
|
|
It could be because you're not defining the proper version number in your class declaration. I've had the same problem trying to sink web browser events.
Try setting the MSHTML version to 4.0:
public IDispEventImpl<2,CTBar,&__uuidof(HTMLElementEvents2),&LIBID_MSHTML, 4, 0>
HTH,
scott.
|
|
|
|
|
Tried, no effect!
Any other suggestions?
|
|
|
|
|
Hi, everyone!
Here is a sample of the usage of allocate of STL.
When compiling it with VC6.0, some error occur.
I have added the source codes and related error
messages below.
Source:
--------
#include <vector>
#include <algorithm>
#include <iostream>
#include <functional>
using namespace std;
int main()
{
vector<int> a (2, 5);
vector<int> b (2, 7);
int *c = allocate((ptrdiff_t) a.size(), (int*)0 );
transform ( a.begin(), a.end(), b.begin(),
raw_storage_iterator<int*, int> (c), plus<int>() );
copy (&c[0], &c[2], ostream_iterator<int> (cout, " ") );
return 1;
}
--------
Error messages:
--------
C:\Program Files\Microsoft Visual Studio\MyProjects\testRawIterator\testRawIterator.cpp(12) : error C2065: 'allocate' :
undeclared identifier
C:\Program Files\Microsoft Visual Studio\MyProjects\testRawIterator\testRawIterator.cpp(12) : error C2440: 'initializing' :
cannot convert from 'int' to 'int *'
Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
Error executing cl.exe.
--------
How to resolve the trouble?
Thanks in advance,
George
|
|
|
|
|
alllocate() is supposed to be a member function of your special allocator class, not a global function.
PS. I think you should get this book.
|
|
|
|
|
I'm trying to retrieve the Url of a new window for my BHO... I did what S.Rod. suggested (his code was in C#, I'm using C++/ATL)
case DISPID_NEWWINDOW2:
{
CComPtr<IDispatch> pDisp = NULL;
m_pBlankDlg = new CBlankDlg();
m_pBlankDlg->Create( NULL );
CComPtr<IUnknown> spUnk;
m_pBlankDlg->GetDlgControl( IDC_BROWSER, IID_IWebBrowser2, (void **) &spUnk );
CComQIPtr<IWebBrowser2> spWB = spUnk;
spWB->get_Application( &pDisp );
pDispParams->rgvarg[1].pdispVal = pDisp;
m_pBlankDlg->ShowWindow( SW_SHOW );
}
And in CBlankDlg :
class CBlankDlg :
public CAxDialogImpl<CBlankDlg>,
public IDispEventImpl<IDC_BROWSER,CBlankDlg>
{
...
BEGIN_SINK_MAP(CBlankDlg)
SINK_ENTRY(IDC_BROWSER, 250, BeforeNavigate2Browser)
END_SINK_MAP()
void __stdcall BeforeNavigate2Browser(LPDISPATCH pDisp, VARIANT* URL, VARIANT* Flags, VARIANT* TargetFrameName, VARIANT* PostData, VARIANT* Headers, BOOL* Cancel);
The BeforeNavigate2 event is never triggered... why?
thanks for your help!
---------------
Tired of Spam? Introducing InboxShield® for Microsoft® Outlook®
http://www.edovia.com
|
|
|
|
|
Fixed it!
spWB->get_Application(&pIDispatch);
*(pDispParams->rgvarg[1].ppdispVal) = pIDispatch;
---------------
Tired of Spam? Introducing InboxShield® for Microsoft® Outlook®
http://www.edovia.com
|
|
|
|
|