Objective Grid: Enabling right mouse button dragging

Article ID: 298
Last updated: 11 Jun, 2018
Article ID: 298
Last updated: 11 Jun, 2018
Revision: 3
Views: 2186
Posted: 11 Jan, 2001
by Meltreger B.
Updated: 11 Jun, 2018
by Meltreger B.

Problem


How can I enable dragging cells with the right mouse button and display a popup-menu when the user releases the mouse button? In the popup-menu I would like the user to give the option to copy or move the cells.


Cause



Action


Add the following menu resource to your resource file:

IDR_MENU_DNDACTION MENU DISCARDABLE
BEGIN
POPUP "Drop Action"
BEGIN
MENUITEM "&Copy", ID_DND_COPY
MENUITEM "&Move", ID_DND_MOVE
END
END

Next, add the following handlers to the message map of your grid view:

ON_WM_RBUTTONDOWN()
ON_COMMAND(ID_DND_MOVE, OnDndMove)
ON_COMMAND(ID_DND_COPY, OnDndCopy)

In your header file, add the following attributes and overrides:

// Attributes
BOOL m_bRButton;
UINT m_nDndAction;
// Operations
virtual BOOL OnGridDrop(CGXNoOleDataObjectProxy* pDataObject, DROPEFFECT dropEffect, CPoint point);

virtual BOOL DndDropActionMenu(CGXNoOleDataObjectProxy* pDataObject, DROPEFFECT dropEffect, CPoint point);

// Generated message map functions
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
afx_msg void OnDndMove();
afx_msg void OnDndCopy();

Here are the implementations of these functions:

void C1stGridView::OnRButtonDown(UINT nFlags, CPoint point)
{
if (GetCapture() == NULL)
{
CRect rectHit;
ROWCOL nRow, nCol;
int ht = HitTest(point, &nRow, &nCol);

if (ht == GX_SELEDGEHIT)
{

if (m_nDndFlags)
{
ROWCOL ncRow = nRow;
ROWCOL ncCol = nCol;
CGXRange rgCovered(nRow, nCol);

if (GetCoveredCellsRowCol(nRow, nCol, rgCovered))
{

ncRow = rgCovered.top;
ncCol = rgCovered.left;
}

m_bRButton = TRUE;
BOOL b = DndStartDragDrop(ncRow, ncCol);
m_bRButton = FALSE;

if (b)

return;
}
}
}

// check, if user clicked on a header or cell in the grid
CGXGridView::OnRButtonDown(nFlags, point);

}

BOOL C1stGridView::OnGridDrop(CGXNoOleDataObjectProxy* pDataObject, DROPEFFECT dropEffect, CPoint point)
{

// Kill the timer started in OnGridDragEnter.
if (!m_bDndGlobalTimer && m_dwDndDropTargetFlags & GX_DNDEGDESCROLL)
m_pGridWnd->KillTimer(GX_TIMER_DNDSCROLLOTHER);
// kill timer for this window
if (m_bDndGlobalTimer)
{
m_pGridWnd->KillTimer(GX_TIMER_DNDSCROLLSELF);
m_bDndGlobalTimer = FALSE;
}

if (m_bRButton)

dropEffect = DndDropActionMenu(pDataObject, dropEffect, point);
return CGXGridCore::OnGridDrop(pDataObject, dropEffect, point);
}

BOOL C1stGridView::DndDropActionMenu(CGXNoOleDataObjectProxy* pDataObject, DROPEFFECT dropEffect, CPoint pt)
{

if (dropEffect == DROPEFFECT_MOVE)
{
CMenu CopyMoveMenu;
m_nDndAction = 0;
CopyMoveMenu.LoadMenu(IDR_MENU_DNDACTION);
CMenu* pPopup = CopyMoveMenu.GetSubMenu(0);
ClientToScreen(&pt);

pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, this, NULL);

MSG msg;
while (::PeekMessage(&msg, m_hWnd, WM_COMMAND, WM_COMMAND, PM_REMOVE))
{

TranslateMessage(&msg);
DispatchMessage(&msg);
}

switch (m_nDndAction)
{
case ID_DND_COPY:

dropEffect = DROPEFFECT_COPY;
break;
case ID_DND_MOVE:
dropEffect = DROPEFFECT_MOVE;
break;
default:
dropEffect = DROPEFFECT_NONE;
break;
}
}

return dropEffect;

}

void C1stGridView::OnDndMove()
{

m_nDndAction = ID_DND_MOVE;
}

void C1stGridView::OnDndCopy()
{

m_nDndAction = ID_DND_COPY;
}

This article was:   Helpful | Not helpful
Report an issue
Article ID: 298
Last updated: 11 Jun, 2018
Revision: 3
Views: 2186
Posted: 11 Jan, 2001 by Meltreger B.
Updated: 11 Jun, 2018 by Meltreger B.

Others in this category