CWindow RC 21

Started by José Roca, September 09, 2016, 02:32:30 PM

Previous topic - Next topic

José Roca

Not sure if we may need an option to add a prefix. This was needed with PowerBASIC because it does not support leading underscores in the names. Maybe we can use a namespace instead, to avoid possible name conflicts.

Marc Pons

Jose

help to compile:


i imagine that comment  in your code :
' $FB_RESPATH = "Resources/FBTLBRES.rc"

is your own option to indicate in your adapted CSED editor where is the rc file

I've done the same with my own version  using
_:[CSED_COMPIL_RC]:   ./Resources/FBTLBRES.rc  ' with ou without double quotes !

but i can imagine if someone is trying to compile the code, it will be a problem (with different ide)

the complete command line i use is the following : 

Quote"c:\FreeBasic\FreeBASIC-1.05.0-win32\fbc.exe" -x "c:\FreeBasic\TLB_100\TLB_100.exe" -s gui -v TLB_100.bas "c:\FreeBasic\TLB_100\Resources\FBTLBRES.rc"  > TLB_100.log 2>&1

replacing   "c:\FreeBasic\FreeBASIC-1.05.0-win32\fbc.exe"       by the full path to fbc.exe
and c:\FreeBasic\TLB_100\            by the path where is located the tlb project

can solve the problem (if any)

José Roca

#17
It was only a quick hack for using my partially adapted editor with FB. I'm using it until Paul will finish his WinFBE editor.

I don't want to make more editors. Too time consuming.

Marc Pons

Jose
QuoteNot sure if we may need an option to add a prefix.

it is only depending on how you intend to provide the code:
if it will be a class with all in it ( methods/propreties/events...) and some flag to identify wich id/hwnd is used
when more than 1 of same object is used the prefix is not necessery but if it is not as complete  , prefix is helpfull.


Maybe we can use a namespace instead
you know i do not like namespace  ;)  , i know it is more professionnal but ...

make the decision, what you will choose , will be good (i am so happy , you are doing that job)

José Roca

#19
> you know i do not like namespace

Don't understand why. It is like adding a prefix. And it's easy to add it, change it or remove it. You don't know how many times I missed it in PowerBASIC.

> if it will be a class with all in it ( methods/propreties/events...) and some flag to identify wich id/hwnd is used

In the browser, I will add a class to parse the TreeView, that contains all the information extracted from the typelib. How the code will be geneated is not yet decided. Using the automation view to generate interface definitions and/or object macros like the ones provided in the FB headers is the less problematic way. Using abstract methods is problematic because the FB headers don't provide support for it.

There are also the problems of duplicates (this is why I want to use namespaces) and forward references (it is a one-pass compiler).

If you want you can start to generate code in the way that you like. All the information that you need is in the treeview, and it is much easier to parse a treeview than a typelib.


José Roca

Added code to retrieve the default value of optional aprameters:


         ' // See if it has a default value
         IF (pParam[y].paramdesc.wParamFlags AND PARAMFLAG_FHASDEFAULT) = PARAMFLAG_FHASDEFAULT THEN
            DIM pex AS PARAMDESCEX PTR = pParam[y].paramdesc.pparamdescex
            DIM cbsDefaultValue AS CBSTR = AfxVarToBstr(@pex->vardefaultvalue)
            IF pex->vardefaultvalue.vt = VT_BSTR THEN
               TreeView_AddItem(hTreeView, hParamNameNode, NULL, "Default value = " & CHR(34) & **cbsDefaultValue & CHR(34))
'               cbstrFBSyntax += " = " & CHR(34) & **cbsDefaultValue & CHR(34)
            ELSE
               TreeView_AddItem(hTreeView, hParamNameNode, NULL, "Default value = " & cbsDefaultValue)
               cbstrFBSyntax += " = " & cbsDefaultValue
            END IF
         END IF


The AfxVarToStr wrapper saves a lot of work. It avoids to have to check for the vartype and add code to extract the value for every type.

