Click here to Skip to main content
12,624,724 members (37,473 online)
Click here to Skip to main content

Stats

182.3K views
20.2K downloads
167 bookmarked
Posted

The Ultimate Toolbox - Updates and User Contributions

, 12 Feb 2013 CPOL
Updates and User Contributions for the Ultimate Toolbox Libraries
Ultimate Grid
Demos
OutlookStyle
OutlookStyle.aps
OutlookStyle.dsp
OutlookStyle.dsw
OutlookStyle.suo
res
bitmap1.bmp
bmattach.bmp
bmp00001.bmp
bmp00002.bmp
bmp00003.bmp
Flags.bmp
OutlookStyle.ico
OutlookStyleDoc.ico
Toolbar.bmp
toolbar1.bmp
toolbar2.bmp
toolbarf.bmp
CellTypes
Include
Source
DataSources
ODBC
OleDB
EditControls
BuildDLL
Build DLL.dsp
Build DLL.dsw
res
BuildLib
ugmfclib.dsp
ugmfclib.dsw
Lib
Skel
Ultimate TCP-IP
Include
Security
Include
Source
source
Examples
Client
Mail
icon1.ico
icon2.ico
MailClientS.suo
test.dsp
test.dsw
Ultimate Toolbox
include
source
lib
Build DLLs
Build Libs
// ==========================================================================
//			Class Implementation: COXCustomizeShortkeysPage
// ==========================================================================

// Version: 9.3

// This software along with its related components, documentation and files ("The Libraries")
// is � 1994-2007 The Code Project (1612916 Ontario Limited) and use of The Libraries is
// governed by a software license agreement ("Agreement").  Copies of the Agreement are
// available at The Code Project (www.codeproject.com), as part of the package you downloaded
// to obtain this file, or directly from our office.  For a copy of the license governing
// this software, you may contact us at legalaffairs@codeproject.com, or by calling 416-849-8900.
                         
// //////////////////////////////////////////////////////////////////////////



#include "stdafx.h"

// v93 update 03 - 64-bit
#include "UTB64Bit.h"

#include "OXCustomizeShortkeysPage.h"
#include "OXCustomizeManager.h"

#include "OXBitmapMenuOrganizer.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

const int ID_OX_IMAGEOFFSET_COUNT=2;
const int ID_OX_IMAGEOFFSET_MENUGROUP=0;
const int ID_OX_IMAGEOFFSET_NOIMAGE=1;

#include "UTB64Bit.h"

/////////////////////////////////////////////////////////////////////////////
// COXCustomizeShortkeysPage dialog

IMPLEMENT_DYNCREATE(COXCustomizeShortkeysPage, COXCustomizePage)

COXCustomizeShortkeysPage::COXCustomizeShortkeysPage()
{
	//{{AFX_DATA_INIT(COXCustomizeShortkeysPage)
	m_sAssignedTo = _T("");
	m_sCommandDescription = _T("");
	m_nAccelTableIndex = -1;
	m_nShortkeyIndex = -1;
	//}}AFX_DATA_INIT
	m_nDialogID=IDD;
	m_sProfileName.Empty();
	m_bReadOnly=FALSE;
}


COXCustomizeShortkeysPage::~COXCustomizeShortkeysPage()
{
}


BOOL COXCustomizeShortkeysPage::OnCloseManager(BOOL bIsOk) 
{	
	CWinApp* pApp=AfxGetApp();
	ASSERT(pApp!=NULL);

	if(bIsOk)
	{
		if(!ApplyChanges())
			return FALSE;
		m_shortkeysOrganizer.SaveState(m_sProfileName);
	}
	else
	{
		if(!m_sProfileName.IsEmpty())
		{
			m_shortkeysOrganizer.LoadState(m_sProfileName);
		}
	}

	return TRUE;
}


