Page 1 of 1
[ANSWERED] How to use CLSIDFromString()
Posted: Sun Oct 14, 2012 11:49 pm
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!
Re: How to use CLSIDFromString()
Posted: Sun Oct 14, 2012 11:57 pm
by Josh
Do you have activated Unicode?
Re: How to use CLSIDFromString()
Posted: Mon Oct 15, 2012 12:33 am
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
Re: How to use CLSIDFromString()
Posted: Mon Oct 15, 2012 4:31 pm
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.
Re: How to use CLSIDFromString()
Posted: Mon Oct 15, 2012 4:48 pm
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.
Re: How to use CLSIDFromString()
Posted: Mon Oct 15, 2012 5:49 pm
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?
Re: How to use CLSIDFromString()
Posted: Mon Oct 15, 2012 5:51 pm
by netmaestro
You don't need to free anything using Purebasic pseudotypes.
Re: How to use CLSIDFromString()
Posted: Tue Oct 16, 2012 3:23 am
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.
Re: [ANSWERED] How to use CLSIDFromString()
Posted: Tue Oct 16, 2012 6:50 am
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:
Re: [ANSWERED] How to use CLSIDFromString()
Posted: Wed Oct 17, 2012 8:23 am
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:
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.