2

am trying to do this in delphi but am not sure about the CTYPE function.

Dim docStyleSheet As mshtml.IHTMLStyleSheet = CType(doc.styleSheets.item(0), mshtml.IHTMLStyleSheet)
Dim docStyleRules As mshtml.HTMLStyleSheetRulesCollection = CType(docStyleSheet.rules, mshtml.HTMLStyleSheetRulesCollection)

why we cant simply do this in delphi:

stylesheet :=  document.styleSheets.item(0) As IHTMLStyleSheet;

the full code can be found at this link https://stackoverflow.com/a/2996819

Tlama, David... thanx for the correction yes its a vb code.

Community
  • 1
  • 1
Radament
  • 112
  • 6
  • Er, that is VB code not C – David Heffernan Jun 20 '13 at 11:56
  • @Tlama , my problem is that instead of creating a new stylesheet, i want to modify the rules of an existing one, which is stylesheet(0), but stylesheet is an IHTMLStylesheet and document.stylesheets.item(0) is an olevariant. – Radament Jun 20 '13 at 12:03
  • when writing something like "why we cant simply do this in delphi" it better to tell why delphi does not accept it. It did gave you some error, compile-time or runtime, so why making this message a secret ? Same goes for "and document.stylesheets.item(0) is an olevariant" - this information would better be in question rather than burried deep within comments. Read ESR's essay "How to ask smart questions" please. And then with this last remark of yours you just answered your own question: you cannot use AS here because AS operator applies to classes and interfaces, not to variants. – Arioch 'The Jun 20 '13 at 12:04

1 Answers1

3

AS. the answer was extended few times, as more and more info was uncovered turning the question from "what is CType function?" to "How to convert OleVariant to a required Interface type?". Thus the answer gradually covers all those topics.

So, you met unknown function in Microsoft Visual Basic code. What is one to do, when he meets something yet unknown? Go Google.

Google.com with text CType MSDN gives us this link in its top results: http://msdn.microsoft.com/en-us/library/vstudio/4x2877xb.aspx

Returns the result of explicitly converting an expression to a specified data type, object, structure, class, or interface. If no conversion is defined from expression to typename (for example, from Integer to Date), Visual Basic displays a compile-time error message.

So we have to reproduce typecast in Delphi, preferably compile-type type-cast, if possible.

Google.com with text typecast docwiki gives us this link in its top results:

Which in turn gives us one more link referenced in the text:

So you have two syntaxes to try. One you tried and ruled out - the one with AS operator. Then try another, direct typecast syntax.

stylesheet :=  IHTMLStyleSheet( document.styleSheets.item(0) );

Sometimes if above fails it also helps doing double typecast, Variant -> IUnknown -> certain interface, but in many cases that is but redundant version of the upper code.

stylesheet :=  IHTMLStyleSheet( IInterface( document.styleSheets.item(0) ) );

Well, now that it was told that the source expression datatype is OleVariant we can read documentation with more precise aim, about Variant datatype conversions (OleVariant is little different from Variant in modern Delphi):

  • AS operator is applicable to classes, objects and interfaces. It is not applicable to Variant expressions. This answers the original "why we cannot..." question.
  • Documentation on Variant type suggests converting it using direct typecast syntax.

.

stylesheet :=  IInterface( document.styleSheets.item(0) ) as IHTMLStyleSheet;

If wished, you can even use (over?)defensive programming using http://docwiki.embarcadero.com/Libraries/XE2/en/System.Variants.VarType to check that you got varUnknown or varDispatch before attempting at getting IUnknown out of the returned value.

PS. The question seems as a duplicate now.

Community
  • 1
  • 1
Arioch 'The
  • 15,799
  • 35
  • 62
  • thats right, the real question is "How to convert OleVariant to a required Interface type?". , and yes i should Read ESR's essay "How to ask smart questions", thank you, that answer works perfect, and i did learned alot from it. – Radament Jun 20 '13 at 12:35
  • 1
    you really should. We have a proverb "Good question is half an answer" and i believe most nations do. As you start making good question it is rather often that the question gets solved in midway. – Arioch 'The Jun 20 '13 at 12:37
  • 1
    Imagine what happens if the document won't have any stylesheet, when the `IHTMLStyleSheetRulesCollection.item(0)` won't have anything to return. – TLama Jun 20 '13 at 12:44
  • 1
    @Tlama , i use this to solve that problem document.styleSheets.length; if its < 1 then there is no stylesheets in the document. – Radament Jun 20 '13 at 12:49
  • @TLama Feeling too lazy too google or try. Perhaps you know a geist of Microsoft patterns or had 1st hand experience ? Would it return nil or throw OLE exception ? – Arioch 'The Jun 20 '13 at 20:12
  • @user2504958 use back-ticks to make code (or identifiers) easier readable. When you enter your comments, there is a "help" link down to the right, it lists tips like that. – Arioch 'The Jun 20 '13 at 20:16