Re: [GD-Windows] Extending Internet Explorer DOM when hosting
Brought to you by:
vexxed72
|
From: Rich <leg...@xm...> - 2002-01-16 04:18:27
|
In article <HEE...@mi...>,
"Jon Watte" <hp...@mi...> writes:
> Thanks; this is the second recommendation I get for this method.
By "this method", I assume you mean making a simple COM object you can
call from HTML script? For an example of that, see the source for
izfree <http://izfree.sourceforge.net/>. It contains a simple COM
object written in ATL that exposes a dispinterface that can be
accessed from script in a web page. The object wraps the API
function ::CoCreateGuid, so that scripts can generate GUIDs anytime
they want in a web page.
Here's a step-by-step I posted to usenet:
Date: Thu Dec 20 11:35:47 MST 2001
Groups: microsoft.public.scripting.vbscript
From: leg...@ma... (Rich)
Reply-To: (Rich) leg...@ma...
Subject: Re: API Calls from VBScript
Refs: <339...@po...> <ez#p2ZUiBHA.1
976@tkmsftngp05>
---------
[Please do not mail me a copy of your followup]
"Christian METZ" <cm...@dy...> spake the secret code
<ez#p2ZUiBHA.1976@tkmsftngp05> thusly:
>Has Michael Harris say it, not directly from VBS, but you can use OCX in a
>VBS. So if you need to make an API call you need a OCX to do it.
Its easier than that. You only need to make a COM object that is
callable from scripting languages.
Scripting languages use late binding, also known as dispinterfaces.
The only requirement on your COM object is that it provide a default
dispinterface for the scripting environment. This is very easy to do
with Visual C++ and the ATL app wizard. Here's the recipe:
1. Select File / New...
2. Select the Projects tab
3. Select ATL COM AppWizard, enter a name and location for the
project, and click OK.
4. Select Server Type DLL and click Finish
5. In the Workspace window, select the Class View tab
6. Select New ATL Object... from the context menu for your project's
classes
7. Select Simple Object from the Objects category in the ATL Object
Wizard and click Next.
8. Select the Attributes tab, check "Support ISupportErrorInfo" and leave
the rest at the default values. ISupportErrorInfo allows your object
to communicate more useful information about errors back to the
calling script. (Its what fills in the Err object in VBScript.)
9. Select the Names tab and enter a short name for your object; the Object
Wizard automatically fills in the rest of the fields which you can edit
if you don't like what it created.
10. Click OK
11. Expand your project's classes in the class view to display the new
interface you just created (it will have a sideways lollipop displayed
next to the name which will begin with an 'I')
12. Select Add Method... or Add Property... from the context menu for
the newly created interface. I found it best to add all the properties
and methods you need before doing anything else. As you add methods
and properties to the interface definition, the Object Wizard adds
stub code to your C++ class that implements the corresponding methods
and/or properties.
13. Expand the C++ class that implements your interface in the Class
View. You should see your new interface listed underneath your
implementation class. Expand the interface to show its methods and
properties. You can double-click on any of the methods and property
functions and the corresponding code is loaded in the editor window.
14. Edit the boiler plate code to provide the necessary
implementation.
15. Debug your implementation
The compile project for the code provided by the ATL COM AppWizard
automatically registers the COM object for use after a successful
compile. After step 12 is completed above you should be able to
compile your object that does nothing and have it registered. You can
then test it by writing a VBScript to create your object. The
object's ProgId was entered in the Names tab of the Object Wizard, but
you can also find it by opening the object's .rgs file in the editor.
The .rgs file is in the Resources folder in the File View of the
Workspace window.
I've done this sort of thing several times, and it works great. For
instance, I've written an HTA using VBScript and I needed to generate
GUIDs. At first I was just running guidgen from the Platform SDK to
generate new GUIDs. But lots of people might not have the Platform
SDK installed or they might not have guidgen from Visual C++. So I
wrote a small object that called ::CoCreateGuid and then
::StringFromGUID2 to return the GUID as a BSTR. Here's the entire
implementation:
// Generator.cpp : Implementation of CGenerator
#include "stdafx.h"
#include "Guidgen.h"
#include "Generator.h"
/////////////////////////////////////////////////////////////////////////////
// CGenerator
#define NUM_OF(ary_) (sizeof(ary_)/sizeof((ary_)[0]))
STDMETHODIMP CGenerator::Generate(BSTR *guid)
{
if (!guid)
{
return E_POINTER;
}
GUID g = { 0 };
const HRESULT hr = ::CoCreateGuid(&g);
if (FAILED(hr))
{
return hr;
}
OLECHAR buffer[80];
if (!::StringFromGUID2(g, buffer, NUM_OF(buffer)))
{
return E_INVALIDARG;
}
*guid = CComBSTR(buffer).Detach();
return S_OK;
}
Its slightly ugly due to the COM semantics of HRESULTs and BSTRs, but
the idea is pretty straightforward.
So using that object, I was able to eliminate the dependency my HTA
had for guidgen, and as a side effect it works faster too since the
generator code is attached to my process and I don't have to run
guidgen into a file and parse the resulting file.
--
Ask me about my upcoming book on Direct3D from Addison-Wesley!
Direct3D Book http://www.xmission.com/~legalize/book/
Don't Support Spammers! Boycott Fractal Painter 7!
http://www.xmission.com/~legalize/spammers.html
|