vb.net - Correct way to get an interface / object from an interface pointer? -
having known nothing interfaces until now, having remarkably hard time trying implement solution given this question.
i think correctly getting pointer ishellfolder interface, don't seem able use pointer. how usable interface when having pointer?
the code below shows doing , suspect problems.
first, interface delarations:
' have wrapped interfaces in own namespace, "binarusshell". ' have declared every interface's functions / subs in same order in .idl files of windows platform sdk 7.1. ' every function / sub has <preservesig()> attribute can see native return values when debugging. ' i'd keep question lean possible, showing few functions per interface. ' of course, have implemented of them (as in respective .idl file). namespace binarusshell <comimport()> _ <interfacetype(cominterfacetype.interfaceisiunknown)> _ <guid("000214fa-0000-0000-c000-000000000046")> _ public interface iextracticon ' above guid guid unicode version of interface, i.e. iextracticonw. ' therefore, unicode variant of strings used in parameters of following functions. ' see include files of windows sdk done way well. <preservesig()> function geticonlocation(byval uflags uinteger, <marshalas(unmanagedtype.lpwstr, sizeparamindex:=2)> byval psziconfile string, byval cchmax uinteger, byref piindex integer, byref pwflags uinteger) integer ' ... ' here comes second function (iextracticon has two) ... ' ... end interface <comimport()> _ <interfacetype(cominterfacetype.interfaceisiunknown)> _ <guid("000214e6-0000-0000-c000-000000000046")> _ public interface ishellfolder <preservesig()> function getuiobjectof(<[in]()> byval hwndowner intptr, <[in]()> byval cidl uinteger, <[in]()> <marshalas(unmanagedtype.lparray, sizeparamindex:=1)> byval apidl() intptr, <[in]()> <marshalas(unmanagedtype.lpstruct)> byval riid guid, <[in](), out()> byref rgfreserved uinteger, <out()> byref ppv intptr) integer ' ... ' here come other functions ... ' ... end interface end namespace
second, windows api declarations, , third, function want implement (this stuck):
' windows api declarations in class win32api. ' class not wrapped in namespace. ' keep question lean possible, leaving out declarations of constants or guids. ' have taken of them literally windows platform sdk 7.1. public class win32api <dllimport("shell32.dll", charset:=charset.auto)> _ private shared function shbindtoparent(<[in]()> byval pidl intptr, <[in]()> <marshalas(unmanagedtype.lpstruct)> byval riid guid, <out()> byref ppv intptr, <out()> byref ppidllast intptr) integer end function <dllimport("shell32.dll", charset:=charset.auto)> _ private shared function shgetknownfolderidlist(<[in]()> <marshalas(unmanagedtype.lpstruct)> byval rfid guid, <[in]()> byval dwflags uinteger, <[in]()> byval htoken intptr, <out()> byref ppidl intptr) integer end function ' ----------------------------------------------------- ' function implement in class win32api well. ' function @ stage nothing useful outer world; ' meant code stepping through debugger. ' comments below show result of every step , understanding has happened. public shared function icontest() boolean dim ui_returnflags uinteger dim i_result integer dim intptr_currentpidlabsolute intptr, intptr_parentishellfolder intptr, intptr_currentiextracticon intptr dim arintptr_relpidlist(0) intptr dim ishellfolder_parent binarusshell.ishellfolder dim iextracticon_extractor binarusshell.iextracticon i_result = shgetknownfolderidlist(folderid_system, 0, 0, intptr_currentpidlabsolute) ' above seems work. i_result 0 means success, , ' intptr_currentpidlabsolute has reasonable value now. i_result = shbindtoparent(intptr_currentpidlabsolute, iid_ishellfolder, intptr_parentishellfolder, arintptr_relpidlist(0)) ' above seems work. i_result 0 means success, , ' intptr_parentishellfolder , arintptr_relpidlist(0) have reasonable values now. ' problems begin. have no clue how interface / object ' intptr_parentishellfolder can use within vb.net. ' therefore, have tried following (but believing wrong): ishellfolder_parent = directcast(marshal.getobjectforiunknown(intptr_parentishellfolder), binarusshell.ishellfolder) ' not throw error, have no clue happening. ' marshal.getobjectforiunknown, name implies, should return object ' encapsulates iunknown interface, giving pointer ishellfolder ' interface, wonder why doesn't freak out. original idea ' try way believe ishellfolder inherits iunknown, ' *eventually* work way. comment that? i_result = ishellfolder_parent.getuiobjectof(0, 1, arintptr_relpidlist, iid_iextracticon, ui_returnflags, intptr_currentiextracticon) ' point puzzled. i_result still 0, ' means success, intptr_currentiextracticon 0 well, meaning ' has gone horribly wrong. according understanding of ' msdn documentation, getuiobjectof must not return s_ok if ' has gone wrong; in other words, if returns s_ok, intptr_currentiextracticon ' must set reasonable value. explain what's happening? ' have left out rest of function because wouldn't make sense ' use null pointer further action. end function end class
any ideas doing wrong? docs, got impression every folder item (virtual or not) , file exposes iextracticon.
answering own question: when defining ishellfolder
interface in vb.net, had forgotten include bindtofolder()
function (you shouldn't try implement things @ 03:00 a.m., notably if had no clue of things until 1 hour before).
of course, documented everywhere, made ishellfolder
interface produce wrong results (again not knowing talking about, since bindtofolder()
comes before getuiobjectof()
in interface definition, , latter in turn comes before getdisplaynameof()
, imagine getdisplaynameof()
has been called when code called getuiobjectof()
, explain weird results).
now have corrected ishellfolder
definition (i.e. have added missing function) , have double-checked other interface definitions (those without errors), , works expected.
Comments
Post a Comment