BOOL COXCustomizeShortkeysPage::
InitializeShortkeys(CFrameWnd* pFrameWnd, 
					LPCTSTR lpszProfileName/*=_T("CustomizeShortkeys")*/)
{
	ASSERT(pFrameWnd!=NULL);

	CWinApp* pApp=AfxGetApp();
	ASSERT(pApp!=NULL);

	CWnd* pWnd=AfxGetMainWnd();
	ASSERT(pWnd!=NULL);
	CFrameWnd* pMainFrameWnd=DYNAMIC_DOWNCAST(CFrameWnd,pWnd);
	ASSERT(pMainFrameWnd!=NULL);

	// build array of all commands available in the system
	//
	// document menus
	if(m_pCustomizeManager->IsMDIFramework())
	{
		POSITION pos=pApp->GetFirstDocTemplatePosition();
		while(pos!=NULL)
		{
			CDocTemplate* pDocTemplate=pApp->GetNextDocTemplate(pos);
			ASSERT(pDocTemplate!=NULL);
			CMultiDocTemplate* pMultiDocTemplate=
				DYNAMIC_DOWNCAST(CMultiDocTemplate,pDocTemplate);
			if(pMultiDocTemplate!=NULL)
			{
				if(pMultiDocTemplate->m_hMenuShared!=NULL)
					RetrieveCommandsFromMenu(pMultiDocTemplate->m_hMenuShared);
			}
		}
	}

	// default menu
	HINSTANCE hInstance=AfxFindResourceHandle(MAKEINTRESOURCE(IDR_MAINFRAME),RT_MENU);
	if(hInstance!=NULL)
	{
		HMENU hMenu=::LoadMenu(hInstance,MAKEINTRESOURCE(IDR_MAINFRAME));
		if(hMenu!=NULL)
		{
			RetrieveCommandsFromMenu(hMenu);
			::DestroyMenu(hMenu);
		}
	}

	// toolbars
	//
	// Iterate all the control bars and use only the toolbars
	POSITION pos=pFrameWnd->m_listControlBars.GetHeadPosition();
	while(pos!=NULL)
	{
		CToolBar* pToolbar=DYNAMIC_DOWNCAST(CToolBar, 
			(CControlBar*)pFrameWnd->m_listControlBars.GetNext(pos));
		//If it is a CToolBar
		if(pToolbar!=NULL)
		{
			// Get the original imagelist of the toolbar
			int nButtonCount=pToolbar->GetToolBarCtrl().GetButtonCount();
			// Iterate all buttons on the toolbar
			for(int nButtonIndex=0; nButtonIndex<nButtonCount; nButtonIndex++)
			{
				UINT nID=0;
				UINT nStyle=0;
				int nImageIndex=0;
				pToolbar->GetButtonInfo(nButtonIndex,nID,nStyle,nImageIndex);
				//If the Item is not a button
				if(nStyle&TBBS_SEPARATOR)
					continue;
				m_mapCommands.SetAt(nID,-1);
			}
		}
	}

	//
	////////////////////////////////////////

	// built image list with all images used in the toolbars
	VERIFY(m_ilImages.Create(ID_OXCUSTOMIZE_TBIMAGE_WIDTH,
		ID_OXCUSTOMIZE_TBIMAGE_HEIGHT,ILC_COLOR24|ILC_MASK,0,0));
	// Iterate all the control bars and use only the toolbars
	pos=pMainFrameWnd->m_listControlBars.GetHeadPosition();
	while(pos!=NULL)
	{
		CToolBar* pToolbar=DYNAMIC_DOWNCAST(CToolBar, 
			(CControlBar*)pMainFrameWnd->m_listControlBars.GetNext(pos));
		//If its a CToolBar
		if(pToolbar!=NULL)
		{
			// Get the original imagelist of the toolbar
			HIMAGELIST hOrigImageList=
				(HIMAGELIST)pToolbar->SendMessage(TB_GETIMAGELIST);
			int nFirstImageIndex=0;
			if(hOrigImageList!=NULL)
			{
				CImageList origImageList;
				CImageList* pOrigImageList=
					CImageList::FromHandlePermanent(hOrigImageList);
				if(pOrigImageList==NULL)
				{
					if(!origImageList.Attach(hOrigImageList))
					{
						TRACE(_T("COXCustomizeShortkeysPage::InitializeCommands: failed to retrieve image list from toolbars\n"));
						return FALSE;
					}
					pOrigImageList=&origImageList;
				}

				int nOrigImageCount=pOrigImageList->GetImageCount();
				ASSERT(0<nOrigImageCount);

				nFirstImageIndex=m_ilImages.GetImageCount();

				for(int nButtonIndex=0; nButtonIndex<nOrigImageCount; nButtonIndex++)
				{
					HICON hIcon=pOrigImageList->ExtractIcon(nButtonIndex);
					ASSERT(hIcon!=NULL);
					VERIFY(m_ilImages.Add(hIcon)!=-1);
					VERIFY(::DestroyIcon(hIcon));
				}

				// Close everything
				if((HIMAGELIST)origImageList!=NULL)
				{
					origImageList.Detach();
				}
			}

			int nButtonCount=pToolbar->GetToolBarCtrl().GetButtonCount();
			// Iterate all buttons on the toolbar
			for(int nButtonIndex=0; nButtonIndex<nButtonCount; nButtonIndex++)
			{
				UINT nID=0;
				UINT nStyle=0;
				int nImageIndex=0;
				pToolbar->GetButtonInfo(nButtonIndex,nID,nStyle,nImageIndex);
				//If the Item is not a button
				if(nStyle&TBBS_SEPARATOR || nImageIndex==-1)
					continue;

				int nImageIndexTest=-1;
				// check if this button is in the commands map
				VERIFY(m_mapCommands.Lookup(nID,nImageIndexTest));
				if(nImageIndexTest==-1)
				{
					nImageIndexTest=nImageIndex+nFirstImageIndex;
					m_mapCommands.SetAt(nID,nImageIndexTest);
				}
			}
		}
	}

	// add to the image list images that would be used in tree of all available 
	// commands in order to represent: command groups, command without image,
	// new menu ite and separator item
	//
	int nFirstImageIndex=m_ilImages.GetImageCount();
	HICON hIcon=pApp->LoadIcon(IDI_OX_CUSTOMIZE_COMMANDGROUP);
	ASSERT(hIcon!=NULL);
	VERIFY(m_ilImages.Add(hIcon)==nFirstImageIndex+ID_OX_IMAGEOFFSET_MENUGROUP);

	hIcon=pApp->LoadIcon(IDI_OX_CUSTOMIZE_NOIMAGE);
	ASSERT(hIcon!=NULL);
	VERIFY(m_ilImages.Add(hIcon)==nFirstImageIndex+ID_OX_IMAGEOFFSET_NOIMAGE);

	//
	/////////////////////////

	m_shortkeysOrganizer.Attach(pFrameWnd,TRUE);
	
	if(lpszProfileName!=NULL)
	{
		m_sProfileName=lpszProfileName;
		VERIFY(m_shortkeysOrganizer.LoadState(m_sProfileName));
	}

	return TRUE;
}