José Roca

I have changed the code that sets the parameter name, data type and indirection to:


         ' // Parameter name, type and indirection
         SELECT CASE **cbstrTypeKind
            CASE "TKIND_INTERFACE", "TKIND_DISPATCH", "TKIND_COCLASS"
               IF wIndirectionLevel = 2 THEN
                  cbstrFBSyntax = "BYVAL " & **cbstrParamName & " AS " & **cbstrVarType & " PTR PTR"
               ELSE
                  cbstrFBSyntax = "BYVAL " & **cbstrParamName & " AS " & **cbstrVarType & " PTR"
               END IF
            CASE "TKIND_RECORD", "TKIND_UNION", "TKIND_ENUM"
               IF wIndirectionLevel = 2 THEN
                  cbstrFBSyntax = "BYVAL " & **cbstrParamName & " AS " & **cbstrVarType & " PTR PTR"
               ELSEIF wIndirectionLevel = 1 THEN
                  cbstrFBSyntax = "BYVAL " & **cbstrParamName &  " AS " & **cbstrVarType & " PTR"
               ELSE
                  cbstrFBSyntax = "BYVAL " & **cbstrParamName & " AS " & **cbstrVarType
               END IF
            CASE ELSE
               IF LEFT(**cbstrTypeKind, 11) = "TKIND_ALIAS" THEN
                  IF wIndirectionLevel = 2 THEN
                     cbstrFBSyntax = "BYVAL " & **cbstrParamName & " AS " & **cbstrVarType & " PTR PTR"
                  ELSEIF wIndirectionLevel = 1 THEN
                     cbstrFBSyntax = "BYVAL " & **cbstrParamName &  " AS " & **cbstrVarType & " PTR"
                  ELSE
                     cbstrFBSyntax = "BYVAL " & **cbstrParamName & " AS " & **cbstrVarType
                  END IF
               ELSE
                  SELECT CASE **cbstrVarType
                     CASE "VT_UNKNOWN"
                        IF wIndirectionLevel = 2 THEN
                           cbstrFBSyntax = "BYVAL " & **cbstrParamName & " AS IUnknown PTR PTR"
                        ELSEIF wIndirectionLevel = 1 THEN
                           IF ((wFlags AND PARAMFLAG_FOUT) = PARAMFLAG_FOUT) OR ((wFlags AND PARAMFLAG_FRETVAL) = PARAMFLAG_FRETVAL) THEN
                              cbstrFBSyntax = "BYVAL " & **cbstrParamName & " AS IUnknown PTR PTR"
                           ELSE
                              cbstrFBSyntax = "BYVAL " & **cbstrParamName & " AS IUnknown PTR"
                           END IF
                        ELSE
                           cbstrFBSyntax = "BYVAL " & **cbstrParamName & " AS IUnknown PTR"
                        END IF
                     CASE "VT_DISPATCH"
                        IF wIndirectionLevel = 2 THEN
                           cbstrFBSyntax = "BYVAL " & **cbstrParamName & " AS IDispatch PTR PTR"
                        ELSEIF wIndirectionLevel = 1 THEN
                           IF ((wFlags AND PARAMFLAG_FOUT) = PARAMFLAG_FOUT) OR ((wFlags AND PARAMFLAG_FRETVAL) = PARAMFLAG_FRETVAL) THEN
                              cbstrFBSyntax = "BYVAL " & **cbstrParamName & " AS IDispatch PTR PTR"
                           ELSE
                              cbstrFBSyntax = "BYVAL " & **cbstrParamName & " AS IDispatch PTR"
                           END IF
                        ELSE
                           cbstrFBSyntax = "BYVAL " & **cbstrParamName & " AS IDispatch PTR"
                        END IF
                     CASE "VT_VOID"
                        IF wIndirectionLevel = 2 THEN
                           cbstrFBSyntax = "BYVAL " & **cbstrParamName & " AS ANY PTR PTR"
                        ELSEIF wIndirectionLevel = 1 THEN
                           IF ((wFlags AND PARAMFLAG_FOUT) = PARAMFLAG_FOUT) OR ((wFlags AND PARAMFLAG_FRETVAL) = PARAMFLAG_FRETVAL) THEN
                              cbstrFBSyntax = "BYVAL " & **cbstrParamName & " AS ANY PTR PTR"
                           ELSE
                              cbstrFBSyntax = "BYVAL " & **cbstrParamName & " AS ANY PTR"
                           END IF
                        ELSE
                           cbstrFBSyntax = "BYVAL " & **cbstrParamName & " AS ANY PTR"
                        END IF
                     CASE "VT_LPSTR"
                        IF wIndirectionLevel = 2 THEN
                           cbstrFBSyntax = "BYVAL " & **cbstrParamName & " AS ZSTRING PTR PTR"
                        ELSE
                           cbstrFBSyntax = "BYVAL " & **cbstrParamName & " AS ZSTRING PTR"
                        END IF
                     CASE "VT_LPWSTR"
                        IF wIndirectionLevel = 2 THEN
                           cbstrFBSyntax = "BYVAL " & **cbstrParamName & " AS WSTRING PTR PTR"
                        ELSE
                           cbstrFBSyntax = "BYVAL " & **cbstrParamName & " AS WSTRING PTR"
                        END IF
                     CASE "VT_BSTR"
                        IF wIndirectionLevel = 2 THEN
                           cbstrFBSyntax = "BYVAL " & **cbstrParamName & " AS BSTR PTR PTR"
                        ELSEIF wIndirectionLevel = 1 THEN
                           cbstrFBSyntax = "BYVAL " & **cbstrParamName & " AS BSTR PTR"
                        ELSE
                           cbstrFBSyntax = "BYVAL " & **cbstrParamName & " AS BSTR"
                        END IF
                     CASE ELSE
                        IF wIndirectionLevel = 2 THEN
                           cbstrFBSyntax = "BYVAL " & **cbstrParamName &  " AS " & **cbstrFBKeyword & " PTR PTR"
                        ELSEIF wIndirectionLevel = 1 THEN
                           cbstrFBSyntax = "BYVAL " & **cbstrParamName &  " AS " & **cbstrFBKeyword & " PTR"
                        ELSE
                           cbstrFBSyntax = "BYVAL " & **cbstrParamName &  " AS " & **cbstrFBKeyword
                        END IF
                  END SELECT
               END IF
         END SELECT


Hopefully it will work correctly.

José Roca

#22
TypeLib Browser Beta 02

Incorporates all the changes previously discussed and other small changes.

Marc Pons

#23
the beta 02 works perfectly !!!


continuing checking with the ocx/dll in my machine comparing with axsuite3 and with your tlb_501( pb version)

found  one (where ? what? ) wich crashs your tlb_501 
when  option get run time key is on, but ok when get run time key is off

with the fb beta 02 works corectly but "get run time key" is not activated
so i've done the test whith the following modified code for fb  (from your sleeping code)

' ========================================================================================
' Retrieves the license key for licensed controls.
' Note: As CoGetClassObject creates an unitialized instance of the server to access the
' IClassFactory2 interface, it can take some time with remote servers such as WSCRIPT.EXE.
' ========================================================================================
FUNCTION TLB_GetRuntimeLicenseKey (BYREF sInfo AS WSTRING) AS CWSTR

   DIM hr                 AS HRESULT              ' // HRESULT
   DIM pIClassFactory2    AS IClassFactory2 PTR   ' // IClassFactory2 interface
   DIM ClassClsid         AS CLSID                ' // CLSID
   DIM tLicInfo           AS LICINFO              ' // LICINFO structure
   DIM cbstrLicKey        AS CBSTR                ' // License key

function = ""
   ' // Retrieve the CLSID from the PROGID or from the CLSID string of the component
