mirror of
https://github.com/reactos/reactos.git
synced 2024-11-28 05:53:31 +08:00
[BROWSEUI] CBandSiteMenu: Implement the Desktop, Quick Launch and New Toolbar menu items
This commit is contained in:
parent
0ed80264f9
commit
37e6151b40
@ -22,9 +22,20 @@
|
||||
#include "shellbars.h"
|
||||
#include <strsafe.h>
|
||||
|
||||
/* The menu consists of 3 parts. The first is loaded from the resources,
|
||||
the second is populated with the classes of the CATID_DeskBand comcat
|
||||
and the third part consists of the entries for each CISFBand in the band side.
|
||||
The first 5 ids are reserved for the resource menu, the following ids will be
|
||||
for the CATID_DeskBand classes and the rest for the CISFBands.
|
||||
The ids for the CISFBand menu items are not continuous, in this range
|
||||
each menu id is calculated by adding the band id to the last id for the CATID_DeskBand range */
|
||||
#define FIRST_COMCAT_MENU_ID 0x5
|
||||
|
||||
CBandSiteMenu::CBandSiteMenu():
|
||||
m_menuDsa(NULL),
|
||||
m_hmenu(NULL)
|
||||
m_comcatDsa(NULL),
|
||||
m_hmenu(NULL),
|
||||
m_DesktopPidl(NULL),
|
||||
m_QLaunchPidl(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
@ -33,14 +44,37 @@ CBandSiteMenu::~CBandSiteMenu()
|
||||
if (m_hmenu)
|
||||
DestroyMenu(m_hmenu);
|
||||
|
||||
if (m_menuDsa)
|
||||
DSA_Destroy(m_menuDsa);
|
||||
if (m_comcatDsa)
|
||||
DSA_Destroy(m_comcatDsa);
|
||||
|
||||
if (m_DesktopPidl)
|
||||
ILFree(m_DesktopPidl);
|
||||
|
||||
if (m_QLaunchPidl)
|
||||
ILFree(m_QLaunchPidl);
|
||||
|
||||
m_BandSite = NULL;
|
||||
}
|
||||
|
||||
HRESULT WINAPI CBandSiteMenu::FinalConstruct()
|
||||
{
|
||||
HRESULT hr = SHGetFolderLocation(0, CSIDL_DESKTOP, NULL, 0, &m_DesktopPidl);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
HRESULT CBandSiteMenu::CreateMenuPart()
|
||||
WCHAR buffer[MAX_PATH];
|
||||
hr = SHGetFolderPathAndSubDirW(0, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, L"Microsoft\\Internet Explorer\\Quick Launch", buffer);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
m_QLaunchPidl = ILCreateFromPathW(buffer);
|
||||
if (m_QLaunchPidl == NULL)
|
||||
return E_FAIL;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CBandSiteMenu::_CreateMenuPart()
|
||||
{
|
||||
WCHAR wszBandName[MAX_PATH];
|
||||
WCHAR wszBandGUID[MAX_PATH];
|
||||
@ -56,16 +90,16 @@ HRESULT CBandSiteMenu::CreateMenuPart()
|
||||
if (m_hmenu)
|
||||
DestroyMenu(m_hmenu);
|
||||
|
||||
if (m_menuDsa)
|
||||
DSA_Destroy(m_menuDsa);
|
||||
if (m_comcatDsa)
|
||||
DSA_Destroy(m_comcatDsa);
|
||||
|
||||
/* Load the template we will fill in */
|
||||
m_hmenu = LoadMenuW(GetModuleHandleW(L"browseui.dll"), MAKEINTRESOURCEW(IDM_TASKBAR_TOOLBARS));
|
||||
if (!m_hmenu)
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
|
||||
m_menuDsa = DSA_Create(sizeof(GUID), 5);
|
||||
if (!m_menuDsa)
|
||||
m_comcatDsa = DSA_Create(sizeof(GUID), 5);
|
||||
if (!m_comcatDsa)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
/* Get the handle of the submenu where the available items will be shown */
|
||||
@ -94,8 +128,8 @@ HRESULT CBandSiteMenu::CreateMenuPart()
|
||||
SHGetValue(HKEY_CLASSES_ROOT, wRegKey, NULL, NULL, wszBandName, &dwDataSize);
|
||||
|
||||
/* Insert it */
|
||||
InsertMenu(hmenuToolbars, cBands, MF_BYPOSITION, DSA_GetItemCount(m_menuDsa), wszBandName);
|
||||
DSA_AppendItem(m_menuDsa, &iter);
|
||||
InsertMenu(hmenuToolbars, cBands, MF_BYPOSITION, DSA_GetItemCount(m_comcatDsa) + FIRST_COMCAT_MENU_ID, wszBandName);
|
||||
DSA_AppendItem(m_comcatDsa, &iter);
|
||||
cBands++;
|
||||
}
|
||||
while (dwRead > 0);
|
||||
@ -103,12 +137,197 @@ HRESULT CBandSiteMenu::CreateMenuPart()
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CBandSiteMenu::_CreateNewISFBand(HWND hwnd, REFIID riid, void** ppv)
|
||||
{
|
||||
WCHAR path[MAX_PATH];
|
||||
WCHAR message[256];
|
||||
BROWSEINFOW bi = { hwnd, NULL, path };
|
||||
|
||||
if (LoadStringW(GetModuleHandleW(L"browseui.dll"), IDS_BROWSEFORNEWTOOLAR, message, _countof(message)))
|
||||
bi.lpszTitle = message;
|
||||
else
|
||||
bi.lpszTitle = L"Choose a folder";
|
||||
|
||||
LPITEMIDLIST pidlSelected = SHBrowseForFolderW(&bi);
|
||||
if (pidlSelected == NULL)
|
||||
return S_FALSE;
|
||||
|
||||
CComPtr<IShellFolderBand> pISFB;
|
||||
HRESULT hr = CISFBand_CreateInstance(IID_IShellFolderBand, (PVOID*)&pISFB);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
goto done;
|
||||
|
||||
hr = pISFB->InitializeSFB(NULL, pidlSelected);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
goto done;
|
||||
|
||||
hr = pISFB->QueryInterface(riid, ppv);
|
||||
|
||||
done:
|
||||
ILFree(pidlSelected);
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT CBandSiteMenu::_CreateBuiltInISFBand(UINT uID, REFIID riid, void** ppv)
|
||||
{
|
||||
LPITEMIDLIST pidl;
|
||||
HRESULT hr;
|
||||
|
||||
pidl = (uID == IDM_TASKBAR_TOOLBARS_DESKTOP) ? m_DesktopPidl : m_QLaunchPidl;
|
||||
|
||||
CComPtr<IShellFolderBand> pISFB;
|
||||
hr = CISFBand_CreateInstance(IID_IShellFolderBand, (PVOID*)&pISFB);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
hr = pISFB->InitializeSFB(NULL, pidl);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
return pISFB->QueryInterface(riid, ppv);
|
||||
}
|
||||
|
||||
HRESULT CBandSiteMenu::_AddISFBandToMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, IUnknown* pBand, DWORD dwBandID, UINT *newMenuId)
|
||||
{
|
||||
CComPtr<IShellFolderBand> psfb;
|
||||
HRESULT hr = pBand->QueryInterface(IID_PPV_ARG(IShellFolderBand, &psfb));
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
BANDINFOSFB bi = {ISFB_MASK_IDLIST};
|
||||
hr = psfb->GetBandInfoSFB(&bi);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
if (!bi.pidl)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
WCHAR buffer[MAX_PATH];
|
||||
hr = ILGetDisplayNameEx(NULL, bi.pidl, buffer, ILGDN_INFOLDER) ? S_OK : E_FAIL;
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
UINT id = idCmdFirst + DSA_GetItemCount(m_comcatDsa) + FIRST_COMCAT_MENU_ID + dwBandID;
|
||||
if (id >= idCmdLast)
|
||||
return E_FAIL;
|
||||
|
||||
*newMenuId = id;
|
||||
InsertMenu(hmenu, indexMenu, MF_BYPOSITION, id, buffer);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
UINT CBandSiteMenu::_GetMenuIdFromISFBand(IUnknown *pBand)
|
||||
{
|
||||
UINT ret = UINT_MAX;
|
||||
|
||||
CComPtr<IShellFolderBand> psfb;
|
||||
HRESULT hr = pBand->QueryInterface(IID_PPV_ARG(IShellFolderBand, &psfb));
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return ret;
|
||||
|
||||
BANDINFOSFB bi = {ISFB_MASK_IDLIST};
|
||||
hr = psfb->GetBandInfoSFB(&bi);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return ret;
|
||||
|
||||
CComPtr<IShellFolder> psfDesktop;
|
||||
LPITEMIDLIST pidl = bi.pidl;
|
||||
if (!pidl)
|
||||
return ret;
|
||||
|
||||
if (pidl->mkid.cb == 0)
|
||||
{
|
||||
ret = IDM_TASKBAR_TOOLBARS_DESKTOP;
|
||||
goto done;
|
||||
}
|
||||
|
||||
hr = SHGetDesktopFolder(&psfDesktop);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
goto done;
|
||||
|
||||
hr = psfDesktop->CompareIDs(0, pidl, m_QLaunchPidl);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
goto done;
|
||||
|
||||
if (HRESULT_CODE(hr) == 0)
|
||||
ret = IDM_TASKBAR_TOOLBARS_QUICKLAUNCH;
|
||||
|
||||
done:
|
||||
if (pidl)
|
||||
ILFree(pidl);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
UINT CBandSiteMenu::_GetMenuIdFromBand(CLSID *BandCLSID)
|
||||
{
|
||||
/* Try to find the clsid of the band in the dsa */
|
||||
UINT count = DSA_GetItemCount(m_comcatDsa);
|
||||
for (UINT i = 0; i < count; i++)
|
||||
{
|
||||
GUID* pdsaGUID = (GUID*)DSA_GetItemPtr(m_comcatDsa, i);
|
||||
if (IsEqualGUID(*pdsaGUID, *BandCLSID))
|
||||
{
|
||||
/* The index in the dsa is also the index in the menu */
|
||||
return i + FIRST_COMCAT_MENU_ID;
|
||||
}
|
||||
}
|
||||
|
||||
return UINT_MAX;
|
||||
}
|
||||
|
||||
UINT CBandSiteMenu::_GetBandIdFromClsid(CLSID* pclsid)
|
||||
{
|
||||
CComPtr<IPersist> pBand;
|
||||
CLSID BandCLSID;
|
||||
DWORD dwBandID;
|
||||
|
||||
for (UINT uBand = 0; SUCCEEDED(m_BandSite->EnumBands(uBand, &dwBandID)); uBand++)
|
||||
{
|
||||
if (FAILED(m_BandSite->GetBandObject(dwBandID, IID_PPV_ARG(IPersist, &pBand))))
|
||||
continue;
|
||||
|
||||
if (FAILED(pBand->GetClassID(&BandCLSID)))
|
||||
continue;
|
||||
|
||||
if (IsEqualGUID(*pclsid, BandCLSID))
|
||||
return dwBandID;
|
||||
}
|
||||
|
||||
return UINT_MAX;
|
||||
}
|
||||
|
||||
UINT CBandSiteMenu::_GetBandIdForBuiltinISFBand(UINT uID)
|
||||
{
|
||||
CComPtr<IPersist> pBand;
|
||||
CLSID BandCLSID;
|
||||
DWORD dwBandID;
|
||||
|
||||
for (UINT uBand = 0; SUCCEEDED(m_BandSite->EnumBands(uBand, &dwBandID)); uBand++)
|
||||
{
|
||||
if (FAILED(m_BandSite->GetBandObject(dwBandID, IID_PPV_ARG(IPersist, &pBand))))
|
||||
continue;
|
||||
|
||||
if (FAILED(pBand->GetClassID(&BandCLSID)))
|
||||
continue;
|
||||
|
||||
if (!IsEqualGUID(BandCLSID, CLSID_ISFBand))
|
||||
continue;
|
||||
|
||||
UINT menuID = _GetMenuIdFromISFBand(pBand);
|
||||
if (menuID == uID)
|
||||
return dwBandID;
|
||||
}
|
||||
|
||||
return UINT_MAX;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE CBandSiteMenu::SetOwner(IUnknown *pOwner)
|
||||
{
|
||||
TRACE("CBandSiteMenu::SetOwner(%p, %p)\n", this, pOwner);
|
||||
|
||||
/* Cache the menu that will be merged every time QueryContextMenu is called */
|
||||
CreateMenuPart();
|
||||
_CreateMenuPart();
|
||||
|
||||
return pOwner->QueryInterface(IID_PPV_ARG(IBandSite, &m_BandSite));
|
||||
}
|
||||
@ -119,11 +338,12 @@ HRESULT STDMETHODCALLTYPE CBandSiteMenu::QueryContextMenu(
|
||||
CComPtr<IPersist> pBand;
|
||||
CLSID BandCLSID;
|
||||
DWORD dwBandID;
|
||||
UINT idMax;
|
||||
|
||||
TRACE("CBandSiteMenu::QueryContextMenu(%p, %p, %u, %u, %u, 0x%x)\n", this, hmenu, indexMenu, idCmdFirst, idCmdLast, uFlags);
|
||||
|
||||
/* First Merge the menu with the available bands */
|
||||
Shell_MergeMenus(hmenu, m_hmenu, indexMenu, idCmdFirst, idCmdLast, MM_DONTREMOVESEPS | MM_SUBMENUSHAVEIDS);
|
||||
idMax = Shell_MergeMenus(hmenu, m_hmenu, indexMenu, idCmdFirst, idCmdLast, MM_DONTREMOVESEPS | MM_SUBMENUSHAVEIDS);
|
||||
|
||||
HMENU hmenuToolbars = GetSubMenu(hmenu, indexMenu);
|
||||
|
||||
@ -136,63 +356,107 @@ HRESULT STDMETHODCALLTYPE CBandSiteMenu::QueryContextMenu(
|
||||
if (FAILED(pBand->GetClassID(&BandCLSID)))
|
||||
continue;
|
||||
|
||||
/* Try to find the clsid of the band in the dsa */
|
||||
UINT count = DSA_GetItemCount(m_menuDsa);
|
||||
for (UINT i = 0; i < count; i++)
|
||||
UINT menuID;
|
||||
if (IsEqualGUID(BandCLSID, CLSID_ISFBand))
|
||||
{
|
||||
GUID* pdsaGUID = (GUID*)DSA_GetItemPtr(m_menuDsa, i);
|
||||
if (memcmp(pdsaGUID, &BandCLSID, sizeof(GUID)) == 0)
|
||||
menuID = _GetMenuIdFromISFBand(pBand);
|
||||
if (menuID == UINT_MAX)
|
||||
{
|
||||
/* The index in the dsa is also the index in the menu */
|
||||
CheckMenuItem(hmenuToolbars, i, MF_CHECKED | MF_BYPOSITION);
|
||||
HRESULT hr;
|
||||
hr = _AddISFBandToMenu(hmenuToolbars, 0, idCmdFirst, idCmdLast, pBand, dwBandID, &menuID);
|
||||
if (SUCCEEDED(hr) && menuID > idMax)
|
||||
idMax = menuID;
|
||||
menuID -= idCmdFirst;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
menuID = _GetMenuIdFromBand(&BandCLSID);
|
||||
}
|
||||
|
||||
if (menuID != UINT_MAX)
|
||||
CheckMenuItem(hmenuToolbars, menuID + idCmdFirst, MF_CHECKED);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(idMax - idCmdFirst +1));
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE CBandSiteMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
|
||||
{
|
||||
HRESULT hRet;
|
||||
DWORD dwBandID;
|
||||
|
||||
/* FIXME: do we need to handle this and how? */
|
||||
if (HIWORD(lpici->lpVerb) != NULL)
|
||||
return E_FAIL;
|
||||
|
||||
/* Get the GUID of the item that was clicked */
|
||||
UINT uID = LOWORD(lpici->lpVerb);
|
||||
GUID *pguidToolbar = (GUID *)DSA_GetItemPtr(m_menuDsa, uID);
|
||||
if (uID == IDM_TASKBAR_TOOLBARS_NEW)
|
||||
{
|
||||
CComPtr<IDeskBand> pDeskBand;
|
||||
hRet = _CreateNewISFBand(lpici->hwnd, IID_PPV_ARG(IDeskBand, &pDeskBand));
|
||||
if (FAILED_UNEXPECTEDLY(hRet))
|
||||
return hRet;
|
||||
|
||||
hRet = m_BandSite->AddBand(pDeskBand);
|
||||
if (FAILED_UNEXPECTEDLY(hRet))
|
||||
return hRet;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
else if (uID > (UINT)DSA_GetItemCount(m_comcatDsa) + FIRST_COMCAT_MENU_ID )
|
||||
{
|
||||
dwBandID = uID - (DSA_GetItemCount(m_comcatDsa) + FIRST_COMCAT_MENU_ID );
|
||||
|
||||
m_BandSite->RemoveBand(dwBandID);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
else if (uID == IDM_TASKBAR_TOOLBARS_DESKTOP || uID == IDM_TASKBAR_TOOLBARS_QUICKLAUNCH)
|
||||
{
|
||||
dwBandID = _GetBandIdForBuiltinISFBand(uID);
|
||||
if (dwBandID != UINT_MAX)
|
||||
{
|
||||
m_BandSite->RemoveBand(dwBandID);
|
||||
}
|
||||
else
|
||||
{
|
||||
CComPtr<IDeskBand> pDeskBand;
|
||||
hRet = _CreateBuiltInISFBand(uID, IID_PPV_ARG(IDeskBand, &pDeskBand));
|
||||
if (FAILED_UNEXPECTEDLY(hRet))
|
||||
return hRet;
|
||||
|
||||
hRet = m_BandSite->AddBand(pDeskBand);
|
||||
if (FAILED_UNEXPECTEDLY(hRet))
|
||||
return hRet;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* Get the GUID of the item that was clicked */
|
||||
GUID *pguidToolbar = (GUID *)DSA_GetItemPtr(m_comcatDsa, uID - FIRST_COMCAT_MENU_ID);
|
||||
if (!pguidToolbar)
|
||||
return E_FAIL;
|
||||
|
||||
/* Try to find if a band with a guid is present. If it is remove it and return */
|
||||
CComPtr<IPersist> pBand;
|
||||
CLSID BandCLSID;
|
||||
DWORD dwBandID;
|
||||
for (UINT uBand = 0; SUCCEEDED(m_BandSite->EnumBands(uBand, &dwBandID)); uBand++)
|
||||
/* Try to find if a band with a guid is present. If it is, remove it and return */
|
||||
dwBandID = _GetBandIdFromClsid(pguidToolbar);
|
||||
if (dwBandID != UINT_MAX)
|
||||
{
|
||||
if (FAILED(m_BandSite->GetBandObject(dwBandID, IID_PPV_ARG(IPersist, &pBand))))
|
||||
continue;
|
||||
|
||||
if (FAILED(pBand->GetClassID(&BandCLSID)))
|
||||
continue;
|
||||
|
||||
if (memcmp(pguidToolbar, &BandCLSID, sizeof(GUID)) == 0)
|
||||
{
|
||||
/* We found it, remove it */
|
||||
m_BandSite->RemoveBand(dwBandID);
|
||||
return S_OK;
|
||||
}
|
||||
/* We found it, remove it */
|
||||
m_BandSite->RemoveBand(dwBandID);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* It is not present. Add it. */
|
||||
CComPtr<IDeskBand> pDeskBand;
|
||||
hRet = CoCreateInstance(*pguidToolbar, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IDeskBand, &pDeskBand));
|
||||
if (FAILED_UNEXPECTEDLY(hRet))
|
||||
return hRet;
|
||||
|
||||
/* It is not present. Add it. */
|
||||
CComPtr<IDeskBand> pDeskBand;
|
||||
HRESULT hRet = CoCreateInstance(*pguidToolbar, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IDeskBand, &pDeskBand));
|
||||
if (FAILED(hRet))
|
||||
return hRet;
|
||||
|
||||
hRet = m_BandSite->AddBand(pDeskBand);
|
||||
if (FAILED_UNEXPECTEDLY(hRet))
|
||||
return hRet;
|
||||
hRet = m_BandSite->AddBand(pDeskBand);
|
||||
if (FAILED_UNEXPECTEDLY(hRet))
|
||||
return hRet;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -29,14 +29,24 @@ class CBandSiteMenu :
|
||||
public IShellService
|
||||
{
|
||||
CComPtr<IBandSite> m_BandSite;
|
||||
HDSA m_menuDsa;
|
||||
HDSA m_comcatDsa;
|
||||
HMENU m_hmenu;
|
||||
LPITEMIDLIST m_DesktopPidl;
|
||||
LPITEMIDLIST m_QLaunchPidl;
|
||||
|
||||
HRESULT CreateMenuPart();
|
||||
HRESULT _CreateMenuPart();
|
||||
HRESULT _CreateNewISFBand(HWND hwnd, REFIID riid, void** ppv);
|
||||
HRESULT _CreateBuiltInISFBand(UINT uID, REFIID riid, void** ppv);
|
||||
HRESULT _AddISFBandToMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, IUnknown* pBand, DWORD dwBandID, UINT *newMenuId);
|
||||
UINT _GetMenuIdFromISFBand(IUnknown *pBand);
|
||||
UINT _GetMenuIdFromBand(CLSID *BandCLSID);
|
||||
UINT _GetBandIdFromClsid(CLSID* pclsid);
|
||||
UINT _GetBandIdForBuiltinISFBand(UINT uID);
|
||||
|
||||
public:
|
||||
CBandSiteMenu();
|
||||
~CBandSiteMenu();
|
||||
HRESULT WINAPI FinalConstruct();
|
||||
|
||||
// *** IShellService methods ***
|
||||
virtual HRESULT STDMETHODCALLTYPE SetOwner(IUnknown *);
|
||||
|
Loading…
Reference in New Issue
Block a user