ATL ActiveX - Using in HTML pages using <PARAM> Tag

Hi Guys!
I'm getting desperate here. I'm writing an ATL component (Thanks to a few previous questions asked here...). Now it is working great, but I want to insert it into Web pages. Using HTML PARAM tag. (Using VBScripts to load the component and use functions works great, but I don't want to use it because I want a generic component that will work under netscape also!).
anyway. Using PARAM I tried two ways. One is to do this

--

<OBJECT ID="MYCONTROL" WIDTH=470 HEIGHT=62
 CLASSID="CLSID:MYCONTROLCLSID">
 <PARAM NAME="Param1" VALUE="23">
 <PARAM NAME="Param2" VALUE="26">
 </OBJECT>

--

and the other way is to use

<PARAM NAME="Line0001" VALUE="SetSomething(0,1,0)">

which didn't work either.

I was then told I need to implement PropertyBagsImpl. I did it, but that didn't work again. THEN I was told I need to override the load function of the PropertyBagsImpl template.
But this is where I'm stuck. How do I do that? the MSDN states the header to be

HRESULT Read( LPCOLESTR pszPropName, VARIANT* pVar, IErrorLog* pErrorLog);

but if I overload it I get an error saying that this declaration differs from the original virtual function by return type or calling convention (or something like that).

What Can I do??? How do I use that LOAD thing, anyway? What are those pointers in the function? Please help...

Thanks!

Ron.
ShadowHawk071998Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

jhanceCommented:
I didn't realze that Netscape Navigator supported ActiveX controls at all.
0
jkrCommented:
>>I didn't realze that Netscape Navigator supported ActiveX
>>controls at all

AFAIK, it doesn't. Does it work with IE?
0
ShadowHawk071998Author Commented:
Hmmm.. Good point actually!
I tell you why I thought that VBScript won't work. It's because We need to put that ActiveX inside HTML Help documents (These are HTML documents run inside IE enviroment, I reckon). So will VBSCript work there? If so, it might work after all... :)

Anyway. I'm sure I used ActiveX Inside Netscape. They have a plug-in that enables you to run those controls (I KNOW that Microsoft Investor uses an ActiveX and I always use Netscape!)

Cheers,

Ron.
0
Cloud Class® Course: C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

ShadowHawk071998Author Commented:
BTW!!!
OOPS!!!
When I said

HRESULT Read( LPCOLESTR pszPropName, VARIANT* pVar,
                                    IErrorLog* pErrorLog);


I meant

HRESULT Load(
  IPropertyBag* pPropBag,  //Pointer to caller's property bag
  IErrorLog* pErrorLog  //Pointer to error log
);

I need to override the Load and not the Read (From what I gather, the container will call the 'Load' of the control, which then will call the 'Read' to interpret the actual properties from that strange pointer he gets...
 
0
Tommy HuiEngineerCommented:
The correct way of handling this situation is to override the IPersistPropertyBagImpl::Load with something like this:

STDMETHODIMP YourClass::Load(LPPROPERTYBAG pPropBag, LPERRORLOG pErrorLog)
{
      CComVariant var;
      HRESULT hr;
      var.vt = VT_I4;
      hr = pPropBag->Read(L"noItems", &var, pErrorLog);
      if (FAILED(hr))
            return hr;
      if (var.vt != VT_I4)
            return E_INVALIDARG;

      long items = var.iVal;
      var.Clear();

      OLECHAR strParam[8];
      for (long idx = 1; idx <= items; idx++)
      {
            swprintf(strParam, L"Item%d", idx);
            hr = pPropBag->Read(strParam, &var, pErrorLog);
            if (FAILED(hr))
                  return hr;
            if (var.vt == VT_BSTR)
                  m_URLs.push_back(CComBSTR(var.bstrVal));
            var.Clear();
      }
      return IPersistPropertyBagImpl<CURLTreeView>::Load(pPropBag, pErrorLog);
}

Note that this was written because IPersistPropertyBagImpl does not know how to deal with arrays, so you will have to write a custom version.

But, even if you do this, if IE is set up with a high security, the control will not see the parameters. You will need to add additional code to get around this security problem. You will need to support IObjectSafety.

To do this, add to your derivation

  public IObjectSafetyImpl<YourClass>,

Add to the COM map

  COM_INTERFACE_ENTRY(IObjectSafety)

Add the method you want to override:

// IObjectSafety
   STDMETHOD(SetInterfaceSafetyOptions)(REFIID riid, DWORD dwSupportedOptions, DWORD dwEnabledOptions);

Add this code to your .cpp module

STDMETHODIMP YourClass::SetInterfaceSafetyOptions(REFIID riid, DWORD dwSupportedOptions, DWORD dwEnabledOptions)
{
   if (riid == IID_IPersistPropertyBag)
   {
      if (dwEnabledOptions != INTERFACESAFE_FOR_UNTRUSTED_DATA)
         return E_FAIL;
      return S_OK;
   }
   return IObjectSafetyImpl<CURLTreeView>::SetInterfaceSafetyOptions(riid, dwSupportedOptions, dwEnabledOptions);
}

That should make it work now.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
ShadowHawk071998Author Commented:
Hi!
This actually worked, although It took me several hours.
The part

hr = pPropBag->Read(L"noItems", &var, pErrorLog);

Didn't work... but I can live without it. I know the parameters.

Just one question, though. At the end you say

IObjectSafetyImpl<CURLTreeView>::SetInterfaceSafetyOptions(riid, dwSupportedOptions, dwEnabledOptions);

Which didn't work for me. Can you please explain and say why I need it? (It works great without it!).

Thanks again!!!

Ron.
0
Tommy HuiEngineerCommented:
Oops. Sorry, but CURLTreeView is my base class from which this code was taken. You don't need to call the base class unless you are deriving from a class that has implements IObjectSafetyImpl.
0
ShadowHawk071998Author Commented:
Oh. Okay. Gotcha.
To finalise things, I guess that

  m_URLs

Is also one of your data members (Some sort of vector thing).

THanks,

Ron.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.