Mercurial > vba-clojure
view src/win32/AcceleratorManager.cpp @ 8:08a8e09ca414
add files required by automake
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:54:39 -0600 |
parents | f9f4f1b99eed |
children |
line wrap: on
line source
1 ////////////////////////////////////////////////////////////////////////////////2 // Copyright (C) 1998 by Thierry Maurel3 // All rights reserved4 //5 // Distribute freely, except: don't remove my name from the source or6 // documentation (don't take credit for my work), mark your changes (don't7 // get me blamed for your possible bugs), don't alter or remove this8 // notice.9 // No warrantee of any kind, express or implied, is included with this10 // software; use at your own risk, responsibility for damages (if any) to11 // anyone resulting from the use of this software rests entirely with the12 // user.13 //14 // Send bug reports, bug fixes, enhancements, requests, flames, etc., and15 // I'll try to keep a version up to date. I can be reached as follows:16 // tmaurel@caramail.com (or tmaurel@hol.fr)17 //18 ////////////////////////////////////////////////////////////////////////////////19 // File : AcceleratorManager.cpp20 // Project : AccelsEditor21 ////////////////////////////////////////////////////////////////////////////////22 // Version : 1.0 * Author : T.Maurel23 // Date : 17.08.9824 //25 // Remarks : implementation of the CAcceleratorManager class.26 //27 ////////////////////////////////////////////////////////////////////////////////28 // Modified by aquanull:29 // All win32 registry stuff removed31 #include "stdafx.h"32 #include <windows.h> // MIIM_STRING33 #include "resource.h"34 #include "AcceleratorManager.h"35 #include "CmdAccelOb.h"36 #include "Reg.h"37 #include "VBA.h"38 //#include "../common/System.h"40 CAcceleratorManager::CAcceleratorManager()41 {42 m_bAutoSave = FALSE;43 m_pWndConnected = NULL;45 m_bDefaultTable = false;46 }48 CAcceleratorManager::~CAcceleratorManager()49 {50 #if 051 if (m_bAutoSave)52 {53 bool bRet = Write();54 if (!bRet)55 systemMessage(0, "CAcceleratorManager::~CAcceleratorManager\nError in CAcceleratorManager::Write...");56 }57 #endif58 Reset();59 }61 CAcceleratorManager & CAcceleratorManager::operator=(const CAcceleratorManager& accelmgr)62 {63 Reset();65 CCmdAccelOb*pCmdAccel;66 CCmdAccelOb*pNewCmdAccel;67 WORD wKey;68 // Copy the 2 tables : normal accel table...69 POSITION pos = accelmgr.m_mapAccelTable.GetStartPosition();70 while (pos != NULL)71 {72 accelmgr.m_mapAccelTable.GetNextAssoc(pos, wKey, pCmdAccel);73 pNewCmdAccel = new CCmdAccelOb;74 ASSERT(pNewCmdAccel != NULL);75 *pNewCmdAccel = *pCmdAccel;76 m_mapAccelTable.SetAt(wKey, pNewCmdAccel);77 }78 // ... and saved accel table.79 pos = accelmgr.m_mapAccelTableSaved.GetStartPosition();80 while (pos != NULL)81 {82 accelmgr.m_mapAccelTableSaved.GetNextAssoc(pos, wKey, pCmdAccel);83 pNewCmdAccel = new CCmdAccelOb;84 ASSERT(pNewCmdAccel != NULL);85 *pNewCmdAccel = *pCmdAccel;86 m_mapAccelTableSaved.SetAt(wKey, pNewCmdAccel);87 }89 // The Strings-ID table90 CString szKey;91 pos = accelmgr.m_mapAccelString.GetStartPosition();92 while (pos != NULL)93 {94 accelmgr.m_mapAccelString.GetNextAssoc(pos, szKey, wKey);95 m_mapAccelString.SetAt(szKey, wKey);96 }97 m_bDefaultTable = accelmgr.m_bDefaultTable;99 return *this;100 }102 //////////////////////////////////////////////////////////////////////103 // Internal fcts104 //105 void CAcceleratorManager::Reset()106 {107 CCmdAccelOb*pCmdAccel;108 WORD wKey;109 POSITION pos = m_mapAccelTable.GetStartPosition();110 while (pos != NULL)111 {112 m_mapAccelTable.GetNextAssoc(pos, wKey, pCmdAccel);113 delete pCmdAccel;114 }115 m_mapAccelTable.RemoveAll();116 m_mapAccelString.RemoveAll();118 pos = m_mapAccelTableSaved.GetStartPosition();119 while (pos != NULL)120 {121 m_mapAccelTableSaved.GetNextAssoc(pos, wKey, pCmdAccel);122 delete pCmdAccel;123 }124 m_mapAccelTableSaved.RemoveAll();125 }127 bool CAcceleratorManager::AddAccel(BYTE cVirt, WORD wIDCommand, WORD wKey, LPCTSTR szCommand, bool bLocked)128 {129 ASSERT(szCommand != NULL);131 WORD wIDCmd;132 if (m_mapAccelString.Lookup(szCommand, wIDCmd) == TRUE)133 {134 if (wIDCmd != wIDCommand)135 return false;136 }138 CCmdAccelOb*pCmdAccel = NULL;139 if (m_mapAccelTable.Lookup(wIDCommand, pCmdAccel) == TRUE)140 {141 if (pCmdAccel->m_szCommand != szCommand)142 {143 return false;144 }145 CAccelsOb*pAccel;146 POSITION pos = pCmdAccel->m_Accels.GetHeadPosition();147 while (pos != NULL)148 {149 pAccel = pCmdAccel->m_Accels.GetNext(pos);150 if (pAccel->m_cVirt == cVirt &&151 pAccel->m_wKey == wKey)152 return FALSE;153 }154 // Adding the accelerator155 pCmdAccel->Add(cVirt, wKey, bLocked);156 }157 else158 {159 pCmdAccel = new CCmdAccelOb(cVirt, wIDCommand, wKey, szCommand, bLocked);160 ASSERT(pCmdAccel != NULL);161 m_mapAccelTable.SetAt(wIDCommand, pCmdAccel);162 }163 // 2nd table164 m_mapAccelString.SetAt(szCommand, wIDCommand);165 return true;166 }168 //////////////////////////////////////////////////////////////////////169 // Debug fcts170 //171 #ifdef _DEBUG172 void CAcceleratorManager::AssertValid() const173 {}175 void CAcceleratorManager::Dump(CDumpContext& dc) const176 {177 CCmdAccelOb*pCmdAccel;178 WORD wKey;179 dc << "CAcceleratorManager::Dump :\n";180 dc << "m_mapAccelTable :\n";181 POSITION pos = m_mapAccelTable.GetStartPosition();182 while (pos != NULL)183 {184 m_mapAccelTable.GetNextAssoc(pos, wKey, pCmdAccel);185 dc << "a CCmdAccelOb at 0x" << (void *)pCmdAccel << " = {\n";186 dc << pCmdAccel;187 dc << "}\n";188 }189 dc << "\nm_mapAccelTableSaved\n";190 pos = m_mapAccelTableSaved.GetStartPosition();191 while (pos != NULL)192 {193 m_mapAccelTableSaved.GetNextAssoc(pos, wKey, pCmdAccel);194 dc << "a CCmdAccelOb at 0x" << (void *)pCmdAccel << " = {\n";195 dc << pCmdAccel;196 dc << "}\n";197 }198 }200 #endif202 void CAcceleratorManager::Connect(CWnd*pWnd, bool bAutoSave)203 {204 ASSERT(m_pWndConnected == NULL);205 m_pWndConnected = pWnd;206 m_bAutoSave = bAutoSave;207 }209 //////////////////////////////////////////////////////////////////////210 // Update the application's ACCELs table211 //212 bool CAcceleratorManager::UpdateWndTable()213 {214 int iLoop = 0;215 CTypedPtrArray<CPtrArray, LPACCEL> arrayACCEL;217 CCmdAccelOb*pCmdAccel;218 WORD wKey;219 LPACCEL pACCEL;220 CAccelsOb* pAccelOb;221 POSITION pos = m_mapAccelTable.GetStartPosition();222 while (pos != NULL)223 {224 m_mapAccelTable.GetNextAssoc(pos, wKey, pCmdAccel);225 POSITION pos = pCmdAccel->m_Accels.GetHeadPosition();226 while (pos != NULL)227 {228 pAccelOb = pCmdAccel->m_Accels.GetNext(pos);230 pACCEL = new ACCEL;231 ASSERT(pACCEL != NULL);232 pACCEL->fVirt = pAccelOb->m_cVirt;233 pACCEL->key = pAccelOb->m_wKey;234 pACCEL->cmd = pCmdAccel->m_wIDCommand;235 arrayACCEL.Add(pACCEL);236 }237 }239 int nAccel = arrayACCEL.GetSize();240 LPACCEL lpAccel = (LPACCEL)LocalAlloc(LPTR, nAccel * sizeof(ACCEL));241 if (!lpAccel)242 {243 for (iLoop = 0; iLoop < nAccel; iLoop++)244 delete arrayACCEL.GetAt(iLoop);245 arrayACCEL.RemoveAll();247 return false;248 }250 for (iLoop = 0; iLoop < nAccel; iLoop++)251 {252 pACCEL = arrayACCEL.GetAt(iLoop);253 lpAccel[iLoop].fVirt = pACCEL->fVirt;254 lpAccel[iLoop].key = pACCEL->key;255 lpAccel[iLoop].cmd = pACCEL->cmd;257 delete pACCEL;258 }259 arrayACCEL.RemoveAll();261 HACCEL hNewTable = CreateAcceleratorTable(lpAccel, nAccel);262 if (!hNewTable)263 {264 ::LocalFree(lpAccel);265 return false;266 }267 HACCEL hOldTable = theApp.hAccel;268 if (!::DestroyAcceleratorTable(hOldTable))269 {270 ::LocalFree(lpAccel);271 return false;272 }273 theApp.hAccel = hNewTable;274 ::LocalFree(lpAccel);276 UpdateMenu(GetMenu(*AfxGetApp()->m_pMainWnd));278 return true;279 }281 //////////////////////////////////////////////////////////////////////282 // Create/Destroy accelerators283 //284 bool CAcceleratorManager::DeleteAccel(BYTE cVirt, WORD wIDCommand, WORD wKey)285 {286 CCmdAccelOb*pCmdAccel = NULL;287 if (m_mapAccelTable.Lookup(wIDCommand, pCmdAccel) == TRUE)288 {289 POSITION pos = pCmdAccel->m_Accels.GetHeadPosition();290 POSITION PrevPos;291 CAccelsOb*pAccel = NULL;292 while (pos != NULL)293 {294 PrevPos = pos;295 pAccel = pCmdAccel->m_Accels.GetNext(pos);296 if (pAccel->m_bLocked == true)297 return false;299 if (pAccel->m_cVirt == cVirt && pAccel->m_wKey == wKey)300 {301 pCmdAccel->m_Accels.RemoveAt(PrevPos);302 delete pAccel;303 return true;304 }305 }306 }307 return false;308 }310 bool CAcceleratorManager::DeleteEntry(WORD wIDCommand)311 {312 CCmdAccelOb*pCmdAccel = NULL;313 VERIFY(m_mapAccelTable.Lookup(wIDCommand, pCmdAccel) == TRUE);315 CAccelsOb*pAccel;316 POSITION pos = pCmdAccel->m_Accels.GetHeadPosition();317 while (pos != NULL)318 {319 pAccel = pCmdAccel->m_Accels.GetNext(pos);320 if (pAccel->m_bLocked == true)321 return false;322 }323 m_mapAccelString.RemoveKey(pCmdAccel->m_szCommand);324 m_mapAccelTable.RemoveKey(wIDCommand);325 delete pCmdAccel;327 return true;328 }330 bool CAcceleratorManager::DeleteEntry(LPCTSTR szCommand)331 {332 ASSERT(szCommand != NULL);334 WORD wIDCommand;335 if (m_mapAccelString.Lookup(szCommand, wIDCommand) == TRUE)336 {337 return DeleteEntry(wIDCommand);338 }339 return true;340 }342 bool CAcceleratorManager::SetAccel(BYTE cVirt, WORD wIDCommand, WORD wKey, LPCTSTR szCommand, bool bLocked)343 {344 ASSERT(szCommand != NULL);346 return AddAccel(cVirt, wIDCommand, wKey, szCommand, bLocked);347 }349 bool CAcceleratorManager::AddCommandAccel(WORD wIDCommand, LPCTSTR szCommand, bool bLocked)350 {351 ASSERT(szCommand != NULL);353 ASSERT(m_pWndConnected != NULL);354 HACCEL hOriginalTable = theApp.hAccel;356 int nAccel = ::CopyAcceleratorTable(hOriginalTable, NULL, 0);357 LPACCEL lpAccel = (LPACCEL)LocalAlloc(LPTR, (nAccel) * sizeof(ACCEL));358 if (!lpAccel)359 return false;360 ::CopyAcceleratorTable(hOriginalTable, lpAccel, nAccel);362 bool bRet = false;363 for (int i = 0; i < nAccel; i++)364 {365 if (lpAccel[i].cmd == wIDCommand)366 bRet = AddAccel(lpAccel[i].fVirt, wIDCommand, lpAccel[i].key, szCommand, bLocked);367 }368 ::LocalFree(lpAccel);369 return bRet;370 }372 bool CAcceleratorManager::CreateEntry(WORD wIDCommand, LPCTSTR szCommand)373 {374 ASSERT(szCommand != NULL);376 WORD wIDDummy;377 if (m_mapAccelString.Lookup(szCommand, wIDDummy) == TRUE)378 return false;380 CCmdAccelOb*pCmdAccel = new CCmdAccelOb(wIDCommand, szCommand);381 ASSERT(pCmdAccel != NULL);382 m_mapAccelTable.SetAt(wIDCommand, pCmdAccel);383 m_mapAccelString.SetAt(szCommand, wIDCommand);385 return false;386 }388 //////////////////////////////////////////////////////////////////////389 // Get a string from the ACCEL definition390 //391 bool CAcceleratorManager::GetStringFromACCEL(ACCEL*pACCEL, CString& szAccel)392 {393 ASSERT(pACCEL != NULL);395 CAccelsOb accel(pACCEL);396 accel.GetString(szAccel);398 if (szAccel.IsEmpty())399 return false;400 else401 return true;402 }404 bool CAcceleratorManager::GetStringFromACCEL(BYTE cVirt, WORD nCode, CString& szAccel)405 {406 CAccelsOb accel(cVirt, nCode);407 accel.GetString(szAccel);409 if (szAccel.IsEmpty())410 return false;411 else412 return true;413 }415 void CAcceleratorManager::UpdateMenu(HMENU menu)416 {417 int count = GetMenuItemCount(menu);419 OSVERSIONINFO info = {0};420 info.dwOSVersionInfoSize = sizeof(info);421 GetVersionEx(&info);423 if (info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)424 {425 MENUITEMINFO info = {0};426 info.cbSize = sizeof(info) - sizeof(HBITMAP);427 info.fMask = MIIM_ID | MIIM_SUBMENU;428 for (int i = 0; i < count; i++)429 {430 GetMenuItemInfo(menu, i, TRUE, &info);432 if (info.hSubMenu != NULL)433 {434 UpdateMenu(info.hSubMenu);435 }436 else437 {438 if (info.wID != (UINT)-1)439 {440 char ss[128];441 MENUITEMINFO info2 = {0};442 info2.cbSize = sizeof(info2) - sizeof(HBITMAP); // FIXME: why?443 info2.fMask = MIIM_STRING;444 info2.dwTypeData = ss;445 info2.cch = 128;446 GetMenuItemInfo(menu, i, MF_BYPOSITION, &info2);448 CString str(ss);449 int index = str.Find('\t');450 if (index != -1)451 str = str.Left(index);453 WORD command = info.wID;455 CCmdAccelOb *o;456 if (m_mapAccelTable.Lookup(command, o))457 {458 if (o->m_Accels.GetCount())459 {460 POSITION pos = o->m_Accels.GetHeadPosition();461 CAccelsOb *accel = o->m_Accels.GetNext(pos);463 CString s;464 accel->GetString(s);465 str += "\t";466 str += s;467 }468 }469 if (str != ss)470 ModifyMenu(menu, i, MF_BYPOSITION | MF_STRING, info.wID, str);471 }472 }473 }474 }475 else476 {477 MENUITEMINFO info = {0};478 info.cbSize = sizeof(info);479 info.fMask = MIIM_ID | MIIM_SUBMENU;480 for (int i = 0; i < count; i++)481 {482 GetMenuItemInfo(menu, i, TRUE, &info);484 if (info.hSubMenu != NULL)485 {486 UpdateMenu(info.hSubMenu);487 }488 else489 {490 if (info.wID != (WORD)-1)491 {492 wchar_t ss[128];493 wchar_t str[512];494 MENUITEMINFOW info2 = {0};495 info2.cbSize = sizeof(info2);496 info2.fMask = MIIM_STRING;497 info2.dwTypeData = ss;498 info2.cch = 128;499 GetMenuItemInfoW(menu, i, MF_BYPOSITION, &info2);501 wcscpy(str, ss);503 wchar_t *p = wcschr(str, '\t');504 if (p)505 *p = 0;507 CCmdAccelOb *o;508 WORD command = info.wID;509 if (m_mapAccelTable.Lookup(command, o))510 {511 if (o->m_Accels.GetCount())512 {513 POSITION pos = o->m_Accels.GetHeadPosition();515 CAccelsOb *accel = o->m_Accels.GetNext(pos);517 CString s;518 accel->GetString(s);520 wchar_t temp[128];521 temp[0] = '\t';522 temp[1] = 0;523 wcscat(str, temp);524 p = temp;525 for (const char *sp = s; *sp; sp++)526 *p++ = *sp;527 *p = 0;528 wcscat(str, temp);529 }530 }531 if (wcscmp(str, ss))532 ModifyMenuW(menu, i, MF_BYPOSITION | MF_STRING, info.wID, str);533 }534 }535 }536 }537 }539 //////////////////////////////////////////////////////////////////////540 // In/Out to the registry541 //542 bool CAcceleratorManager::Load()543 {544 // ASSERT(szRegKey != NULL);546 // m_hRegKey = hRegKey;547 // m_szRegKey = szRegKey;549 DWORD data[2048/sizeof(DWORD)];551 DWORD len = sizeof(data);552 if (regQueryBinaryValue("keyboard", (char *)data, len))553 {554 int count = len/sizeof(DWORD);556 CCmdAccelOb*pCmdAccel;557 CAccelsOb* pAccel;558 DWORD dwIDAccelData, dwAccelData;559 BOOL bExistID;560 int iIndex = 0;561 if (count)562 {563 WORD wKey;564 POSITION pos = m_mapAccelTable.GetStartPosition();566 while (pos != NULL)567 {568 m_mapAccelTable.GetNextAssoc(pos, wKey, pCmdAccel);569 pCmdAccel->DeleteUserAccels();570 }572 while (iIndex < count)573 {574 dwIDAccelData = data[iIndex++];576 WORD wIDCommand = LOWORD(dwIDAccelData);577 bExistID = m_mapAccelTable.Lookup(wIDCommand, pCmdAccel);579 if (bExistID)580 {581 pCmdAccel->DeleteUserAccels();582 }583 for (int j = 0; j < HIWORD(dwIDAccelData) && iIndex < count; j++)584 {585 dwAccelData = data[iIndex++];586 if (bExistID)587 {588 pAccel = new CAccelsOb;589 ASSERT(pAccel != NULL);590 pAccel->SetData(dwAccelData);591 pCmdAccel->Add(pAccel);592 }593 }594 }595 }596 UpdateWndTable();597 return true;598 }599 return false;600 }602 bool CAcceleratorManager::Write()603 {604 CDWordArray AccelsDatasArray;605 CDWordArray CmdDatasArray;607 int iCount = 0;608 CCmdAccelOb*pCmdAccel;609 CAccelsOb* pAccel;610 DWORD dwAccelData;612 WORD wKey;613 POSITION pos = m_mapAccelTable.GetStartPosition();614 while (pos != NULL)615 {616 m_mapAccelTable.GetNextAssoc(pos, wKey, pCmdAccel);617 CmdDatasArray.RemoveAll();619 POSITION pos = pCmdAccel->m_Accels.GetHeadPosition();620 while (pos != NULL)621 {622 pAccel = pCmdAccel->m_Accels.GetNext(pos);623 // if (!pAccel->m_bLocked) {624 dwAccelData = pAccel->GetData();625 CmdDatasArray.Add(dwAccelData);626 // }627 }629 if (CmdDatasArray.GetSize() > 0)630 {631 CmdDatasArray.InsertAt(0, MAKELONG(pCmdAccel->m_wIDCommand, CmdDatasArray.GetSize()));633 AccelsDatasArray.Append(CmdDatasArray);634 iCount++;635 }636 }637 // AccelsDatasArray.InsertAt(0, MAKELONG(65535, iCount));639 int count = AccelsDatasArray.GetSize();640 DWORD *data = (DWORD *)malloc(count * sizeof(DWORD));641 ASSERT(data != NULL);643 for (int index = 0; index < count; index++)644 data[index] = AccelsDatasArray[index];646 regSetBinaryValue("keyboard", (char *)data, count*sizeof(DWORD));648 AccelsDatasArray.RemoveAll();649 CmdDatasArray.RemoveAll();651 free(data);653 return true;654 }656 //////////////////////////////////////////////////////////////////////657 // Defaults values management.658 //659 bool CAcceleratorManager::CreateDefaultTable()660 {661 if (m_bDefaultTable)662 return false;664 CCmdAccelOb*pCmdAccel;665 CCmdAccelOb*pNewCmdAccel;667 CAccelsOb*pAccel;668 CAccelsOb*pNewAccel;670 WORD wKey;671 POSITION pos = m_mapAccelTable.GetStartPosition();672 while (pos != NULL)673 {674 m_mapAccelTable.GetNextAssoc(pos, wKey, pCmdAccel);675 pNewCmdAccel = new CCmdAccelOb;676 ASSERT(pNewCmdAccel != NULL);678 POSITION pos = pCmdAccel->m_Accels.GetHeadPosition();679 while (pos != NULL)680 {681 pAccel = pCmdAccel->m_Accels.GetNext(pos);682 if (!pAccel->m_bLocked)683 {684 pNewAccel = new CAccelsOb;685 ASSERT(pNewAccel != NULL);687 *pNewAccel = *pAccel;688 pNewCmdAccel->m_Accels.AddTail(pNewAccel);689 }690 }691 if (pNewCmdAccel->m_Accels.GetCount() != 0)692 {693 pNewCmdAccel->m_wIDCommand = pCmdAccel->m_wIDCommand;694 pNewCmdAccel->m_szCommand = pCmdAccel->m_szCommand;696 m_mapAccelTableSaved.SetAt(wKey, pNewCmdAccel);697 }698 else699 delete pNewCmdAccel;700 }702 m_bDefaultTable = true;703 return true;704 }706 #include "mainwnd.h"707 bool CAcceleratorManager::Default()708 {709 /// this is NYI for some reason, so the "Reset All" button doesn't work711 #if 0712 // still doesn't work:713 Reset();714 regDeleteValue("keyboard");715 regDeleteValue("keyboardCount");716 Connect((MainWnd *)theApp.m_pMainWnd);717 extern void winAccelAddCommands(CAcceleratorManager& mgr);718 Load();719 CreateDefaultTable();720 winAccelAddCommands(*this);721 UpdateWndTable();722 Write();723 UpdateMenu(theApp.menu);724 m_pWndConnected = NULL;725 #endif727 return true;728 }