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
}
}
}
}
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.