123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- #include "./menushortcuts.h"
- #include <strsafe.h>
- // change key string to capitalised only so it's more UI consistant (otherwise messes up the localisation look)
- wchar_t* CapitaliseKeyName(wchar_t* szAccelName){
- if(szAccelName) {
- wchar_t *p = &szAccelName[1];
- int space = 0;
- while(p && *p){
- if(*p == L' ') space = 1;
- else {
- if(!space) {
- *p = tolower(*p);
- }
- else {
- space = 0;
- }
- }
- p = CharNextW(p);
- }
- }
- return szAccelName;
- }
- BOOL AppendShortcutTextEx(LPWSTR pszItemText, INT cchTextMax, WORD wID, ACCEL *pszAccel, INT cchAccel, UINT uMode)
- {
- BOOL bDirty = FALSE;
- if (!pszItemText) return FALSE;
- UINT cchLen = lstrlenW(pszItemText);
- if (MSF_REPLACE == (0x0F & uMode))
- {
- UINT len;
- for (len = 0; len < cchLen && L'\t' != pszItemText[len]; len++);
- if (cchLen != len)
- {
- cchLen = len;
- pszItemText[len] = L'\0';
- bDirty = TRUE;
- }
- }
- if (wID > 0)
- {
- wchar_t szAccelName[64] = {0};
- BOOL bFirst = TRUE;
- pszItemText += cchLen;
- size_t cchText = cchTextMax - cchLen;
- for(int k = 0; k < cchAccel; k++)
- {
- if (wID == pszAccel[k].cmd)
- {
- HRESULT hr = StringCchCopyExW(pszItemText, cchText, ((bFirst) ? L"\t" : L", "), &pszItemText, &cchText, STRSAFE_IGNORE_NULLS);
- if (S_OK == hr && (FCONTROL & pszAccel[k].fVirt)) {
- GetKeyNameTextW(MapVirtualKey(VK_CONTROL, 0)<<16, szAccelName, sizeof(szAccelName)/sizeof(szAccelName[0]));
- hr = StringCchCopyExW(pszItemText, cchText, CapitaliseKeyName(szAccelName), &pszItemText, &cchText, STRSAFE_IGNORE_NULLS);
- if(S_OK == hr) StringCchCatExW(pszItemText, cchText, L"+", &pszItemText, &cchText, STRSAFE_IGNORE_NULLS);
- }
- if (S_OK == hr && (FALT & pszAccel[k].fVirt)) {
- GetKeyNameTextW(MapVirtualKey(VK_MENU, 0)<<16, szAccelName, sizeof(szAccelName)/sizeof(szAccelName[0]));
- hr = StringCchCopyExW(pszItemText, cchText, CapitaliseKeyName(szAccelName), &pszItemText, &cchText, STRSAFE_IGNORE_NULLS);
- if(S_OK == hr) hr = StringCchCatExW(pszItemText, cchText, L"+", &pszItemText, &cchText, STRSAFE_IGNORE_NULLS);
- }
- if (S_OK == hr && (FSHIFT & pszAccel[k].fVirt)) {
- GetKeyNameTextW(MapVirtualKey(VK_SHIFT, 0)<<16, szAccelName, sizeof(szAccelName)/sizeof(szAccelName[0]));
- hr = StringCchCopyExW(pszItemText, cchText, CapitaliseKeyName(szAccelName), &pszItemText, &cchText, STRSAFE_IGNORE_NULLS);
- if(S_OK == hr) hr = StringCchCatExW(pszItemText, cchText, L"+", &pszItemText, &cchText, STRSAFE_IGNORE_NULLS);
- }
- if (S_OK == hr)
- {
- if (FVIRTKEY & pszAccel[k].fVirt)
- {
- szAccelName[0] = L'\0';
- UINT vkey = MapVirtualKey(pszAccel[k].key, 0);
- /* benski> this removes "NUM" from the descriptions of certain characters */
- switch(pszAccel[k].key)
- {
- case VK_INSERT:
- case VK_DELETE:
- case VK_HOME:
- case VK_END:
- case VK_NEXT: // Page down
- case VK_PRIOR: // Page up
- case VK_LEFT:
- case VK_RIGHT:
- case VK_UP:
- case VK_DOWN:
- vkey |= 0x100; // Add extended bit
- }
- vkey<<=16;
- if (GetKeyNameTextW(vkey, szAccelName, sizeof(szAccelName)/sizeof(szAccelName[0]))) {
- hr = StringCchCopyExW(pszItemText, cchText, CapitaliseKeyName(szAccelName), &pszItemText, &cchText, STRSAFE_IGNORE_NULLS);
- }
- }
- else if (cchText > 1)
- {
- pszItemText[0] = (wchar_t)pszAccel[k].key;
- pszItemText[1] = L'\0';
- pszItemText += 2;
- cchText -= 2;
- }
- }
- bFirst = FALSE;
- bDirty = (S_OK == hr);
- }
- }
- }
- return bDirty;
- }
- BOOL AppendMenuShortcutsEx(HMENU hMenu, ACCEL *pszAccel, INT cchAccel, UINT uMode)
- {
- wchar_t szText[4096] = {0};
- if (!hMenu) return FALSE;
- MENUITEMINFOW mii = { sizeof(MENUITEMINFOW), };
- INT c = GetMenuItemCount(hMenu);
- if (0 == c || -1 == c) return TRUE;
- for (int i = 0; i < c; i++)
- {
- mii.fMask = MIIM_ID | MIIM_STRING | MIIM_FTYPE | MIIM_SUBMENU;
- mii.cch = sizeof(szText)/sizeof(szText[0]);
- mii.dwTypeData = szText;
-
- if (GetMenuItemInfoW(hMenu, i, TRUE, &mii) &&
- 0 == ((MFT_SEPARATOR | MFT_MENUBREAK |MFT_MENUBARBREAK) & mii.fType))
- {
- if (AppendShortcutTextEx(mii.dwTypeData, sizeof(szText)/sizeof(szText[0]), (WORD)mii.wID, pszAccel, cchAccel, uMode))
- {
- mii.fMask = MIIM_STRING;
- SetMenuItemInfoW(hMenu, i, TRUE, &mii);
- }
- if (NULL != mii.hSubMenu && (MSF_WALKSUBMENU & uMode))
- {
- AppendMenuShortcutsEx(mii.hSubMenu, pszAccel, cchAccel, uMode);
- }
- }
- }
- return TRUE;
- }
- BOOL AppendMenuShortcuts(HMENU hMenu, HACCEL *phAccel, INT count, UINT uMode)
- {
- ACCEL *pszAccel = NULL;
- INT c = 0;
- if (!hMenu) return FALSE;
- if (phAccel)
- {
- for (int i = 0; i < count; i++)
- {
- c += CopyAcceleratorTable(phAccel[i], NULL, 0);
- }
- if (c)
- {
- pszAccel = (ACCEL*)calloc(c, sizeof(ACCEL));
- if (!pszAccel) return FALSE;
- }
- int k = 0;
- for (int i = 0; i < count; i++)
- {
- k += CopyAcceleratorTable(phAccel[i], &pszAccel[k], c - k);
- }
- }
- BOOL r = AppendMenuShortcutsEx(hMenu, pszAccel, c, uMode);
- if (pszAccel) free(pszAccel);
- return r;
- }
- BOOL AppendShortcutText(LPWSTR pszItemText, INT cchTextMax, WORD wID, HACCEL *phAccel, INT count, UINT uMode)
- {
- ACCEL *pszAccel = NULL;
- INT c = 0;
- if (!pszItemText) return FALSE;
- if (phAccel)
- {
- for (int i = 0; i < count; i++)
- {
- c += CopyAcceleratorTable(phAccel[i], NULL, 0);
- }
- if (c)
- {
- pszAccel = (ACCEL*)calloc(c, sizeof(ACCEL));
- if (!pszAccel) return FALSE;
- }
- int k = 0;
- for (int i = 0; i < count; i++)
- {
- k += CopyAcceleratorTable(phAccel[i], &pszAccel[k], c - k);
- }
- }
- BOOL r = AppendShortcutTextEx(pszItemText, cchTextMax, wID, pszAccel, c, uMode);
- if (pszAccel) free(pszAccel);
- return r;
- }
|