[ANSWERED] How to use CLSIDFromString()

Just starting out? Need help? Post your questions and find answers here.
User avatar
TI-994A
Addict
Addict
Posts: 2698
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

[ANSWERED] How to use CLSIDFromString()

Post by TI-994A »

Hello everyone. There are some very good examples in the use of CoCreateInstance() in this forum, but I can't find any of CLSIDFromString(). Is this function usable from PureBasic? I've been trying out this routine which I found in this forum, but to no success:

Code: Select all

Define CLSID_ShellLink.CLSID, shlCLSID.s, hRes.l
shlCLSID = "{00021401-0000-0000-C000-000000000046}"
hRes =  CLSIDFromString_(@shlCLSID , @CLSID_ShellLink)
Select hRes
 Case #NOERROR
    Debug "Success"
 Case #CO_E_CLASSSTRING
    Debug "The class string was improperly formatted."
 Case #REGDB_E_CLASSNOTREG
    Debug "The CLSID corresponding to the class string was not found in the registry."
 Case #REGDB_E_READREGDB
    Debug "The registry could not be opened for reading."
 Default
    Debug hRes
EndSelect
Am I doing it wrongly?

---> Please see netmaestro's solutions below. Thank you netmaestro!
Last edited by TI-994A on Tue Oct 16, 2012 3:26 am, edited 1 time in total.
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
User avatar
Josh
Addict
Addict
Posts: 1183
Joined: Sat Feb 13, 2010 3:45 pm

Re: How to use CLSIDFromString()

Post by Josh »

Do you have activated Unicode?
sorry for my bad english
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: How to use CLSIDFromString()

Post by netmaestro »

This api doesn't take an asciiz, it takes an olestring (or bstr). If you don't wish to compile as Unicode, Give these a try:

Code: Select all

; ASCII only for this version...

