Dax89
Joined: 10 Aug 2009 Posts: 2
|
Posted: Mon Aug 10, 2009 3:37 am Post subject: ShellAPI Fix |
|
|
Hi!
I'm doing some tests with ShellAPI and I have found some errors in modules.
For example: the SHGetDesktopFolder takes an IShellFolder** as parameter, but in D, an interface is already a pointer, so is sufficient do:
Code: |
IShellFolder pDesktopFolder = null;
SHGetDesktopFolder(&pDesktopFolder);
|
And, it works.
The alias LPSHELLFOLDER becomes:
Code: |
alias IShellFolder LPSHELLFOLDER;
|
not:
Code: |
alias IShellFolder* LPSHELLFOLDER; //Wrong!
|
The IShellFolder is defined as follows:
Code: |
extern(Windows) interface IShellFolder : public IUnknown
{
HRESULT QueryInterface(REFIID,PVOID*);
ULONG AddRef();
ULONG Release();
HRESULT ParseDisplayName(HWND,LPBC,LPOLESTR,PULONG,LPITEMIDLIST*,PULONG);
HRESULT EnumObjects(HWND,DWORD,LPENUMIDLIST*);
HRESULT BindToObject(LPCITEMIDLIST,LPBC,REFIID,PVOID*);
HRESULT BindToStorage(LPCITEMIDLIST,LPBC,REFIID,PVOID*);
HRESULT CompareIDs(LPARAM,LPCITEMIDLIST,LPCITEMIDLIST);
HRESULT CreateViewObject(HWND,REFIID,PVOID*);
HRESULT GetAttributesOf(UINT,LPCITEMIDLIST*,PULONG);
HRESULT GetUIObjectOf(HWND,UINT,LPCITEMIDLIST*,REFIID,PUINT,PVOID*);
HRESULT GetDisplayNameOf(LPCITEMIDLIST,DWORD,LPSTRRET);
HRESULT SetNameOf(HWND,LPCITEMIDLIST,LPCOLESTR,DWORD,LPITEMIDLIST*);
}
|
I think that is wrong because QueryInterface(), AddRef() and Release() methods are defined in IUnknown interface and it is unnecessary in IShellFolder.
I have made a test removing these three methods and the interface looks as follow:
Code: |
extern(Windows) interface IShellFolder : public IUnknown
{
HRESULT ParseDisplayName(HWND,LPBC,LPOLESTR,PULONG,LPITEMIDLIST*,PULONG);
HRESULT EnumObjects(HWND,DWORD,LPENUMIDLIST*);
HRESULT BindToObject(LPCITEMIDLIST,LPBC,REFIID,PVOID*);
HRESULT BindToStorage(LPCITEMIDLIST,LPBC,REFIID,PVOID*);
HRESULT CompareIDs(LPARAM,LPCITEMIDLIST,LPCITEMIDLIST);
HRESULT CreateViewObject(HWND,REFIID,PVOID*);
HRESULT GetAttributesOf(UINT,LPCITEMIDLIST*,PULONG);
HRESULT GetUIObjectOf(HWND,UINT,LPCITEMIDLIST*,REFIID,PUINT,PVOID*);
HRESULT GetDisplayNameOf(LPCITEMIDLIST,DWORD,LPSTRRET);
HRESULT SetNameOf(HWND,LPCITEMIDLIST,LPCOLESTR,DWORD,LPITEMIDLIST*);
}
|
This is a problem in other interfaces too.
Summarizing the problems are:
1) When in C++ is passed a double pointer to an interface, in D is necessary to pass a single pointer to an interface, because in D an interface is already a single pointer
2) AddRef(), Release() an QueryInterface() methods are implemented in IUnknown and inherited through other interfaces, so there is no need to define it again.
I'm sorry for this long post and my poor english.
PS: I'm using the latest win32 binding. |
|