BOOL COXCustomizeShortkeysPage::ApplyChanges()
{
	if(!UpdateData(TRUE))
		return FALSE;

	VERIFY(m_shortkeysOrganizer.SetAccelerators());

	return TRUE;
}


void COXCustomizeShortkeysPage::DoDataExchange(CDataExchange* pDX)
{
	COXCustomizePage::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(COXCustomizeShortkeysPage)
	DDX_Control(pDX, IDC_OX_STATIC_DESCRIPTION, m_textDescription);
	DDX_Control(pDX, IDC_OX_HOTKEY_SHORTKEY, m_hotKey);
	DDX_Control(pDX, IDC_OX_COMBO_TABLE, m_comboTable);
	DDX_Control(pDX, IDC_OX_TREE_COMMANDS, m_treeCommands);
	DDX_Control(pDX, IDC_OX_SEPARATOR_SHORTKEYS, m_sepShortkeys);
	DDX_Control(pDX, IDC_OX_SEPARATOR_DESCRIPTION, m_sepDescription);
	DDX_Control(pDX, IDC_OX_SEPARATOR_CONFLICTS, m_sepConflict);
	DDX_Control(pDX, IDC_OX_SEPARATOR_COMMANDS, m_sepCommands);
	DDX_Control(pDX, IDC_OX_LIST_SHORTKEYS, m_listShortkeys);
	DDX_Text(pDX, IDC_OX_STATIC_ASSIGNED_TO, m_sAssignedTo);
	DDX_Text(pDX, IDC_OX_STATIC_DESCRIPTION, m_sCommandDescription);
	DDX_CBIndex(pDX, IDC_OX_COMBO_TABLE, m_nAccelTableIndex);
	DDX_LBIndex(pDX, IDC_OX_LIST_SHORTKEYS, m_nShortkeyIndex);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(COXCustomizeShortkeysPage, COXCustomizePage)
	//{{AFX_MSG_MAP(COXCustomizeShortkeysPage)
	ON_BN_CLICKED(IDC_OX_BUTTON_ASSIGN, OnButtonAssign)
	ON_BN_CLICKED(IDC_OX_BUTTON_REMOVE, OnButtonRemove)
	ON_BN_CLICKED(IDC_OX_BUTTON_REMOVE_ALL, OnButtonRemoveAll)
	ON_BN_CLICKED(IDC_OX_BUTTON_RESET_ALL, OnButtonResetAll)
	ON_CBN_SELCHANGE(IDC_OX_COMBO_TABLE, OnSelchangeComboTable)
	ON_LBN_SELCHANGE(IDC_OX_LIST_SHORTKEYS, OnSelchangeListShortkeys)
	ON_NOTIFY(TVN_SELCHANGED, IDC_OX_TREE_COMMANDS, OnSelchangedTreeCommands)
	ON_NOTIFY(NM_KEYDOWN, IDC_OX_HOTKEY_SHORTKEY, OnKeydownHotkey)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// COXCustomizeShortkeysPage message handlers

BOOL COXCustomizeShortkeysPage::Load(const COXCustomizeManager* pCustomizeManager)
{
	// Call default implementation. It will load this demo dialog as the first 
	// page and will create About and CodeSample pages if specified.
	if(!COXCustomizePage::Load(pCustomizeManager))
		return FALSE;

	return TRUE;
}


void COXCustomizeShortkeysPage::Unload()
{
	// add here code for cleaning up all objects created by demo
	//
	//
	//////////////////////////////////////////////////////////////////////////

	COXCustomizePage::Unload();
}

void COXCustomizeShortkeysPage::OnInitDialog()
{
	// must call default implementation
	COXCustomizePage::OnInitDialog();

	// add here initialization code for your demo dialog. Treat it as a
	// normal CDialog::OnInitDialog function

	// separators
	COLORREF clr=::GetSysColor(COLOR_WINDOW);
	m_sepShortkeys.SetTextColor(clr);
	m_sepDescription.SetTextColor(clr);
	m_sepConflict.SetTextColor(clr);
	m_sepCommands.SetTextColor(clr);

	// populate tree
	GetVars();

	// populate table of accelerator contexts
	COXArrAccelTables* pAccelTables=m_shortkeysOrganizer.GetAccelTables();
	ASSERT(pAccelTables!=NULL);
	if(pAccelTables->GetSize()==0)
	{
		// there is no accelerator tables defined for this application
		// as aresult all controls on this dialog must be disabled
		CWnd* pWndChild=GetWindow(GW_CHILD);
		while(pWndChild!=NULL)
		{
			pWndChild->EnableWindow(FALSE);
			pWndChild=pWndChild->GetNextWindow();
		}
		m_bReadOnly=TRUE;
	}
	else
	{
		for(int nIndex=0; nIndex<pAccelTables->GetSize(); nIndex++)
		{
			CString sText=OXDEFAULTACCEL;
			if(pAccelTables->GetAt(nIndex).m_docTemplate!=NULL)
			{
				pAccelTables->GetAt(nIndex).m_docTemplate->
					GetDocString(sText,CDocTemplate::docName);
			}
			m_comboTable.AddString(sText);
		}
	}

	m_nAccelTableIndex=0;

	// layout
	//
	m_LayoutManager.TieChild(&m_treeCommands,OX_LMS_ANY,OX_LMT_SAME);
	m_LayoutManager.TieChild(&m_sepCommands,
		OX_LMS_LEFT|OX_LMS_RIGHT,OX_LMT_SAME);
	m_LayoutManager.TieChild(&m_sepDescription,
		OX_LMS_LEFT|OX_LMS_RIGHT|OX_LMS_BOTTOM,OX_LMT_SAME);
	m_LayoutManager.TieChild(IDC_OX_STATIC_DESCRIPTION,
		OX_LMS_LEFT|OX_LMS_RIGHT|OX_LMS_BOTTOM,OX_LMT_SAME);

	m_LayoutManager.TieChild(IDC_OX_SEPARATOR_SHORTKEYS,OX_LMS_RIGHT,OX_LMT_SAME);
	m_LayoutManager.TieChild(IDC_OX_STATIC_FOR,OX_LMS_RIGHT,OX_LMT_SAME);
	m_LayoutManager.TieChild(IDC_OX_COMBO_TABLE,OX_LMS_RIGHT,OX_LMT_SAME);
	m_LayoutManager.TieChild(IDC_OX_STATIC_CURRENT_KEYS,OX_LMS_RIGHT,OX_LMT_SAME);
	m_LayoutManager.TieChild(IDC_OX_LIST_SHORTKEYS,
		OX_LMS_RIGHT|OX_LMS_BOTTOM|OX_LMS_TOP,OX_LMT_SAME);
	m_LayoutManager.TieChild(IDC_OX_BUTTON_ASSIGN,OX_LMS_RIGHT,OX_LMT_SAME);
	m_LayoutManager.TieChild(IDC_OX_BUTTON_REMOVE,OX_LMS_RIGHT,OX_LMT_SAME);
	m_LayoutManager.TieChild(IDC_OX_BUTTON_REMOVE_ALL,OX_LMS_RIGHT,OX_LMT_SAME);
	m_LayoutManager.TieChild(IDC_OX_BUTTON_RESET_ALL,OX_LMS_RIGHT,OX_LMT_SAME);
	m_LayoutManager.TieChild(IDC_OX_STATIC_NEW_KEY,
		OX_LMS_RIGHT|OX_LMS_BOTTOM,OX_LMT_SAME);
	m_LayoutManager.TieChild(IDC_OX_HOTKEY_SHORTKEY,
		OX_LMS_RIGHT|OX_LMS_BOTTOM,OX_LMT_SAME);
	m_LayoutManager.TieChild(IDC_OX_SEPARATOR_CONFLICTS,
		OX_LMS_RIGHT|OX_LMS_BOTTOM,OX_LMT_SAME);
	m_LayoutManager.TieChild(IDC_OX_STATIC_ASSIGNED_TO,
		OX_LMS_RIGHT|OX_LMS_BOTTOM,OX_LMT_SAME);
	//
	///////////////////////////////////////

	UpdateData(FALSE);
	GetShortkeys();
	ShowVars();

	m_bInitialized=TRUE;
}


void COXCustomizeShortkeysPage::ShowVars()
{
	if(!UpdateData(TRUE))
		return;

	if(m_bReadOnly)
		return;

	HTREEITEM hSelectedItem=m_treeCommands.GetSelectedItem();
	UINT nCommandID=(hSelectedItem==NULL ? (UINT)-1 :
		(UINT)m_treeCommands.GetItemData(hSelectedItem));
	GetDlgItem(IDC_OX_HOTKEY_SHORTKEY)->EnableWindow(nCommandID!=(UINT)-1);
	GetDlgItem(IDC_OX_BUTTON_REMOVE_ALL)->EnableWindow(nCommandID!=(UINT)-1 && 
		m_listShortkeys.GetCount()>0);
	GetDlgItem(IDC_OX_BUTTON_RESET_ALL)->EnableWindow(!m_sProfileName.IsEmpty());

	WORD wVirtualKeyCode;
	WORD wModifiers;
	m_hotKey.GetHotKey(wVirtualKeyCode,wModifiers);
	GetDlgItem(IDC_OX_BUTTON_ASSIGN)->EnableWindow(wVirtualKeyCode!=0);

	BOOL bUpdatable=(m_nShortkeyIndex!=-1);
	if(bUpdatable)
	{
		bUpdatable&=(m_listShortkeys.GetItemData(m_nShortkeyIndex)==0);
	}
	GetDlgItem(IDC_OX_BUTTON_REMOVE)->EnableWindow(bUpdatable);
}


void COXCustomizeShortkeysPage::GetVars()
{
	CWinApp* pApp=AfxGetApp();
	ASSERT(pApp!=NULL);

	// populate tree control
	//
	m_treeCommands.DeleteAllItems();

	// associate image list with tree
	m_treeCommands.SetImageList(&m_ilImages,TVSIL_NORMAL);

	// build tree on the base of all menus available in the system
	//
	HINSTANCE hInstance=AfxFindResourceHandle(MAKEINTRESOURCE(IDR_MAINFRAME),RT_MENU);
	if(hInstance!=NULL)
	{
		HMENU hMenu=::LoadMenu(hInstance,MAKEINTRESOURCE(IDR_MAINFRAME));
		if(hMenu!=NULL)
		{
			AddCommandsFromMenuToTree(hMenu,TVI_ROOT);
			::DestroyMenu(hMenu);
		}
	}

	if(m_pCustomizeManager->IsMDIFramework())
	{
		POSITION pos=pApp->GetFirstDocTemplatePosition();
		while(pos!=NULL)
		{
			CDocTemplate* pDocTemplate=pApp->GetNextDocTemplate(pos);
			ASSERT(pDocTemplate!=NULL);
			CMultiDocTemplate* pMultiDocTemplate=
				DYNAMIC_DOWNCAST(CMultiDocTemplate,pDocTemplate);
			if(pMultiDocTemplate!=NULL)
			{
				if(pMultiDocTemplate->m_hMenuShared!=NULL)
				{
					AddCommandsFromMenuToTree(pMultiDocTemplate->m_hMenuShared,
						TVI_ROOT);
				}
			}
		}
	}
}


void COXCustomizeShortkeysPage::RetrieveCommandsFromMenu(HMENU hMenu)
{
	ASSERT(hMenu!=NULL);

	CMenu* pMenu=CMenu::FromHandle(hMenu);
	ASSERT(pMenu!=NULL);
	
	int nItemCount=pMenu->GetMenuItemCount();
	for(int nIndex=0; nIndex<nItemCount; nIndex++)
	{
		if(pMenu->GetMenuItemID(nIndex)==-1)
		{
			// popup menu
			CMenu* pPopupMenu=pMenu->GetSubMenu(nIndex);
			ASSERT(pPopupMenu!=NULL);
			RetrieveCommandsFromMenu((HMENU)*pPopupMenu);
		}
		else
		{
			UINT nCommandID=pMenu->GetMenuItemID(nIndex);
			if(nCommandID!=0)
			{
				// don't add most recent files used 
				if(nCommandID>=ID_FILE_MRU_FILE1 && nCommandID<=ID_FILE_MRU_FILE16)
					continue;

				// don't add MDIChild windows menu items 
				if(m_pCustomizeManager->IsMDIFramework() && 
					nCommandID>=AFX_IDM_FIRST_MDICHILD)
					continue;

				HINSTANCE hInstance=
					AfxFindResourceHandle(MAKEINTRESOURCE(nCommandID),RT_STRING);
				if(hInstance!=NULL)
					m_mapCommands.SetAt(nCommandID,-1);
			}
		}
	}
}


void COXCustomizeShortkeysPage::AddCommandsFromMenuToTree(HMENU hMenu, 
														  HTREEITEM hParentItem)
{
	ASSERT(hMenu!=NULL);
	ASSERT(hParentItem!=NULL);

	CMenu* pMenu=CMenu::FromHandle(hMenu);
	ASSERT(pMenu!=NULL);
	BOOL bIsBitmapMenu=pMenu->IsKindOf(RUNTIME_CLASS(COXBitmapMenu));
	
	int nItemCount=pMenu->GetMenuItemCount();
	for(int nIndex=0; nIndex<nItemCount; nIndex++)
	{
		UINT nCommandID=pMenu->GetMenuItemID(nIndex);
		if(nCommandID==0)
			continue;

		if(nCommandID!=-1)
		{
			// don't add most recent files used 
			if(nCommandID>=ID_FILE_MRU_FILE1 && nCommandID<=ID_FILE_MRU_FILE16)
				continue;

			// don't add MDIChild windows menu items 
			if(m_pCustomizeManager->IsMDIFramework() && 
				nCommandID>=AFX_IDM_FIRST_MDICHILD)
				continue;

			HINSTANCE hInstance=
				AfxFindResourceHandle(MAKEINTRESOURCE(nCommandID),RT_STRING);
			if(hInstance==NULL)
				continue;
		}

		CString sText(_T(""));
		if(bIsBitmapMenu)
		{
			MENUITEMINFO mii={ sizeof(mii) };
			mii.fMask=MIIM_TYPE|MIIM_DATA;
			::GetMenuItemInfo(pMenu->GetSafeHmenu(),nIndex,TRUE,&mii);

			if(mii.fType==MFT_OWNERDRAW)
			{
				COXItemInfo* pItemInfo=(COXItemInfo*)(mii.dwItemData);
				ASSERT(pItemInfo!=NULL);
				sText=pItemInfo->GetText();
			}
		}
		if(sText.IsEmpty())
		{
			pMenu->GetMenuString(nIndex,sText,MF_BYPOSITION);
		}
		ASSERT(!sText.IsEmpty());

		int nPosition=sText.Find(_T('\t'));
		if(nPosition!=-1)
			sText=sText.Left(nPosition);
		
		nPosition=sText.Find(_T('&'));
		if(nPosition!=-1)
			sText=sText.Left(nPosition)+sText.Mid(nPosition+1);

		HTREEITEM hItem=FindMenuItemInTree(sText,hParentItem);
		if(hItem==NULL)
		{
			int nFirstSpecialImage=m_ilImages.GetImageCount()-ID_OX_IMAGEOFFSET_COUNT;
			int nImageIndex=-1;
			if(nCommandID!=-1)
			{
				VERIFY(m_mapCommands.Lookup(nCommandID,nImageIndex));
				if(nImageIndex==-1)
					nImageIndex=nFirstSpecialImage+ID_OX_IMAGEOFFSET_NOIMAGE;
			}
			else
			{
				nImageIndex=nFirstSpecialImage+ID_OX_IMAGEOFFSET_MENUGROUP;
			}

			hItem=m_treeCommands.InsertItem(sText,nImageIndex,nImageIndex,
				hParentItem,TVI_LAST);
			ASSERT(hItem!=NULL);
			m_treeCommands.SetItemData(hItem,(LPARAM)nCommandID);
		}

		if(nCommandID==-1)
		{
			// popup menu
			m_treeCommands.SetItemState(hItem,TVIS_BOLD,TVIS_BOLD);

			CMenu* pPopupMenu=pMenu->GetSubMenu(nIndex);
			ASSERT(pPopupMenu!=NULL);
			AddCommandsFromMenuToTree((HMENU)*pPopupMenu,hItem);
		}
	}
}


HTREEITEM COXCustomizeShortkeysPage::FindMenuItemInTree(CString sText, 
														HTREEITEM hParentItem) const
{
	ASSERT(!sText.IsEmpty());
	ASSERT(hParentItem!=NULL);

	HTREEITEM hChildItem=m_treeCommands.GetNextItem(hParentItem,TVGN_CHILD);

	HTREEITEM hFoundItem=NULL;
	while(hChildItem!=NULL)
	{
		CString sTextToCompare=m_treeCommands.GetItemText(hChildItem);
		if(sText.CompareNoCase(sTextToCompare)==0)
		{
			hFoundItem=hChildItem;
			break;
		}

		hChildItem=m_treeCommands.GetNextItem(hChildItem,TVGN_NEXT);
	}

	return hFoundItem;
}



void COXCustomizeShortkeysPage::OnButtonAssign() 
{
	// TODO: Add your control notification handler code here
	if(!UpdateData(TRUE))
		return;

	HTREEITEM hSelectedItem=m_treeCommands.GetSelectedItem();
	ASSERT(hSelectedItem!=NULL);
	UINT nCommandID=(UINT)m_treeCommands.GetItemData(hSelectedItem);
	ASSERT(nCommandID!=(UINT)-1);

	WORD wVirtualKeyCode;
	WORD wModifiers;
	m_hotKey.GetHotKey(wVirtualKeyCode,wModifiers);

	BYTE fVirt=FVIRTKEY;
	if(wModifiers&HOTKEYF_SHIFT)
		fVirt|=FSHIFT;
	if(wModifiers&HOTKEYF_CONTROL)
		fVirt|=FCONTROL;
	if(wModifiers&HOTKEYF_ALT)
		fVirt|=FALT;

	COXArrAccelTables* pAccelTables=m_shortkeysOrganizer.GetAccelTables();
	ASSERT(pAccelTables!=NULL);
	ASSERT(m_nAccelTableIndex>=0 && m_nAccelTableIndex<pAccelTables->GetSize());
	VERIFY(m_shortkeysOrganizer.AddAccelerator(fVirt,wVirtualKeyCode,
		(WORD)nCommandID,
		pAccelTables->GetAt(m_nAccelTableIndex).m_docTemplate,TRUE));

	m_hotKey.SetHotKey(0,0);
	m_sAssignedTo.Empty();
	UpdateData(FALSE);

	GetShortkeys();
	ShowVars();
}

void COXCustomizeShortkeysPage::OnButtonRemove() 
{
	// TODO: Add your control notification handler code here
	if(!UpdateData(TRUE))
		return;

	ASSERT(m_nShortkeyIndex>=0 && m_nShortkeyIndex<m_listShortkeys.GetCount());
	ASSERT(m_listShortkeys.GetItemData(m_nShortkeyIndex)==0);

	HTREEITEM hSelectedItem=m_treeCommands.GetSelectedItem();
	ASSERT(hSelectedItem!=NULL);
	WORD nCommandID=(WORD)m_treeCommands.GetItemData(hSelectedItem);
	ASSERT(nCommandID!=(WORD)-1);

	CString sKey(_T(""));
	m_listShortkeys.GetText(m_nShortkeyIndex,sKey);
	ACCEL accel;
	VERIFY(m_shortkeysOrganizer.GetAccelKeyFromString(sKey,&accel));
	accel.cmd=nCommandID;

	COXArrAccelTables* pAccelTables=m_shortkeysOrganizer.GetAccelTables();
	ASSERT(pAccelTables!=NULL);
	ASSERT(m_nAccelTableIndex>=0 && m_nAccelTableIndex<pAccelTables->GetSize());
	VERIFY(m_shortkeysOrganizer.RemoveAccelerator(&accel,
		pAccelTables->GetAt(m_nAccelTableIndex).m_docTemplate));

	GetShortkeys();
	ShowVars();
}

void COXCustomizeShortkeysPage::OnButtonRemoveAll() 
{
	// TODO: Add your control notification handler code here
	if(!UpdateData(TRUE))
		return;

	HTREEITEM hSelectedItem=m_treeCommands.GetSelectedItem();
	ASSERT(hSelectedItem!=NULL);
	WORD nCommandID=(WORD)m_treeCommands.GetItemData(hSelectedItem);
	ASSERT(nCommandID!=(WORD)-1);

	COXArrAccelTables* pAccelTables=m_shortkeysOrganizer.GetAccelTables();
	ASSERT(pAccelTables!=NULL);
	ASSERT(m_nAccelTableIndex>=0 && m_nAccelTableIndex<pAccelTables->GetSize());
	VERIFY(m_shortkeysOrganizer.RemoveAllAccelerators(nCommandID,
		pAccelTables->GetAt(m_nAccelTableIndex).m_docTemplate));

	GetShortkeys();
	ShowVars();
}

void COXCustomizeShortkeysPage::OnButtonResetAll() 
{
	// TODO: Add your control notification handler code here
	
	if(!m_sProfileName.IsEmpty())
	{
		m_shortkeysOrganizer.LoadState(m_sProfileName);
		GetShortkeys();
		ShowVars();
	}
}

void COXCustomizeShortkeysPage::OnSelchangeComboTable() 
{
	// TODO: Add your control notification handler code here
	
	GetShortkeys();
	ShowVars();
}

void COXCustomizeShortkeysPage::OnSelchangeListShortkeys() 
{
	// TODO: Add your control notification handler code here
	
	ShowVars();
}

void COXCustomizeShortkeysPage::OnSelchangedTreeCommands(NMHDR* pNMHDR, 
														 LRESULT* pResult) 
{
	NM_TREEVIEW* pNMTreeView=(NM_TREEVIEW*)pNMHDR;
	// TODO: Add your control notification handler code here

	HTREEITEM hSelectedItem=pNMTreeView->itemNew.hItem;
	if(hSelectedItem!=NULL)
	{
		DWORD_PTR dwData=m_treeCommands.GetItemData(hSelectedItem);
		if(dwData==-1)
		{
			// existing popup menu
			m_sCommandDescription.Format(IDS_OX_CSTMZESHORTKEYSGROUP,//"%s group"
				m_treeCommands.GetItemText(hSelectedItem));
		}
		else 
		{
			UINT nCommandID=(UINT)dwData;
			HINSTANCE hInstance=
				AfxFindResourceHandle(MAKEINTRESOURCE(nCommandID),RT_STRING);
			if(hInstance==NULL)
			{
				m_sCommandDescription.Empty();
			}
			else
			{
				m_sCommandDescription.LoadString(nCommandID);
				int nPosition=m_sCommandDescription.Find(_T('\n'));
				if(nPosition!=-1)
					m_sCommandDescription=m_sCommandDescription.Left(nPosition);
			}
		}
	}
	else
	{
		m_sCommandDescription.Empty();
	}

	m_hotKey.SetHotKey(0,0);
	m_sAssignedTo.Empty();
	
	UpdateData(FALSE);

	GetShortkeys();
	ShowVars();

	*pResult=0;
}


void COXCustomizeShortkeysPage::GetShortkeys()
{
	if(!UpdateData(TRUE))
		return;

	HTREEITEM hSelectedItem=m_treeCommands.GetSelectedItem();
	UINT nCommandID=(hSelectedItem==NULL ? (UINT)-1 :
		(UINT)m_treeCommands.GetItemData(hSelectedItem));

	m_listShortkeys.ResetContent();

	if(m_nAccelTableIndex==-1 || nCommandID==(UINT)-1)
	{
		return;
	}

	ASSERT(nCommandID>0);
	COXArrAccelTables* pAccelTables=m_shortkeysOrganizer.GetAccelTables();
	ASSERT(pAccelTables!=NULL);
	ASSERT(m_nAccelTableIndex<pAccelTables->GetSize());
	CMultiDocTemplate* pDocTemplate=
		pAccelTables->GetAt(m_nAccelTableIndex).m_docTemplate;
	COXArrAccelerators arrAccels;
	if(pDocTemplate!=NULL)
	{
		VERIFY(m_shortkeysOrganizer.
			FindAllAccelerators((WORD)nCommandID,NULL,arrAccels));
		for(int nIndex=0; nIndex<arrAccels.GetSize(); nIndex++)
		{
			ACCEL accel=arrAccels[nIndex];
			CString sKey=m_shortkeysOrganizer.GetAccelKeyString(&accel);
			int nNewItemIndex=m_listShortkeys.
				AddString(sKey,OXLBI_TEXTCOLOR,NULL,RGB(128,128,128));
			ASSERT(nNewItemIndex!=LB_ERR);
			// couldn't be removed or reset
			m_listShortkeys.SetItemData(nNewItemIndex,(DWORD)-1);
		}		
		arrAccels.RemoveAll();
	}
	VERIFY(m_shortkeysOrganizer.
		FindAllAccelerators((WORD)nCommandID,pDocTemplate,arrAccels));
	for(int nIndex=0; nIndex<arrAccels.GetSize(); nIndex++)
	{
		ACCEL accel=arrAccels[nIndex];
		CString sKey=m_shortkeysOrganizer.GetAccelKeyString(&accel);
		int nNewItemIndex=m_listShortkeys.AddString(sKey);
		ASSERT(nNewItemIndex!=LB_ERR);
		// can be removed or reset
		m_listShortkeys.SetItemData(nNewItemIndex,0);
	}		
}

void COXCustomizeShortkeysPage::OnKeydownHotkey(NMHDR* pNMHDR, LRESULT* pResult) 
{
	// TODO: Add your control notification handler code here
	UNREFERENCED_PARAMETER(pNMHDR);

	ShowVars();

	WORD wVirtualKeyCode;
	WORD wModifiers;
	m_hotKey.GetHotKey(wVirtualKeyCode,wModifiers);

	BYTE fVirt=FVIRTKEY;
	if(wModifiers&HOTKEYF_SHIFT)
		fVirt|=FSHIFT;
	if(wModifiers&HOTKEYF_CONTROL)
		fVirt|=FCONTROL;
	if(wModifiers&HOTKEYF_ALT)
		fVirt|=FALT;

	COXArrAccelTables* pAccelTables=m_shortkeysOrganizer.GetAccelTables();
	ASSERT(pAccelTables!=NULL);
	ASSERT(m_nAccelTableIndex>=0 && m_nAccelTableIndex<pAccelTables->GetSize());
	WORD nFoundCommandID=m_shortkeysOrganizer.FindAccelerator(fVirt,wVirtualKeyCode,
		pAccelTables->GetAt(m_nAccelTableIndex).m_docTemplate);
	if(nFoundCommandID!=0)
	{
		HINSTANCE hInstance=
			AfxFindResourceHandle(MAKEINTRESOURCE(nFoundCommandID),RT_STRING);
		if(hInstance==NULL)
		{
			m_sAssignedTo.Format(IDS_OX_CSTMZESHORTKEYSASSIGNED,//"Currently assigned to the command:\nwith ID=%d"
				nFoundCommandID);
		}
		else
		{
			CString sCommandDescription(_T(""));
			sCommandDescription.LoadString(nFoundCommandID);
			int nPosition=sCommandDescription.Find(_T('\n'));
			if(nPosition!=-1)
			{
				sCommandDescription=sCommandDescription.Mid(nPosition+1);
			}
			m_sAssignedTo.Format(IDS_OX_CSTMZESHORTKEYSASSIGNEDS,//"Currently assigned to the command:\n<%s>"
				sCommandDescription);
		}
	}
	else
	{
		m_sAssignedTo.Empty();
	}
	UpdateData(FALSE);

	*pResult = 0;
}

BOOL COXCustomizeShortkeysPage::PreTranslateMessage(MSG* pMsg) 
{
	// TODO: Add your specialized code here and/or call the base class
	
	if(m_shortkeysOrganizer.IsAttached() &&
		pMsg->message>=WM_KEYFIRST && pMsg->message<=WM_KEYLAST)
	{
		COXArrAccelerators arrAccels;
		BYTE fVirt=FVIRTKEY;
		if(::GetKeyState(VK_SHIFT)<0)
			fVirt|=FSHIFT;
		if(::GetKeyState(VK_CONTROL)<0)
			fVirt|=FCONTROL;
		if(::GetKeyState(VK_MENU)<0)
			fVirt|=FALT;

		VERIFY(m_shortkeysOrganizer.
			FindAllAccelerators(fVirt,(WORD)pMsg->wParam,arrAccels));
		if(arrAccels.GetSize()>0)
			return FALSE;

		VERIFY(m_shortkeysOrganizer.
			FindAllRemovedAccelerators(fVirt,(WORD)pMsg->wParam,arrAccels));
		if(arrAccels.GetSize()>0)
			return FALSE;
	}
	return COXCustomizePage::PreTranslateMessage(pMsg);
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

The Ultimate Toolbox
Web Developer
Canada Canada
In January 2005, David Cunningham and Chris Maunder created TheUltimateToolbox.com, a new group dedicated to the continued development, support and growth of Dundas Software’s award winning line of MFC, C++ and ActiveX control products.

Ultimate Grid for MFC, Ultimate Toolbox for MFC, and Ultimate TCP/IP have been stalwarts of C++/MFC development for a decade. Thousands of developers have used these products to speed their time to market, improve the quality of their finished products, and enhance the reliability and flexibility of their software.
Group type: Organisation

428 members


You may also be interested in...

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.161128.1 | Last Updated 13 Feb 2013
Article Copyright 2008 by The Ultimate Toolbox
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid