|
|
|
|
Forum
Please
Log In
to post a new message or reply to an existing one. If you are not registered, please
register.
NOTE: Some forums may be read-only if you are not currently subscribed to
our technical support services.
Subject |
Author |
Date |
|
Phillip Bernard
|
Feb 7, 2008 - 6:49 AM
|
In customize mode when you simply try to select any menu item or toolbar button accidental D&D operation can be performed. It may looks as you just click on menu item and then it disapears.
This happens because you call pSite->DoDragCmdNode() in CExtToolControlBar::OnLButtonDown() and CExtPopupMenuWnd::OnLButtonDown() without checking if D&D operation is realy required.
But for this purpose exists winAPI function DragDetect(). It check if D&D begins by drag rectangle and drag time (the last is undocumented).
Because in Office 2003 D&D is checked only by drag rectangle i suggest following variant of DragDetect
bool MyDragDetect(CWnd *pWnd, CPoint point) { pWnd->ClientToScreen(&point); while (::DragDetect(pWnd->GetSafeHwnd(), point)) { CPoint pt; ::GetCursorPos(&pt); if (pt == point) continue; //only drag time elapsed but mouse is not moved return true; } return false; }
e.g. using this func in ExtPopupMenuWnd.cpp fragment of CExtPopupMenuWnd::OnLButtonDown() .... WND hWndOwn = m_hWnd; _ItemFocusSet( nIndex, TRUE, TRUE, FALSE ); if( ! ::IsWindow( hWndOwn ) ) return; ASSERT( hWndOwn != NULL && ::IsWindow(hWndOwn) );
if (!MyDragDetect(this, point)) { m_pDragSrcNode = NULL; m_bHelperNoHideChild = false; m_nDragSrcIdx = -1; m_bHelperNoRemoveSrc = false; m_bHelperDragOverPassed = false; return; }
pSite->DoDragCmdNode( this, NULL, m_pDragSrcNode, rcItem ); ....
|
|
Technical Support
|
Feb 9, 2008 - 1:28 AM
|
We completely agree with you so we added the following static method to the CExtControlBar class and invoked it from CExtPopupMenuWnd::OnLButtonDown() exactly as you advise: bool CExtControlBar::stat_DoDragDetect(
HWND hWnd,
const POINT & ptWndClient
)
{
if( hWnd == NULL || (! ::IsWindow( hWnd ) ) )
return false;
CPoint ptScreen = ptWndClient;
::ClientToScreen( hWnd, &ptScreen );
while( ::DragDetect( hWnd, ptScreen ) )
{
POINT ptCursorPos;
if( ! ::GetCursorPos( ptScreen) )
return false;
if( ptScreen == ptCursorPos )
continue; //only drag time elapsed but mouse is not moved
return true;
}
return false;
} We have also invoked it from the CExtToolControlBar::OnLButtonDown() method: m_pDragSourceTBB = pTBB;
m_pDragTargetTBB = NULL;
m_nDragTargetShift = 0;
m_bHelperSeparatorAction = false;
_InvalidateButton( nBtnDragSrc );
//UpdateWindow();
if( CExtControlBar::stat_DoDragDetect( m_hWnd, point ) )
pSite->DoDragCmdNode( this, pNodeI, pNodeC, rcItem );
m_pDragSourceTBB = NULL;
m_pDragTargetTBB = NULL;
m_nDragTargetShift = 0;
m_bHelperSeparatorAction = false;
return;
|
|