Fixed issue #2507: Support keyboard shortcuts in yes/no prompts
[TortoiseGit.git] / src / Utils / MiscUI / IconMenu.cpp
blob0763283df4b00ff0b19554a6256f95b699fc4163
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2010-2011, 2013 - TortoiseGit
4 // Copyright (C) 2008-2009, 2011 - TortoiseSVN
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software Foundation,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "stdafx.h"
21 #include "IconMenu.h"
22 #include "SysInfo.h"
23 #include "registry.h"
25 CIconMenu::CIconMenu(void) : CMenu()
27 bShowIcons = !!DWORD(CRegDWORD(_T("Software\\TortoiseGit\\ShowAppContextMenuIcons"), TRUE));
30 CIconMenu::~CIconMenu(void)
32 for (auto it = iconhandles.cbegin(); it != iconhandles.cend(); ++it)
33 DestroyIcon(it->second);
36 BOOL CIconMenu::CreateMenu()
38 if (__super::CreateMenu() == FALSE)
39 return FALSE;
41 SetMenuStyle();
43 return TRUE;
46 BOOL CIconMenu::CreatePopupMenu()
48 if (__super::CreatePopupMenu() == FALSE)
49 return FALSE;
51 SetMenuStyle();
53 return TRUE;
56 BOOL CIconMenu::SetMenuStyle(void)
58 if (!SysInfo::Instance().IsVistaOrLater())
59 return FALSE;
61 MENUINFO MenuInfo;
63 memset(&MenuInfo, 0, sizeof(MenuInfo));
65 MenuInfo.cbSize = sizeof(MenuInfo);
66 MenuInfo.fMask = MIM_STYLE | MIM_APPLYTOSUBMENUS;
67 MenuInfo.dwStyle = MNS_CHECKORBMP;
69 SetMenuInfo(&MenuInfo);
71 return TRUE;
74 BOOL CIconMenu::AppendMenuIcon(UINT_PTR nIDNewItem, LPCTSTR lpszNewItem, UINT uIcon /* = 0 */, HMENU hsubmenu /* = 0 */)
76 TCHAR menutextbuffer[255] = {0};
77 _tcscpy_s(menutextbuffer, lpszNewItem);
79 MENUITEMINFO info = {0};
80 info.cbSize = sizeof(info);
81 info.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID;
82 info.fType = MFT_STRING;
84 if (hsubmenu)
86 info.fMask |= MIIM_SUBMENU;
87 info.hSubMenu = hsubmenu;
90 info.wID = (UINT)nIDNewItem;
91 info.dwTypeData = menutextbuffer;
92 if ((uIcon != 0) && bShowIcons)
94 info.fMask |= MIIM_BITMAP;
95 if (SysInfo::Instance().IsVistaOrLater())
96 info.hbmpItem = bitmapUtils.IconToBitmapPARGB32(AfxGetResourceHandle(), uIcon);
97 else
98 info.hbmpItem = HBMMENU_CALLBACK;
100 icons[nIDNewItem] = uIcon;
103 return InsertMenuItem((UINT)nIDNewItem, &info);
106 BOOL CIconMenu::AppendMenuIcon(UINT_PTR nIDNewItem, UINT_PTR nNewItem, UINT uIcon /* = 0 */, HMENU hsubmenu /* = 0 */)
108 CString temp;
109 temp.LoadString((UINT)nNewItem);
111 return AppendMenuIcon(nIDNewItem, temp, uIcon, hsubmenu);
114 void CIconMenu::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
116 if ((lpDrawItemStruct==NULL)||(lpDrawItemStruct->CtlType != ODT_MENU))
117 return; //not for a menu
118 HICON hIcon = NULL;
119 bool bDestroyIcon = true;
120 if (iconhandles.find(lpDrawItemStruct->itemID) != iconhandles.end())
122 hIcon = iconhandles[lpDrawItemStruct->itemID];
123 bDestroyIcon = false;
125 else
126 hIcon = (HICON)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(icons[lpDrawItemStruct->itemID]), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
127 if (hIcon == NULL)
128 return;
129 DrawIconEx(lpDrawItemStruct->hDC,
130 lpDrawItemStruct->rcItem.left - 16,
131 lpDrawItemStruct->rcItem.top + (lpDrawItemStruct->rcItem.bottom - lpDrawItemStruct->rcItem.top - 16) / 2,
132 hIcon, 16, 16,
133 0, NULL, DI_NORMAL);
134 if (bDestroyIcon)
135 DestroyIcon(hIcon);
138 void CIconMenu::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
140 if (lpMeasureItemStruct==NULL)
141 return;
142 lpMeasureItemStruct->itemWidth += 2;
143 if (lpMeasureItemStruct->itemHeight < 16)
144 lpMeasureItemStruct->itemHeight = 16;
147 BOOL CIconMenu::SetMenuItemData(UINT_PTR nIDNewItem, LONG_PTR data)
150 MENUITEMINFO menuinfo ={0};
151 menuinfo.cbSize = sizeof(menuinfo);
152 GetMenuItemInfo((UINT)nIDNewItem, &menuinfo);
153 menuinfo.dwItemData =data;
154 menuinfo.fMask |= MIIM_DATA;
155 return SetMenuItemInfo((UINT)nIDNewItem ,&menuinfo);
159 LONG_PTR CIconMenu::GetMenuItemData(UINT_PTR nIDNewItem)
161 MENUITEMINFO menuinfo ={0};
162 menuinfo.fMask |= MIIM_DATA;
163 menuinfo.cbSize = sizeof(menuinfo);
164 GetMenuItemInfo((UINT)nIDNewItem, &menuinfo);
166 return menuinfo.dwItemData;