delphic++builderihtmldocument2

Translating Delphi VarSupports to C++ Builder


I am attempting to translate this code from Delphi to C++ Builder:

 procedure HandleStyleSheets(const Document: IDispatch);
var
  Doc: IHTMLDocument2;                      // document object
  StyleSheets: IHTMLStyleSheetsCollection;  // document's style sheets
  SheetIdx: Integer;                        // loops thru style sheets
  OVSheetIdx: OleVariant;                   // index of a style sheet
  StyleSheet: IHTMLStyleSheet;              // reference to a style sheet
  OVStyleSheet: OleVariant;                 // variant ref to style sheet
  RuleIdx: Integer;                         // loops thru style sheet rules
  Style: IHTMLRuleStyle;                    // ref to rule's style
begin
   // Get IHTMLDocument2 interface of document
  if not Supports(Document, IHTMLDocument2, Doc) then
Exit;
  // Loop through all style sheets
  StyleSheets := Doc.styleSheets;
  for SheetIdx := 0 to Pred(StyleSheets.length) do
  begin
   OVSheetIdx := SheetIdx; // sheet index as variant required for next call
   // Get reference to style sheet (comes as variant which we convert to
   // interface reference)
   OVStyleSheet := StyleSheets.item(OVSheetIdx);
 if VarSupports(OVStyleSheet, IHTMLStyleSheet, StyleSheet) then
 begin
   // Loop through all rules within style a sheet
   for RuleIdx := 0 to Pred(StyleSheet.rules.length) do
   begin
     // Get style from a rule and reset required attributes.
     // Note: style is IHTMLRuleStyle, not IHTMLStyle, although many
     // attributes are shared between these interfaces
     Style := StyleSheet.rules.item(RuleIdx).style;
     Style.backgroundImage := '';  // removes any background image
     Style.backgroundColor := '';  // resets background colour to default
     end;
   end;
  end;
end;

Everything went fine until this line:

    if (VarSupports(OVStyleSheet, IID_IHTMLStyleSheet, StyleSheet))

It reports: E2285 Could not find a match for 'VarSupports(OleVariant,_GUID,_di_IHTMLStyleSheet)'

Everything else translated just fine. Can anyone help me with above line?

My translation so far:

DelphiInterface<IHTMLDocument2> Doc;                                        // document object
DelphiInterface<IHTMLStyleSheetsCollection> StyleSheets;                    // document's style sheets
int SheetIdx;                                                               // loops thru style sheets
OleVariant OVSheetIdx;                                                      // index of a style sheet
DelphiInterface<IHTMLStyleSheet> StyleSheet;                                // reference to a style sheet
OleVariant OVStyleSheet;                                                    // variant ref to style sheet
int RuleIdx;                                                                // loops thru style sheet rules
DelphiInterface<IHTMLRuleStyle> Style;                                      // ref to rule's style
DelphiInterface<IHTMLStyleSheetRule> StyleSheetRule;

// Get IHTMLDocument2 interface of document
if (!Supports(EmbeddedWB1->Document, IID_IHTMLDocument2, Doc)) throw Exception("Not supported");

// Loop through all style sheets
StyleSheets = Doc->styleSheets;
for (SheetIdx = 0; SheetIdx < StyleSheets->length; SheetIdx++)
    {
    OVSheetIdx = SheetIdx;                                                  // sheet index as variant required for next call
    // Get reference to style sheet (comes as variant which we convert to  interface reference)
    StyleSheets->item(OVSheetIdx, OVStyleSheet);
    if (VarSupports(OVStyleSheet, IID_IHTMLStyleSheet, StyleSheet))
        {
        // Loop through all rules within style a sheet
        for (RuleIdx = 0; RuleIdx < StyleSheet->rules->length; RuleIdx)
            {
            // Get style from a rule and reset required attributes.
            // Note: style is IHTMLRuleStyle, not IHTMLStyle, although many
            // attributes are shared between these interfaces

            StyleSheet->rules->item(RuleIdx, StyleSheetRule);
            Style = StyleSheetRule->style;

            Style->backgroundImage = L"";  // removes any background image
            Style->backgroundColor = L"";  // resets background colour to default
            }
        }
    }
}

Solution

  • The reason for the compile error is that VarSupports is defined as taking a Variant, and you are passing an OleVariant.

    It looks to me as if the code is trying to assign the OVStyleSheet to the IHTMLStyleSheet interface StyleSheet. In C++ Builder, you should be able to just assign it, as in

    _di_IInterface inter = _di_IInterface(OVStyleSheet);
    StyleSheet = inter;
    

    If that succeeds and StyleSheet is not NULL, you should be able to use StyleSheet. Note that invalid Variant assignments can throw an exception, so you might want to handle that (and assume that the exception also means that the OVStyleSheet does not support the IHTMLStyleSheet interface)

    Also, C++ Builder has an Interface.Supports function that appears to do what VarSupports does, except that VarSupports takes a variant, so Interface.Supports also requires you to obtain the interface from the OleVariant yourself. Probably something like:

    di_IInterface inter = _di_IInterface(OVStyleSheet);
    if (inter->Supports(StyleSheet))
    {
        ShowMessage("StyleSheet has been assigned");
    }
    

    This compiles, but I have not tested it.