Announcement

Collapse
No announcement yet.

Variant as UDT Problem

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Variant as UDT Problem

    Win XP(Prof) SP3 - PBWin 9.01.

    I have a problem converting VB6 to PBWin.

    Original VB6 Code:
    Code:
    Dim tRange as udtTextRange
    ...
    ...
    Set oDoc = mySession.ActiveDoc
    tRange = oDoc.TextSelection
    My Conversion:
    Code:
    GLOBAL tRange AS udtTextRange
    ...
    GLOBAL vtemp as VARIANT
    ...
    OBJECT GET mySession.ActiveDoc TO myDocument
    
    OBJECT GET myDocument.TextSelection TO tRange    ' This produces a "syntax error"
    
    OBJECT GET myDocument.TextSelection TO vtemp     'This compiles
    i = VARIANTVT(vtemp)
    MSGBOX "textselection_variant = " & HEX$(i)
    The .inc file :
    Code:
    TYPE udtTextRange
        beginrange AS udtTextLoc
        endrange AS udtTextLoc
    END TYPE
    ...
    ...
    Property Get TextSelection <297> () As Variant
    VARIANTVT(vtemp) returns (From the Help file):
    36 Not Listed in Help
    Whereas I would expect :
    29 %VT_USERDEFINED User Defined Type

    Is my conversion wrong?

    Bob
    Last edited by Robert Wallace; 3 Sep 2009, 03:26 AM. Reason: Corrected Description "36"

  • #2
    >Dim tRange as udtTextRange
    >OBJECT GET myDocument.TextSelection TO tRange

    If I've been reading carefully, when you use the dispatch interface via the "OBJECT GET" statement, that always returns a VARIANT, and it's only the "direct" interface which can return a UDT from a property call.
    Michael Mattias
    Tal Systems (retired)
    Port Washington WI USA
    [email protected]
    http://www.talsystems.com

    Comment


    • #3
      MCM - Many thanks for the hint (if I remember the time zones you must be working all night!!)

      This leaves me between the devil and the deep blue sea - from my previous posts you will see that the first half of my program didn't work if I used a "Direct" interface

      Comment


      • #4
        So get the variant... then move the variant to a UDT.

        If you can't simply....
        Code:
          OBJECT GET   .... to vVar
          UdtVar         = vVar
        .. then you can
        Code:
          LOCAL pVar AS VARIANTAPI  PTR 
          OBJECT GET ... to vVar 
          pVar = VARPTR (vVar)
        .. and move the data to UDTVar from the detail provided in the VARIANTAPI structure.
        Michael Mattias
        Tal Systems (retired)
        Port Washington WI USA
        [email protected]
        http://www.talsystems.com

        Comment


        • #5
          Code:
            OBJECT GET   .... to vVar
            UdtVar         = vVar
          This produces a "Data Type Mismatch"
          Code:
            LOCAL pVar AS VARIANTAPI  PTR 
            OBJECT GET ... to vVar 
            pVar = VARPTR (vVar)
          .. and move the data to UDTVar from the detail provided in the VARIANTAPI structure.
          Haven't a clue how to do the above
          (However as vVar isn't returning a UDT as it should then how would I know how to interpret any data even if I knew how to program it.).

          Back to VB6 again (inspite of criticisms - for an old program it handles very complex COM beautifully and, infact, with little or no speed difference - only the program size is different)

          -----------------------------------------------
          Added Later.

          Finally understood what MCM was getting at but I still get a VARIANT Type of 36 which seems to be illegal

          Bob
          Last edited by Robert Wallace; 1 Sep 2009, 12:17 PM. Reason: Understood MCM's code

          Comment


          • #6
            TYPE "36?" That' s not what I get.... I get BSTR ...
            Code:
            TYPE FOO
                 X AS LONG
                 Y AS LONG
            END TYPE
            
            
            FUNCTION PBMAIN() AS LONG
                 
              LOCAL v AS VARIANT, F AS FOO, S AS STRING
              
                 F.X =  1234
                 F.Y =  5678
                  
                 LET v  =F
                 STDOUT "Variant type =" &  FORMAT$(VARIANTVT(v))  ' returns 8 (bSTR)
                 S = VARIANT$(v)
                 
                 TYPE SET F= S
                 STDOUT USING$("X #  Y #", f.x, f.y)
                 WAITKEY$
            
            END FUNCTION
            
            ==> 
            
            Variant type =8
            X 1234  Y 5678
            MCM
            Last edited by Michael Mattias; 1 Sep 2009, 03:59 PM. Reason: Forgot to include the def of TYPE Foo
            Michael Mattias
            Tal Systems (retired)
            Port Washington WI USA
            [email protected]
            http://www.talsystems.com

            Comment


            • #7
              ' returns 8 (bSTR)
              The last thing I would expect it to return - according to the documentation:

              8 %VT_BSTR Dynamic String
              I would have expected:

              29 %VT_USERDEFINED User Defined Type
              Bob

              Comment


              • #8
                I'm still trying to figure out which types can be combined to make a '36'

                Maybe 36 (decimal) is something new.

                That, or the whole idea of using the Component Object Model is to get away from returning records as UDTs... i.e., each member of a UDT is supposed to be a property.

                MCM
                Michael Mattias
                Tal Systems (retired)
                Port Washington WI USA
                [email protected]
                http://www.talsystems.com

                Comment


                • #9
                  Maybe 36 (decimal) is something new.
                  No the tlb dates back to at least 2006.

                  I am beginning to suspect that it may be a VB6 special and that I will never be able to rewrite in PBWin.

                  The VB6 code is deceptively simple:
                  Code:
                  tRange = oDoc.TextSelection
                  but "TextSelection" returns a Variant and tRange is two UDT's within a UDT - I can't image how VB6 extracts the data from the Variant and puts it into a UDT:confused2:

                  Unfortunately that single statement is the heart of the program (it defines the beginning and end of a selected text and the current position within a line of text) which enables all the other text handling procedures.

                  Bob

                  P.S. I have just read that VB6 will work within Windows 7 for the lifetime of that operating system (I suspect for ever!!)

                  Comment


                  • #10
                    I'm guessing that VT_VOID just specifies that the data is a blob-- some miscellaneous collection of data. VB is probably just stuffing the UDT with the contents of the variant, up to the size of the UDT. You can readily duplicate that approach by something along the lines of:

                    sInfo$ = PEEK$(VARPTR(vTemp), SIZEOF(vTemp))
                    sInfo$ = MID$(sInfo$, 9) ' skip to variant data
                    sInfo$ = LEFT$(sInfo$, SIZEOF(tRange)) ' make sure it's not too long
                    POKE$ VARPTR(tRange), sInfo$

                    Comment


                    • #11
                      > that VT_VOID

                      But VT_VOID is not 36 decimal.

                      What the heck is VT_TYPE 36 decimal?
                      Michael Mattias
                      Tal Systems (retired)
                      Port Washington WI USA
                      [email protected]
                      http://www.talsystems.com

                      Comment


                      • #12
                        What the heck is VT_TYPE 36 decimal?
                        It is %VT_RECORD, an UDT in C++ lingo.

                        Please, see my post and Dominic Mitchell's post in this thread:

                        http://www.powerbasic.com/support/pb...hlight=brecord
                        Forum: http://www.jose.it-berater.org/smfforum/index.php

                        Comment


                        • #13
                          You can find information about the IRecordInfo interface here:
                          http://msdn.microsoft.com/en-us/library/ms221039.aspx
                          Forum: http://www.jose.it-berater.org/smfforum/index.php

                          Comment


                          • #14
                            Excellent description and support code for '36' in linked post!!!

                            Found this in SDK..
                            IRecordInfo Interface
                            IRecordInfo describes the structure of a particular UDT. You can use IRecordInfo any time you need to access the description of UDTs contained in type libraries. IRecordInfo can be reused as needed; there can be many instances of the UDT for a single IRecordInfo pointer.
                            There's a whole lot more in the SDK article.

                            That's from my on-disk SDK... while this big test run is executing, let me see if I can find a link to the on-line version at MSDN....yup, here 'tis...

                            http://msdn.microsoft.com/en-us/library/ms221039.aspx

                            MCM
                            Michael Mattias
                            Tal Systems (retired)
                            Port Washington WI USA
                            [email protected]
                            http://www.talsystems.com

                            Comment


                            • #15
                              A big Thank You

                              Many thanks for all your help

                              Just for the record the following is the final working code

                              Code:
                              FUNCTION GetPosn (StartPosn AS LONG, EndPosn AS LONG, read_write AS LONG) AS LONG
                                LOCAL tRange AS udtTextRange PTR
                                LOCAL pv AS VARIANT_STRUCT PTR
                              
                                OBJECT GET myDocument.TextSelection TO vtemp
                                pv = VARPTR(vtemp)
                                tRange = @pv.br.pvRecord
                                IF read_write = 0 THEN                       'Read
                                  startposn = @tRange.beginrange.offset
                                  endposn = @tRange.endrange.offset
                                ELSE                                         'Write
                                  @tRange.beginrange.offset = startposn
                                  @tRange.endrange.offset = endposn
                                END IF
                              END FUNCTION
                              Last edited by Robert Wallace; 3 Sep 2009, 06:18 AM. Reason: Updated version of the Function

                              Comment


                              • #16
                                Next Problem !

                                The original VB6 code creates tRange which is used for all other text handling:
                                Code:
                                Dim tRange as udtTextRange
                                ...
                                ...
                                Set oDoc = mySession.ActiveDoc
                                tRange = oDoc.TextSelection
                                I now have to delete the marked text(VB6):
                                Code:
                                oDoc.TextSelection trange
                                The Method is:
                                Code:
                                Method DeleteText <349> (Byval textRange As Variant) As Long
                                How do I convert the PTR from the previous post:
                                Code:
                                LOCAL tRange AS udtTextRange PTR
                                into the form required by the Method?

                                Comment


                                • #17
                                  You already have it. Pass vTemp.
                                  Forum: http://www.jose.it-berater.org/smfforum/index.php

                                  Comment


                                  • #18
                                    You already have it. Pass vTemp
                                    That is what I thought too but the Compiler won't have it:
                                    Code:
                                    OBJECT GET myDocument.TextSelection TO vtemp
                                    myDocument.DeleteText vtemp
                                    The cursor is placed in front of vtemp and I get the message:
                                    Code:
                                    METHOD or PROPERTY name expected

                                    Comment


                                    • #19
                                      You are using the Object Call|Get|Set syntax, therefore, change
                                      Code:
                                      myDocument.DeleteText vtemp
                                      to
                                      Code:
                                      Object Call myDocument.DeleteText(vtemp)
                                      Dominic Mitchell
                                      Phoenix Visual Designer
                                      http://www.phnxthunder.com

                                      Comment


                                      • #20
                                        I am a complete idiot - it works of course

                                        Comment

                                        Working...
                                        X