mirror of
https://github.com/reactos/reactos.git
synced 2025-05-23 02:56:09 +00:00
[SHELL32]
- Implement IContextMenu3 interface. Implement drawing the icons on WM_DRAWITEM. CORE-8866 svn path=/trunk/; revision=67009
This commit is contained in:
parent
22c2b66b34
commit
b1a175cbfa
2 changed files with 81 additions and 63 deletions
|
@ -30,17 +30,14 @@ CNewMenu::CNewMenu()
|
||||||
m_pItems = NULL;
|
m_pItems = NULL;
|
||||||
m_pLinkItem = NULL;
|
m_pLinkItem = NULL;
|
||||||
m_pSite = NULL;
|
m_pSite = NULL;
|
||||||
m_hbmFolder = NULL;
|
m_hiconFolder = NULL;
|
||||||
m_hbmLink = NULL;
|
m_hiconLink = NULL;
|
||||||
|
m_idCmdFirst = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
CNewMenu::~CNewMenu()
|
CNewMenu::~CNewMenu()
|
||||||
{
|
{
|
||||||
UnloadAllItems();
|
UnloadAllItems();
|
||||||
if (m_hbmFolder)
|
|
||||||
DeleteObject(m_hbmFolder);
|
|
||||||
if (m_hbmLink)
|
|
||||||
DeleteObject(m_hbmLink);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CNewMenu::UnloadItem(SHELLNEW_ITEM *pItem)
|
void CNewMenu::UnloadItem(SHELLNEW_ITEM *pItem)
|
||||||
|
@ -50,8 +47,8 @@ void CNewMenu::UnloadItem(SHELLNEW_ITEM *pItem)
|
||||||
free(pItem->pwszDesc);
|
free(pItem->pwszDesc);
|
||||||
free(pItem->pwszExt);
|
free(pItem->pwszExt);
|
||||||
|
|
||||||
if (pItem->hBitmap)
|
if (pItem->hIcon)
|
||||||
DeleteObject(pItem->hBitmap);
|
DestroyIcon(pItem->hIcon);
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(), 0, pItem);
|
HeapFree(GetProcessHeap(), 0, pItem);
|
||||||
}
|
}
|
||||||
|
@ -75,29 +72,6 @@ void CNewMenu::UnloadAllItems()
|
||||||
m_pLinkItem = NULL;
|
m_pLinkItem = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HBITMAP IconToBitmap(HICON hIcon)
|
|
||||||
{
|
|
||||||
HDC hdc, hdcScr;
|
|
||||||
HBITMAP hbm, hbmOld;
|
|
||||||
RECT rc;
|
|
||||||
|
|
||||||
hdcScr = GetDC(NULL);
|
|
||||||
hdc = CreateCompatibleDC(hdcScr);
|
|
||||||
SetRect(&rc, 0, 0, GetSystemMetrics(SM_CXMENUCHECK), GetSystemMetrics(SM_CYMENUCHECK));
|
|
||||||
hbm = CreateCompatibleBitmap(hdcScr, rc.right, rc.bottom);
|
|
||||||
ReleaseDC(NULL, hdcScr);
|
|
||||||
|
|
||||||
hbmOld = (HBITMAP)SelectObject(hdc, hbm);
|
|
||||||
FillRect(hdc, &rc, (HBRUSH)(COLOR_MENU + 1));
|
|
||||||
if (!DrawIconEx(hdc, 0, 0, hIcon, rc.right, rc.bottom, 0, NULL, DI_NORMAL))
|
|
||||||
ERR("DrawIcon failed: %x\n", GetLastError());
|
|
||||||
SelectObject(hdc, hbmOld);
|
|
||||||
|
|
||||||
DeleteDC(hdc);
|
|
||||||
|
|
||||||
return hbm;
|
|
||||||
}
|
|
||||||
|
|
||||||
CNewMenu::SHELLNEW_ITEM *CNewMenu::LoadItem(LPCWSTR pwszExt)
|
CNewMenu::SHELLNEW_ITEM *CNewMenu::LoadItem(LPCWSTR pwszExt)
|
||||||
{
|
{
|
||||||
HKEY hKey;
|
HKEY hKey;
|
||||||
|
@ -179,10 +153,7 @@ CNewMenu::SHELLNEW_ITEM *CNewMenu::LoadItem(LPCWSTR pwszExt)
|
||||||
pNewItem->pwszExt = _wcsdup(pwszExt);
|
pNewItem->pwszExt = _wcsdup(pwszExt);
|
||||||
pNewItem->pwszDesc = _wcsdup(fi.szTypeName);
|
pNewItem->pwszDesc = _wcsdup(fi.szTypeName);
|
||||||
if (fi.hIcon)
|
if (fi.hIcon)
|
||||||
{
|
pNewItem->hIcon = fi.hIcon;
|
||||||
pNewItem->hBitmap = IconToBitmap(fi.hIcon);
|
|
||||||
DestroyIcon(fi.hIcon);
|
|
||||||
}
|
|
||||||
|
|
||||||
return pNewItem;
|
return pNewItem;
|
||||||
}
|
}
|
||||||
|
@ -262,16 +233,11 @@ CNewMenu::InsertShellNewItems(HMENU hMenu, UINT idCmdFirst, UINT Pos)
|
||||||
/* Insert new folder action */
|
/* Insert new folder action */
|
||||||
if (!LoadStringW(shell32_hInstance, FCIDM_SHVIEW_NEWFOLDER, wszBuf, _countof(wszBuf)))
|
if (!LoadStringW(shell32_hInstance, FCIDM_SHVIEW_NEWFOLDER, wszBuf, _countof(wszBuf)))
|
||||||
wszBuf[0] = 0;
|
wszBuf[0] = 0;
|
||||||
mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE | MIIM_DATA;
|
mii.fMask = MIIM_ID | MIIM_BITMAP | MIIM_STRING;
|
||||||
mii.fType = MFT_STRING;
|
|
||||||
mii.dwTypeData = wszBuf;
|
mii.dwTypeData = wszBuf;
|
||||||
mii.cch = wcslen(mii.dwTypeData);
|
mii.cch = wcslen(mii.dwTypeData);
|
||||||
mii.wID = idCmd;
|
mii.wID = idCmd;
|
||||||
if (m_hbmFolder)
|
mii.hbmpItem = HBMMENU_CALLBACK;
|
||||||
{
|
|
||||||
mii.fMask |= MIIM_CHECKMARKS;
|
|
||||||
mii.hbmpChecked = mii.hbmpUnchecked = m_hbmFolder;
|
|
||||||
}
|
|
||||||
if (InsertMenuItemW(hMenu, Pos++, TRUE, &mii))
|
if (InsertMenuItemW(hMenu, Pos++, TRUE, &mii))
|
||||||
++idCmd;
|
++idCmd;
|
||||||
|
|
||||||
|
@ -281,11 +247,6 @@ CNewMenu::InsertShellNewItems(HMENU hMenu, UINT idCmdFirst, UINT Pos)
|
||||||
mii.dwTypeData = wszBuf;
|
mii.dwTypeData = wszBuf;
|
||||||
mii.cch = wcslen(mii.dwTypeData);
|
mii.cch = wcslen(mii.dwTypeData);
|
||||||
mii.wID = idCmd;
|
mii.wID = idCmd;
|
||||||
if (m_hbmLink)
|
|
||||||
{
|
|
||||||
mii.fMask |= MIIM_CHECKMARKS;
|
|
||||||
mii.hbmpChecked = mii.hbmpUnchecked = m_hbmLink;
|
|
||||||
}
|
|
||||||
if (InsertMenuItemW(hMenu, Pos++, TRUE, &mii))
|
if (InsertMenuItemW(hMenu, Pos++, TRUE, &mii))
|
||||||
++idCmd;
|
++idCmd;
|
||||||
|
|
||||||
|
@ -296,22 +257,16 @@ CNewMenu::InsertShellNewItems(HMENU hMenu, UINT idCmdFirst, UINT Pos)
|
||||||
InsertMenuItemW(hMenu, Pos++, TRUE, &mii);
|
InsertMenuItemW(hMenu, Pos++, TRUE, &mii);
|
||||||
|
|
||||||
/* Insert rest of items */
|
/* Insert rest of items */
|
||||||
mii.fType = MFT_STRING;
|
mii.fMask = MIIM_ID | MIIM_BITMAP | MIIM_STRING;
|
||||||
mii.fState = MFS_ENABLED;
|
mii.fType = 0;
|
||||||
|
|
||||||
SHELLNEW_ITEM *pCurItem = m_pItems;
|
SHELLNEW_ITEM *pCurItem = m_pItems;
|
||||||
while (pCurItem)
|
while (pCurItem)
|
||||||
{
|
{
|
||||||
TRACE("szDesc %s\n", debugstr_w(pCurItem->pwszDesc));
|
TRACE("szDesc %s\n", debugstr_w(pCurItem->pwszDesc));
|
||||||
mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE | MIIM_DATA;
|
|
||||||
mii.dwTypeData = pCurItem->pwszDesc;
|
mii.dwTypeData = pCurItem->pwszDesc;
|
||||||
mii.cch = wcslen(mii.dwTypeData);
|
mii.cch = wcslen(mii.dwTypeData);
|
||||||
mii.wID = idCmd;
|
mii.wID = idCmd;
|
||||||
if (pCurItem->hBitmap)
|
|
||||||
{
|
|
||||||
mii.fMask |= MIIM_CHECKMARKS;
|
|
||||||
mii.hbmpChecked = mii.hbmpUnchecked = pCurItem->hBitmap;
|
|
||||||
}
|
|
||||||
if (InsertMenuItemW(hMenu, Pos++, TRUE, &mii))
|
if (InsertMenuItemW(hMenu, Pos++, TRUE, &mii))
|
||||||
++idCmd;
|
++idCmd;
|
||||||
pCurItem = pCurItem->pNext;
|
pCurItem = pCurItem->pNext;
|
||||||
|
@ -562,6 +517,8 @@ CNewMenu::QueryContextMenu(HMENU hMenu,
|
||||||
MENUITEMINFOW mii;
|
MENUITEMINFOW mii;
|
||||||
UINT cItems = 0;
|
UINT cItems = 0;
|
||||||
|
|
||||||
|
m_idCmdFirst = idCmdFirst;
|
||||||
|
|
||||||
TRACE("%p %p %u %u %u %u\n", this,
|
TRACE("%p %p %u %u %u %u\n", this,
|
||||||
hMenu, indexMenu, idCmdFirst, idCmdLast, uFlags);
|
hMenu, indexMenu, idCmdFirst, idCmdLast, uFlags);
|
||||||
|
|
||||||
|
@ -637,15 +594,71 @@ CNewMenu::HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
WINAPI
|
||||||
|
CNewMenu::HandleMenuMsg2(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *plResult)
|
||||||
|
{
|
||||||
|
switch (uMsg)
|
||||||
|
{
|
||||||
|
case WM_MEASUREITEM:
|
||||||
|
{
|
||||||
|
MEASUREITEMSTRUCT* lpmis = reinterpret_cast<MEASUREITEMSTRUCT*>(lParam);
|
||||||
|
if (!lpmis || lpmis->CtlType != ODT_MENU)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (lpmis->itemWidth < (UINT)GetSystemMetrics(SM_CXMENUCHECK))
|
||||||
|
lpmis->itemWidth = GetSystemMetrics(SM_CXMENUCHECK);
|
||||||
|
if (lpmis->itemHeight < 16)
|
||||||
|
lpmis->itemHeight = 16;
|
||||||
|
|
||||||
|
if (plResult)
|
||||||
|
*plResult = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WM_DRAWITEM:
|
||||||
|
{
|
||||||
|
DRAWITEMSTRUCT* lpdis = reinterpret_cast<DRAWITEMSTRUCT*>(lParam);
|
||||||
|
if (!lpdis || lpdis->CtlType != ODT_MENU)
|
||||||
|
break;
|
||||||
|
|
||||||
|
DWORD id = LOWORD(lpdis->itemID) - m_idCmdFirst;
|
||||||
|
HICON hIcon = 0;
|
||||||
|
if (id == 0)
|
||||||
|
hIcon = m_hiconFolder;
|
||||||
|
else if (id == 1)
|
||||||
|
hIcon = m_hiconLink;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHELLNEW_ITEM *pItem = FindItemFromIdOffset(id);
|
||||||
|
if (pItem)
|
||||||
|
hIcon = pItem->hIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hIcon)
|
||||||
|
break;
|
||||||
|
|
||||||
|
DrawIconEx(lpdis->hDC,
|
||||||
|
2,
|
||||||
|
lpdis->rcItem.top + (lpdis->rcItem.bottom - lpdis->rcItem.top - 16) / 2,
|
||||||
|
hIcon,
|
||||||
|
16,
|
||||||
|
16,
|
||||||
|
0, NULL, DI_NORMAL);
|
||||||
|
|
||||||
|
if(plResult)
|
||||||
|
*plResult = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT WINAPI
|
HRESULT WINAPI
|
||||||
CNewMenu::Initialize(LPCITEMIDLIST pidlFolder,
|
CNewMenu::Initialize(LPCITEMIDLIST pidlFolder,
|
||||||
IDataObject *pdtobj, HKEY hkeyProgID)
|
IDataObject *pdtobj, HKEY hkeyProgID)
|
||||||
{
|
{
|
||||||
/* Load folder and shortcut icons */
|
/* Load folder and shortcut icons */
|
||||||
HICON hIcon = (HICON)LoadImage(shell32_hInstance, MAKEINTRESOURCE(IDI_SHELL_FOLDER), IMAGE_ICON, 0, 0, LR_SHARED);
|
m_hiconFolder = (HICON)LoadImage(shell32_hInstance, MAKEINTRESOURCE(IDI_SHELL_FOLDER), IMAGE_ICON, 16, 16, LR_SHARED);
|
||||||
m_hbmFolder = hIcon ? IconToBitmap(hIcon) : NULL;
|
m_hiconLink = (HICON)LoadImage(shell32_hInstance, MAKEINTRESOURCE(IDI_SHELL_SHORTCUT), IMAGE_ICON, 16, 16, LR_SHARED);
|
||||||
hIcon = (HICON)LoadImage(shell32_hInstance, MAKEINTRESOURCE(IDI_SHELL_SHORTCUT), IMAGE_ICON, 0, 0, LR_SHARED);
|
|
||||||
m_hbmLink = hIcon ? IconToBitmap(hIcon) : NULL;
|
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ class CNewMenu :
|
||||||
public CComCoClass<CNewMenu, &CLSID_NewMenu>,
|
public CComCoClass<CNewMenu, &CLSID_NewMenu>,
|
||||||
public CComObjectRootEx<CComMultiThreadModelNoCS>,
|
public CComObjectRootEx<CComMultiThreadModelNoCS>,
|
||||||
public IObjectWithSite,
|
public IObjectWithSite,
|
||||||
public IContextMenu2,
|
public IContextMenu3,
|
||||||
public IShellExtInit
|
public IShellExtInit
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
@ -47,7 +47,7 @@ private:
|
||||||
PBYTE pData;
|
PBYTE pData;
|
||||||
ULONG cbData;
|
ULONG cbData;
|
||||||
LPWSTR pwszDesc;
|
LPWSTR pwszDesc;
|
||||||
HBITMAP hBitmap;
|
HICON hIcon;
|
||||||
SHELLNEW_ITEM *pNext;
|
SHELLNEW_ITEM *pNext;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -56,7 +56,8 @@ private:
|
||||||
SHELLNEW_ITEM *m_pLinkItem;
|
SHELLNEW_ITEM *m_pLinkItem;
|
||||||
CComPtr<IUnknown> m_pSite;
|
CComPtr<IUnknown> m_pSite;
|
||||||
HMENU m_hSubMenu;
|
HMENU m_hSubMenu;
|
||||||
HBITMAP m_hbmFolder, m_hbmLink;
|
HICON m_hiconFolder, m_hiconLink;
|
||||||
|
UINT m_idCmdFirst;
|
||||||
|
|
||||||
SHELLNEW_ITEM *LoadItem(LPCWSTR pwszExt);
|
SHELLNEW_ITEM *LoadItem(LPCWSTR pwszExt);
|
||||||
void UnloadItem(SHELLNEW_ITEM *pItem);
|
void UnloadItem(SHELLNEW_ITEM *pItem);
|
||||||
|
@ -80,6 +81,9 @@ public:
|
||||||
virtual HRESULT WINAPI InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi);
|
virtual HRESULT WINAPI InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi);
|
||||||
virtual HRESULT WINAPI GetCommandString(UINT_PTR idCommand, UINT uFlags, UINT *lpReserved, LPSTR lpszName, UINT uMaxNameLen);
|
virtual HRESULT WINAPI GetCommandString(UINT_PTR idCommand, UINT uFlags, UINT *lpReserved, LPSTR lpszName, UINT uMaxNameLen);
|
||||||
|
|
||||||
|
// IContextMenu3
|
||||||
|
virtual HRESULT WINAPI HandleMenuMsg2(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *plResult);
|
||||||
|
|
||||||
// IContextMenu2
|
// IContextMenu2
|
||||||
virtual HRESULT WINAPI HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam);
|
virtual HRESULT WINAPI HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
|
@ -93,6 +97,7 @@ DECLARE_PROTECT_FINAL_CONSTRUCT()
|
||||||
|
|
||||||
BEGIN_COM_MAP(CNewMenu)
|
BEGIN_COM_MAP(CNewMenu)
|
||||||
COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite)
|
COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite)
|
||||||
|
COM_INTERFACE_ENTRY_IID(IID_IContextMenu3, IContextMenu3)
|
||||||
COM_INTERFACE_ENTRY_IID(IID_IContextMenu2, IContextMenu2)
|
COM_INTERFACE_ENTRY_IID(IID_IContextMenu2, IContextMenu2)
|
||||||
COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
|
COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
|
||||||
COM_INTERFACE_ENTRY_IID(IID_IShellExtInit, IShellExtInit)
|
COM_INTERFACE_ENTRY_IID(IID_IShellExtInit, IShellExtInit)
|
||||||
|
|
Loading…
Reference in a new issue