// XTPCustomizeCommandsPage.cpp : implementation of the CXTPCustomizeCommandsPage class. // // This file is a part of the XTREME COMMANDBARS MFC class library. // (c)1998-2012 Codejock Software, All Rights Reserved. // // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN // CONSENT OF CODEJOCK SOFTWARE. // // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A // SINGLE COMPUTER. // // CONTACT INFORMATION: // support@codejock.com // http://www.codejock.com // ///////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "Resource.h" #include "Common/XTPResourceManager.h" #include "Common/XTPDrawHelpers.h" #include "Common/XTPSystemHelpers.h" #include "Common/XTPHookManager.h" #include "Common/XTPColorManager.h" #include "Controls/Resize/XTPResizeRect.h" #include "Controls/Resize/XTPResizePoint.h" #include "Controls/Resize/XTPResize.h" #include "Controls/Dialog/XTPPropertyPage.h" #include "Controls/Dialog/XTPPropertySheet.h" #include "XTPCommandBarsDefines.h" #include "XTPControls.h" #include "XTPControl.h" #include "XTPControlButton.h" #include "XTPControlPopup.h" #include "XTPPaintManager.h" #include "XTPCustomizeTools.h" #include "XTPCustomizeSheet.h" #include "XTPCommandBar.h" #include "XTPCommandBars.h" #include "XTPCustomizeCommandsPage.h" #include "XTPMouseManager.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif XTP_COMMANDBARS_CATEGORYINFO::XTP_COMMANDBARS_CATEGORYINFO(LPCTSTR _strCategory, CXTPCommandBars* pCommandBars) { strCategory = _strCategory; pControls = new CXTPControls; pControls->SetCommandBars(pCommandBars); } XTP_COMMANDBARS_CATEGORYINFO::~XTP_COMMANDBARS_CATEGORYINFO() { pControls->InternalRelease(); } void CXTPCustomizeCommandsListBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC); CRect rc(lpDrawItemStruct->rcItem); CXTPControl* pControl = (CXTPControl*)lpDrawItemStruct->itemData; if (pControl) { BOOL bSelected = (lpDrawItemStruct->itemState & ODS_SELECTED); CXTPCommandBars* pCommandBars = m_pCommandBars; pCommandBars->GetPaintManager()->DrawListBoxControl(pDC, pControl, rc, bSelected, TRUE, pCommandBars); } } BEGIN_MESSAGE_MAP(CXTPCustomizeCommandsListBox, CListBox) //{{AFX_MSG_MAP(CXTPCustomizeCommandsPage) ON_WM_LBUTTONDOWN() ON_WM_SETFOCUS() ON_WM_ERASEBKGND() ON_WM_PAINT() ON_MESSAGE(WM_PRINTCLIENT, OnPrintClient) //}}AFX_MSG_MAP END_MESSAGE_MAP() BOOL CXTPCustomizeCommandsListBox::OnEraseBkgnd(CDC* /*pDC*/) { return TRUE; } void CXTPCustomizeCommandsListBox::OnPaint() { CPaintDC dc(this); CRect rc; GetClientRect(&rc); CXTPBufferDC memDC(dc); m_pCommandBars->GetPaintManager()->DrawListBoxControl(&memDC, NULL, rc, FALSE, TRUE, m_pCommandBars); CListBox::DefWindowProc(WM_PAINT, (WPARAM)memDC.m_hDC, 0); } LRESULT CXTPCustomizeCommandsListBox::OnPrintClient(WPARAM wParam, LPARAM lParam) { CDC* pDC = CDC::FromHandle((HDC)wParam); CXTPClientRect rc(this); m_pCommandBars->GetPaintManager()->DrawListBoxControl(pDC, NULL, rc, FALSE, TRUE, m_pCommandBars); return CListBox::DefWindowProc(WM_PRINTCLIENT, wParam, lParam); } void CXTPCustomizeCommandsListBox::OnSetFocus(CWnd* pOldWnd) { CListBox::OnSetFocus(pOldWnd); if ((GetKeyState(VK_TAB) < 0 || GetKeyState(VK_MENU) < 0) && GetCurSel() == -1) SetCurSel(0); } void CXTPCustomizeCommandsListBox::OnLButtonDown(UINT nFlags, CPoint point) { CXTPCommandBars* pCommandBars = m_pCommandBars; ASSERT(pCommandBars); if (!pCommandBars) return; pCommandBars->SetDragControl(NULL); BOOL bOutside; int nIndex = (int)ItemFromPoint(point, bOutside); CXTPControl* pControl = NULL; if (!bOutside && m_bDragable) { if (SetCurSel(nIndex) != LB_ERR) { // Already selected, start drag operation pControl = (CXTPControl*)GetItemData(nIndex); // since we are eating the message, if the selection has changed, notify the owner. CWnd* pWndOwner = GetOwner(); if (pWndOwner) { SetFocus(); pWndOwner->PostMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), LBN_SELCHANGE), (LPARAM)m_hWnd); } // Special case for New Menu if (pControl && pControl->GetCommandBar() && pControl->GetCommandBar()->GetControlCount() == 0) { pControl = pControl->Clone(TRUE); CXTPCustomizeDropSource* pDropSource = pCommandBars->GetDropSource(); pDropSource->DoDragDrop(pControl, TRUE); pControl->InternalRelease(); return; } if (pControl) { CXTPCustomizeDropSource* pDropSource = pCommandBars->GetDropSource(); pDropSource->DoDragDrop(pControl, TRUE); return; } } } // process as a click first CListBox::OnLButtonDown(nFlags, point); } ///////////////////////////////////////////////////////////////////////////// // CXTPCustomizeCommandsPage property page IMPLEMENT_DYNCREATE(CXTPCustomizeCommandsPage, CXTPPropertyPage) CXTPCustomizeCommandsPage::CXTPCustomizeCommandsPage(CXTPCustomizeSheet* pSheet) : CXTPPropertyPage(XTP_IDD_PAGE_COMMANDS), m_pSheet(pSheet) { //{{AFX_DATA_INIT(CXTPCustomizeCommandsPage) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT } CXTPCustomizeCommandsPage::~CXTPCustomizeCommandsPage() { for (int i = 0; i < m_arrCategories.GetSize(); i++) { delete m_arrCategories[i]; } } void CXTPCustomizeCommandsPage::DoDataExchange(CDataExchange* pDX) { CXTPPropertyPage::DoDataExchange(pDX); //{{AFX_DATA_MAP(CXTPCustomizeCommandsPage) DDX_Control(pDX, XTP_IDC_LIST_COMMANDS, m_lstCommands); DDX_Control(pDX, XTP_IDC_LIST_CATEGORIES, m_lstCategories); //}}AFX_DATA_MAP } XTP_COMMANDBARS_CATEGORYINFO* CXTPCustomizeCommandsPage::FindCategory(LPCTSTR strCategory) const { for (int i = 0; i < m_arrCategories.GetSize(); i++) { if (m_arrCategories[i]->strCategory.Compare(strCategory) == 0) return m_arrCategories[i]; } return NULL; } XTP_COMMANDBARS_CATEGORYINFO* CXTPCustomizeCommandsPage::GetCategoryInfo(int nIndex) const { if (nIndex >= 0 && nIndex < m_arrCategories.GetSize()) return m_arrCategories[nIndex]; return NULL; } BOOL CXTPCustomizeCommandsPage::AddCategory(LPCTSTR strCategory, CMenu* pMenu, BOOL bListSubItems) { CXTPControls* pCategoryControls = InsertCategory(strCategory); int nCount = pMenu->GetMenuItemCount(); for (int i = 0; i < nCount; i++) { if (pMenu->GetMenuItemID(i) > 0) { CXTPControlPopup* pControl = DYNAMIC_DOWNCAST(CXTPControlPopup, pCategoryControls->AddMenuItem(pMenu, i)); if (pControl && bListSubItems) { CXTPControls* pControls = pControl->GetCommandBar()->GetControls(); for (int j = 0; j < pControls->GetCount(); j++) { pCategoryControls->AddClone(pControls->GetAt(j)); } } } } return TRUE; } BOOL CXTPCustomizeCommandsPage::_LoadToolBar(CXTPCommandBar* pCommandBar, UINT nIDResource) { LPCTSTR lpszResourceName = MAKEINTRESOURCE(nIDResource); struct CToolBarData { WORD wVersion; WORD wWidth; WORD wHeight; WORD wItemCount; WORD* items() { return (WORD*)(this + 1); } }; ASSERT(lpszResourceName != NULL); if (!lpszResourceName) return FALSE; // determine location of the bitmap in resource fork HINSTANCE hInst = AfxFindResourceHandle(lpszResourceName, RT_TOOLBAR); if (!hInst) return FALSE; HRSRC hRsrc = ::FindResource(hInst, lpszResourceName, RT_TOOLBAR); if (!hRsrc) return FALSE; HGLOBAL hGlobal = LoadResource(hInst, hRsrc); if (!hGlobal) return FALSE; CToolBarData* pData = (CToolBarData*)LockResource(hGlobal); if (!pData) return FALSE; ASSERT(pData->wVersion == 1); ASSERT(pData->wWidth == 16); int i; UINT* pItems = new UINT[pData->wItemCount]; for (i = 0; i < pData->wItemCount; i++) pItems[i] = pData->items()[i]; BOOL bResult = pCommandBar->SetButtons(pItems, pData->wItemCount); delete[] pItems; UnlockResource(hGlobal); FreeResource(hGlobal); return bResult; } BOOL CXTPCustomizeCommandsPage::AddToolbarCategory(LPCTSTR strCategory, UINT nIDResource) { CXTPControls* pCategoryControls = InsertCategory(strCategory); ASSERT(pCategoryControls); if (!pCategoryControls) return FALSE; CXTPCommandBar* pCommandBar = (CXTPCommandBar*)CXTPCommandBar::CreateObject(); pCommandBar->SetCommandBars(m_pSheet->GetCommandBars()); if (!_LoadToolBar(pCommandBar, nIDResource)) { pCommandBar->InternalRelease(); return FALSE; } for (int i = 0; i < pCommandBar->GetControlCount(); i++) { pCategoryControls->AddClone(pCommandBar->GetControl(i)); } pCommandBar->InternalRelease(); return TRUE; } BOOL CXTPCustomizeCommandsPage::AddCategories(UINT nIDResource, BOOL bListSubItems) { CMenu menu; if (!XTPResourceManager()->LoadMenu(&menu, nIDResource)) return FALSE; int nCount = menu.GetMenuItemCount(); for (int i = 0; i < nCount; i++) { CString strCategory; if (XTPResourceManager()->GetMenuLocaleString(&menu, i, strCategory, MF_BYPOSITION) > 0) { CMenu* pMenu = menu.GetSubMenu(i); if (pMenu) { CXTPPaintManager::StripMnemonics(strCategory); int iPos = strCategory.Find(_T('\t')); if (iPos > 0) { strCategory.ReleaseBuffer(iPos); } if (!AddCategory(strCategory, pMenu, bListSubItems)) return FALSE; } } } return TRUE; } BOOL CXTPCustomizeCommandsPage::AddCategories(CXTPControls* pControls) { for (int i = 0; i < pControls->GetCount(); i++) { CXTPControl* pControl = pControls->GetAt(i); CString strCategory = pControl->GetCategory(); if (!strCategory.IsEmpty()) { CXTPControls* pCategoryControls = InsertCategory(strCategory); pCategoryControls->AddClone(pControl); } } return TRUE; } BOOL CXTPCustomizeCommandsPage::InsertBuiltInMenus(UINT nIDResourceMenu, UINT nIDResourceCategory, int nIndex) { CMenu menu; if (!XTPResourceManager()->LoadMenu(&menu, nIDResourceMenu)) return FALSE; CString strCategory; XTPResourceManager()->LoadString(&strCategory, nIDResourceCategory); ASSERT(FindCategory(strCategory) == NULL); XTP_COMMANDBARS_CATEGORYINFO* pInfo = new XTP_COMMANDBARS_CATEGORYINFO(strCategory, m_pSheet->GetCommandBars()); m_arrCategories.InsertAt(nIndex == -1 ? m_arrCategories.GetSize() : nIndex, pInfo); int nCount = menu.GetMenuItemCount(); for (int i = 0; i < nCount; i++) { pInfo->pControls->AddMenuItem(&menu, i); } return TRUE; } void CXTPCustomizeCommandsPage::InsertNewMenuCategory(UINT nIDResource, int nIndex) { CString strCategory; XTPResourceManager()->LoadString(&strCategory, nIDResource); ASSERT(FindCategory(strCategory) == NULL); XTP_COMMANDBARS_CATEGORYINFO* pInfo = new XTP_COMMANDBARS_CATEGORYINFO(strCategory, m_pSheet->GetCommandBars()); m_arrCategories.InsertAt(nIndex == -1 ? m_arrCategories.GetSize() : nIndex, pInfo); CXTPControl* pControl = pInfo->pControls->Add(xtpControlPopup, 0); pControl->SetCaption(strCategory); } CXTPControls* CXTPCustomizeCommandsPage::InsertCategory(LPCTSTR strCategory, int nIndex) { XTP_COMMANDBARS_CATEGORYINFO* pInfo = FindCategory(strCategory); if (!pInfo) { pInfo = new XTP_COMMANDBARS_CATEGORYINFO(strCategory, m_pSheet->GetCommandBars()); m_arrCategories.InsertAt(nIndex == -1 ? m_arrCategories.GetSize() : nIndex, pInfo); } return pInfo->pControls; } CXTPControls* CXTPCustomizeCommandsPage::GetControls(LPCTSTR strCategory) { XTP_COMMANDBARS_CATEGORYINFO* pInfo = FindCategory(strCategory); return pInfo ? pInfo->pControls : NULL; } void CXTPCustomizeCommandsPage::InsertAllCommandsCategory(UINT nIDResource, int nIndex, BOOL bSortCommands) { CString strCategory; XTPResourceManager()->LoadString(&strCategory, nIDResource); ASSERT(FindCategory(strCategory) == NULL); XTP_COMMANDBARS_CATEGORYINFO* pInfo = new XTP_COMMANDBARS_CATEGORYINFO(strCategory, m_pSheet->GetCommandBars()); for (int i = 0; i < m_arrCategories.GetSize(); i++) { CXTPControls* pControls = m_arrCategories[i]->pControls; for (int j = 0; j < pControls->GetCount(); j++) { pInfo->pControls->AddClone(pControls->GetAt(j)); } } if (bSortCommands) pInfo->pControls->Sort(); m_arrCategories.InsertAt(nIndex == -1 ? m_arrCategories.GetSize() : nIndex, pInfo); } BEGIN_MESSAGE_MAP(CXTPCustomizeCommandsPage, CXTPPropertyPage) //{{AFX_MSG_MAP(CXTPCustomizeCommandsPage) ON_LBN_SELCHANGE(XTP_IDC_LIST_CATEGORIES, OnCategoriesSelectionChanged) ON_WM_DESTROY() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CXTPCustomizeCommandsPage message handlers BOOL CXTPCustomizeCommandsPage::OnInitDialog() { CXTPPropertyPage::OnInitDialog(); for (int i = 0; i < m_arrCategories.GetSize(); i++) { int nIndex = m_lstCategories.AddString(m_arrCategories[i]->strCategory); m_lstCategories.SetItemData(nIndex, i); if (i == 0) m_lstCategories.SetCurSel(0); } CXTPCommandBars* pCommandBars = m_pSheet->GetCommandBars(); CSize sz = pCommandBars->GetPaintManager()->DrawListBoxControl(NULL, NULL, CRect(0, 0, 0, 0), FALSE, FALSE, pCommandBars); m_lstCommands.SetItemHeight(-1, sz.cy); m_lstCommands.m_pCommandBars = m_pSheet->GetCommandBars(); m_lstCommands.m_bDragable = TRUE; if (pCommandBars->IsLayoutRTL()) { m_lstCommands.ModifyStyleEx(0, WS_EX_LAYOUTRTL); m_lstCategories.ModifyStyleEx(0, WS_EX_RIGHT | WS_EX_LEFTSCROLLBAR | WS_EX_RTLREADING); } pCommandBars->GetMouseManager()->AddTrustedWindow(m_hWnd); OnCategoriesSelectionChanged(); SetResize(XTP_IDC_LIST_CATEGORIES, XTP_ANCHOR_TOPLEFT, XTP_ANCHOR_BOTTOMLEFT); SetResize(XTP_IDC_LIST_COMMANDS, XTP_ANCHOR_TOPLEFT, XTP_ANCHOR_BOTTOMRIGHT); return FALSE; } void CXTPCustomizeCommandsPage::OnDestroy() { CXTPCommandBars* pCommandBars = m_pSheet->GetCommandBars(); pCommandBars->GetMouseManager()->RemoveTrustedWindow(m_hWnd); CXTPPropertyPage::OnDestroy(); } void CXTPCustomizeCommandsPage::OnCategoriesSelectionChanged() { m_lstCommands.ResetContent(); int nIndex = m_lstCategories.GetCurSel(); if (nIndex == LB_ERR) return; XTP_COMMANDBARS_CATEGORYINFO* pInfo = GetCategoryInfo((int)m_lstCategories.GetItemData(nIndex)); if (pInfo == NULL) return; for (int i = 0; i < pInfo->pControls->GetCount(); i++) { CXTPControl* pControl = pInfo->pControls->GetAt(i); if (!pControl->IsVisible(xtpHideWrap)) continue; m_lstCommands.SendMessage(LB_INSERTSTRING, m_lstCommands.GetCount(), (LPARAM)pControl); } }