Procedure.l ansi2bstr(ansi.s)
  Size.l=MultiByteToWideChar_(#CP_ACP,0,ansi,-1,0,0)
  Dim unicode.w(Size)
  MultiByteToWideChar_(#CP_ACP, 0, ansi, Len(ansi), unicode(), Size)
  ProcedureReturn SysAllocString_(@unicode())
EndProcedure

Define CLSID_ShellLink.CLSID, shlCLSID.s, hRes.l
shlCLSID = "{00021401-0000-0000-C000-000000000046}"
hRes =  CLSIDFromString_(ansi2bstr(shlCLSID) , @CLSID_ShellLink)
Select hRes
 Case #NOERROR
    Debug "Success"
 Case #CO_E_CLASSSTRING
    Debug "The class string was improperly formatted."
 Case #REGDB_E_CLASSNOTREG
    Debug "The CLSID corresponding to the class string was not found in the registry."
 Case #REGDB_E_READREGDB
    Debug "The registry could not be opened for reading."
 Default
    Debug hRes
EndSelect
Another approach, using a Purebasic pseudotype, should also work in either mode:

Code: Select all

;ASCII or Unicode are both OK for this version

Prototype CLSIDFromString(str.p-bstr, *pClsID.CLSID)

Procedure CLSIDFromString(*string, *pClsID.CLSID)
  hres = CLSIDFromString_(*string, *pClsID)
  If hRes = #NOERROR
    ProcedureReturn 1
  Else
    ProcedureReturn 0
  EndIf
EndProcedure

Global myCLSIDFromString.CLSIDFromString = @CLSIDFromString()

Define CLSID_ShellLink.CLSID, shlCLSID.s, hRes.l

shlCLSID = "{00021401-0000-0000-C000-000000000046}"

Debug Hex(CLSID_ShellLink\data1, #PB_Long) ; nothing done to it yet, should be 0
hRes =  myCLSIDFromString(shlCLSID, @CLSID_ShellLink)
Debug Hex(CLSID_ShellLink\data1, #PB_Long) ; should now be 21401
BERESHEIT
User avatar
TI-994A
Addict
Addict
Posts: 2698
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: How to use CLSIDFromString()

Post by TI-994A »

Josh wrote:Do you have activated Unicode?
Hi Josh. You got it right; thank you.
netmaestro wrote:This api doesn't take an asciiz, it takes an olestring (or bstr).
Hi netmaestro! Works perfectly for my requirements with CoCreateInstance(). Thanks for the tips about UNICode, ASCII, OLEString, bStr, etc. I read them up, but honestly would never have figured them out on my own. Thank you for the examples and for all your help.
Last edited by TI-994A on Tue Oct 16, 2012 3:40 am, edited 1 time in total.
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
User avatar
Josh
Addict
Addict
Posts: 1183
Joined: Sat Feb 13, 2010 3:45 pm

Re: How to use CLSIDFromString()

Post by Josh »

@TI-994A

If you use b-strings, don't forget to free them. Otherwise you get a lot of memory leaks. I don't think, they are automatic freed after ending you program.
sorry for my bad english
User avatar
TI-994A
Addict
Addict
Posts: 2698
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: How to use CLSIDFromString()

Post by TI-994A »

Josh wrote:@TI-994A
If you use b-strings, don't forget to free them. Otherwise you get a lot of memory leaks. I don't think, they are automatic freed after ending you program.
Hello again Josh. Thanks for the heads-up. However, I can't seem to find the function for freeing-up such pseudotypes. From the forum examples that I've seen, we need to use SysFreeString() for bStr pointers created with SysAllocString(). But these functions expect numeric pointers, and not strings.

How should I free shlCLSID.s in netmaestro's example?
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: How to use CLSIDFromString()

Post by netmaestro »

You don't need to free anything using Purebasic pseudotypes.
BERESHEIT
User avatar
TI-994A
Addict
Addict
Posts: 2698
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: How to use CLSIDFromString()

Post by TI-994A »

netmaestro wrote:You don't need to free anything using Purebasic pseudotypes.
That's great. Thanks again guys; really appreciate all your valuable input, and especially the solution.
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
User avatar
Josh
Addict
Addict
Posts: 1183
Joined: Sat Feb 13, 2010 3:45 pm

Re: [ANSWERED] How to use CLSIDFromString()

Post by Josh »

if you use netmaestros first example, you have to change the code a little bit. Change also the procedure return type from .l to .i, its a pointer.

Code: Select all

; ASCII only for this version...

Procedure.i ansi2bstr(ansi.s)
  Size.l=MultiByteToWideChar_(#CP_ACP,0,ansi,-1,0,0)
  Dim unicode.w(Size)
  MultiByteToWideChar_(#CP_ACP, 0, ansi, Len(ansi), unicode(), Size)
  ProcedureReturn SysAllocString_(@unicode())
EndProcedure

Define CLSID_ShellLink.CLSID, shlCLSID.s, hRes.l, *bStr
shlCLSID = "{00021401-0000-0000-C000-000000000046}"
*bStr = ansi2bstr(shlCLSID)
hRes =  CLSIDFromString_(*bStr , @CLSID_ShellLink)
Select hRes
 Case #NOERROR
    Debug "Success"
 Case #CO_E_CLASSSTRING
    Debug "The class string was improperly formatted."
 Case #REGDB_E_CLASSNOTREG
    Debug "The CLSID corresponding to the class string was not found in the registry."
 Case #REGDB_E_READREGDB
    Debug "The registry could not be opened for reading."
 Default
    Debug hRes
EndSelect
SysFreeString_(*bStr)
If I often call such procedures like ansi2bstr, i use the following code:

Code: Select all

; ASCII only for this version...

Procedure.i ansi2bstr(ansi.s)
  Static bStr.i
  
  SysFreeString_(bStr)
  If ansi = ""
    ProcedureReturn
  EndIf

  Size.l=MultiByteToWideChar_(#CP_ACP,0,ansi,-1,0,0)
  Dim unicode.w(Size)
  MultiByteToWideChar_(#CP_ACP, 0, ansi, Len(ansi), unicode(), Size)
  bStr = SysAllocString_(@unicode())
  ProcedureReturn bStr

EndProcedure

Define CLSID_ShellLink.CLSID, shlCLSID.s, hRes.l
shlCLSID = "{00021401-0000-0000-C000-000000000046}"
hRes =  CLSIDFromString_(ansi2bstr(shlCLSID) , @CLSID_ShellLink)
Select hRes
 Case #NOERROR
    Debug "Success"
 Case #CO_E_CLASSSTRING
    Debug "The class string was improperly formatted."
 Case #REGDB_E_CLASSNOTREG
    Debug "The CLSID corresponding to the class string was not found in the registry."
 Case #REGDB_E_READREGDB
    Debug "The registry could not be opened for reading."
 Default
    Debug hRes
EndSelect
With this code it's secured, that all the running time is only one bString stored by this procedure. At the end of you program you call one time:

Code: Select all

ansi2bstr("")
sorry for my bad english
User avatar
TI-994A
Addict
Addict
Posts: 2698
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: [ANSWERED] How to use CLSIDFromString()

Post by TI-994A »

Josh wrote:With this code it's secured, that all the running time is only one bString stored by this procedure. At the end of you program you call one time:

Code: Select all

ansi2bstr("")
Hi Josh. That's a nice and neat way to release resources that can be implemented in other procedures as well. Thanks for the pointer.
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
Post Reply