/** * @file XTPCustomizeTools.cpp * * @copyright * (c) 1998-2025 Codejock Software, All Rights Reserved. * * This source file is the property of Codejock Software and must not be * redistributed by any means without the explicit written permission of * Codejock Software. * * The use of this source code is governed by the terms and conditions specified * in the Toolkit Pro license agreement. Codejock Software grants you, as a * single software developer, the limited right to use this software on one * computer only. * * Contact Information: * support@codejock.com * http://www.codejock.com * */ #include "stdafx.h" #include "Common/XTPVC80Helpers.h" #include "Common/XTPTypeId.h" #include "Common/XTPFramework.h" #include "Common/XTPSystemHelpers.h" #include "Common/XTPSynchro.h" #include "Common/XTPApplication.h" #include "Common/XTPSingleton.h" #include "Common/XTPGdiObjects.h" #include "Common/XTPResourceManager.h" #include "Common/XTPDrawHelpers.h" #include "Common/XTPHookManager.h" #include "Common/XTPColorManager.h" #include "Common/XTPMaskEditT.h" #include "Common/ScrollBar/XTPScrollInfo.h" #include "Common/ScrollBar/XTPScrollBase.h" #include "Common/ScrollBar/XTPScrollBarCtrl.h" #include "Common/ScrollBar/XTPScrollable.h" #include "Controls/Resize/XTPResizeRect.h" #include "Controls/Resize/XTPResizePoint.h" #include "Controls/Resize/XTPResize.h" #include "Controls/Resize/XTPResizeDialog.h" #include "Controls/Util/XTPControlTheme.h" #include "Controls/Button/XTPButton.h" #include "Controls/Edit/XTPEdit.h" #include "Controls/Scroll/XTPScrollBar.h" #include "CommandBars/Resource.h" #include "CommandBars/XTPCommandBarsDefines.h" #include "CommandBars/XTPPaintManager.h" #include "CommandBars/XTPShortcutManager.h" #include "CommandBars/XTPCommandBar.h" #include "CommandBars/XTPControl.h" #include "CommandBars/XTPToolBar.h" #include "CommandBars/XTPCommandBars.h" #include "CommandBars/XTPControlEdit.h" #include "Controls/Dialog/XTPDialogBase.h" #include "Controls/Dialog/XTPPropertySheet.h" #include "CommandBars/Customize/XTPCustomizeSheet.h" #include "CommandBars/Customize/XTPCustomizeTools.h" #include "Common/Base/Diagnostic/XTPDisableNoisyWarnings.h" #ifdef _DEBUG # define new DEBUG_NEW # undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CXTPCustomizeDropSource CXTPCustomizeDropSource::CXTPCustomizeDropSource(CXTPCommandBars* pCommandBars) { m_hcurDelete = XTPResourceManager()->LoadCursor(XTP_IDC_COMMANDBARS_DRAGDELETE); m_hcurMove = XTPResourceManager()->LoadCursor(XTP_IDC_COMMANDBARS_DRAGMOVE); m_hcurCopy = XTPResourceManager()->LoadCursor(XTP_IDC_COMMANDBARS_DRAGCOPY); m_pSheet = NULL; m_pCommandBars = pCommandBars; m_hwndCapture = 0; m_pControl = 0; m_bMove = FALSE; m_bCopyOnly = FALSE; m_pTarget = NULL; } CXTPCustomizeDropSource::~CXTPCustomizeDropSource() { } void CXTPCustomizeDropSource::ContextMenu(CPoint point) { GetSheet()->ContextMenu(point); } DROPEFFECT CXTPCustomizeDropSource::DoDragDrop(CXTPControl* pControl, BOOL bCopyOnly) { _ASSERTE(m_pCommandBars); if (!m_pCommandBars) return 0; CWnd* pWndCapture = m_pSheet ? (CWnd*)m_pSheet : m_pCommandBars->GetSite(); _ASSERTE(pWndCapture); if (!pWndCapture) return 0; m_pControl = pControl; m_hwndCapture = pWndCapture->GetSafeHwnd(); ::SetCapture(m_hwndCapture); m_bMove = FALSE; m_pTarget = NULL; m_bCopyOnly = bCopyOnly; GetCursorPos(&m_ptStart); DROPEFFECT dropEffect = _DoDragDrop(); if (m_pTarget) m_pTarget->OnCustomizeDragLeave(); ReleaseCapture(); ::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW)); return dropEffect; } void CXTPCustomizeDropSource::Register(CXTPCommandBar* pCommandBar) { m_arrTargets.Add(pCommandBar); } void CXTPCustomizeDropSource::UnRegister(CXTPCommandBar* pCommandBar) { for (int i = 0; i < m_arrTargets.GetSize(); i++) { if (pCommandBar == m_arrTargets[i]) { m_arrTargets.RemoveAt(i); } } } CXTPCustomizeSheet* CXTPCustomizeDropSource::GetSheet() const { return m_pSheet; } // picks the current target void CXTPCustomizeDropSource::PickTarget(CPoint point) { HWND hWndPoint = WindowFromPoint(point); BOOL bFound = FALSE; for (int i = (int)m_arrTargets.GetSize() - 1; i >= 0; i--) { CXTPCommandBar* pCommandBar = m_arrTargets[i]; if (pCommandBar->IsVisible() && CXTPWindowRect(pCommandBar).PtInRect(point) && (pCommandBar->GetSafeHwnd() == hWndPoint || ::IsChild(pCommandBar->GetSafeHwnd(), hWndPoint))) { bFound = TRUE; if (m_pTarget == pCommandBar) { m_pTarget->ScreenToClient(&point); m_pTarget->OnCustomizeDragOver(m_pControl, point); } else if (m_pTarget != NULL) { m_pTarget->OnCustomizeDragLeave(); m_pTarget = 0; } if (m_pTarget == 0) { pCommandBar->ScreenToClient(&point); if (pCommandBar->OnCustomizeDragEnter(m_pControl, point) != DROPEFFECT_NONE) { m_pTarget = pCommandBar; } } break; } } if (!bFound && m_pTarget) { m_pTarget->OnCustomizeDragLeave(); m_pTarget = 0; } // set the cursor as appropriate FreshenCursor(); } void CXTPCustomizeDropSource::FreshenCursor() { HCURSOR hCursor = m_hcurDelete; if (m_pTarget) { hCursor = (m_bMove && !m_bCopyOnly) ? m_hcurMove : m_hcurCopy; } ::SetCursor(hCursor); } DROPEFFECT CXTPCustomizeDropSource::_DoDragDrop() { BOOL bMoved = FALSE; DROPEFFECT dropEffect = DROPEFFECT_CANCEL; BOOL bDone = FALSE; while (!bDone && ::GetCapture() == m_hwndCapture) { MSG msg; if (!::GetMessage(&msg, NULL, 0, 0)) { AfxPostQuitMessage((int)msg.wParam); return DROPEFFECT_CANCEL; } if (::GetCapture() != m_hwndCapture) { // capture was stolen while repainting return DROPEFFECT_CANCEL; } switch (msg.message) { case WM_LBUTTONUP: bDone = TRUE; break; case WM_MOUSEMOVE: if (!bMoved) { CPoint pt(msg.pt); if (m_pControl && m_pControl->GetParent()) { DROPEFFECT dropEffectDragStart = DROPEFFECT_CANCEL; m_pControl->GetParent()->ScreenToClient(&pt); m_pControl->OnCustomizeDragOver(m_pControl, pt, dropEffectDragStart); } bMoved = TRUE; } m_bMove = !(msg.wParam & MK_CONTROL); PickTarget(msg.pt); // terminate loop if we happen to get mouse move with button up if (!(msg.wParam & MK_LBUTTON)) bDone = TRUE; dropEffect = DROPEFFECT_NONE; break; case WM_KEYDOWN: if (msg.wParam == VK_ESCAPE) return DROPEFFECT_CANCEL; if (msg.wParam == VK_CONTROL && m_bMove) { m_bMove = FALSE; FreshenCursor(); } break; case WM_KEYUP: if (msg.wParam == VK_CONTROL && !m_bMove) { m_bMove = TRUE; FreshenCursor(); } break; case WM_RBUTTONDOWN: return DROPEFFECT_CANCEL; default: ::DispatchMessage(&msg); } } if (m_pTarget) { dropEffect = DROPEFFECT(m_bMove ? DROPEFFECT_MOVE : DROPEFFECT_COPY); CPoint point; GetCursorPos(&point); m_pTarget->ScreenToClient(&point); m_pTarget->ScreenToClient(&m_ptStart); m_pTarget->OnCustomizeDrop(m_pControl, dropEffect, point, m_ptStart); m_pTarget = 0; } return dropEffect; }