IF INSTR(sInfo, "{") THEN CLSIDFromString(sInfo, @ClassClsid) ELSE CLSIDFromProgID(sInfo, @ClassClsid)
?sInfo
   ' // Get a pointer to the IClassFactory2 interface
'hr = CoGetClassObject(@ClassClsid, CLSCTX_SERVER, NULL, @IID_IClassFactory2, @pIClassFactory2)
   hr = CoGetClassObject(@ClassClsid, CLSCTX_ALL, NULL, @IID_IClassFactory2, @pIClassFactory2)
'hr = CoGetClassObject(@ClassClsid, CLSCTX_INPROC_SERVER, NULL, @IID_IClassFactory2, @pIClassFactory2)
   IF hr <> S_OK THEN exit function
?"step1 " & cast(integer,pIClassFactory2)
if cast(integer,pIClassFactory2)< 10000000 THEN
? "pIClassFactory2 = " & cast(integer,pIClassFactory2) : print "Quit TLB_GetRuntimeLicenseKey"
exit function
   END IF
   ' // Fill the LICINFO structure
   tLicInfo.cbLicInfo = SIZEOF(tLicInfo)
?"step2 " & SIZEOF(tLicInfo)
   hr = IClassFactory2_GetLicInfo(pIClassFactory2, @tLicInfo)
?"step3"
   ' // If there is a runtime key available retrieve it
   IF hr = S_OK THEN
      IF tLicInfo.fRuntimeKeyAvail THEN
IClassFactory2_RequestLicKey(pIClassFactory2, 0, @cbstrLicKey)
?"cbstrLicKey = " & cbstrLicKey
if len(cbstrLicKey)= 36  THEN function = cbstrLicKey
      END IF
   END IF
?"last"
   ' // Release the interface
   IClassFactory2_Release(pIClassFactory2)

END FUNCTION
' ========================================================================================

the function gets correctly the run time key on "good candidates" ,
i've reproduced the crash on the fb version too,
and noticed the pIClassFactory2 is the key point it is why i block it if cast(integer,pIClassFactory2)< 10000000
when it works the value is always bigger than 10000000 , problably something wrong on memory ?

last update : when uregistering an registering again the cast(integer,pIClassFactory2) value changed and now that filter is not ok

José Roca

I'm not going to implement this feature. I had many problems with it, as you are experiencing, and it is not too useful because if you are a licensed user you already should have the license key.

José Roca

#25
Also be aware that some type libraries are buggy or corrupted. For example, bined.dll fails to retrieve an instance of the TYPEATTR structure with some members. It is not a bug in the browser: the same happens when you use OleView.exe.

José Roca

#26
TLB_100 Beta 03

Changed Prefix to Namespace.

Removed the "Code" toolbar button. Code is generated at the same time that the information is displayed in the TreeView. Therefore, you only need to click the "Code" tab to see it.

Added code generation (work in progress). Need to add code to retrieve the parameters.

Note: I have reuploaded the file because there was a duplicate line in the code that generates the code for enums. This caused to generate the "ENUM xxxx" line twice.

José Roca

#27
Added some changes to correctly identify the type of the parameters and a preliminary pass to identify the events interfaces and insert the data in the Events interfaces node.

José Roca

What can't be detected are the vtable events interfaces. This .tlb stuff was designed by the VB6 team and, as VB6 can't use these kind of events, they didn't bother.

José Roca

I'm thinking in doing the following...

If the "Automation view" option is checked, the interface definitions will use the syntax used in the FB headers, that is, no inheritance and listing all and every one of the methods, and using the BSTR and VARIANt data types.

If it is not checked, they will use unheritance and abstract methods, and instead of BSTR and VARIANT, CBSTR and CVARIANT. Using CBSTR instead of BSTR or AFX_BSTR allows to pass literal strings directly, instead of having to pass a variable, and even to use default string values in optional parameters. Of course, this means that my include files have to be used, but the FB headers don't provide support for abstract methods anyway.

Any thoughts?