Перетаскивание элементов
из Toolbar в view
Автор: Pham Hong Nguyen.
Основноя проблема заключается в том, что toolbar не
реагирует на действие переноса элементов.
Следовательно нам нужно брать и посылать
соответствующие сообщения самостоятельно. Итак,
наследуем новый класс CDragToolBar от CToolBar, затем
добавляем в него обработчик события LButtonDown:
void CDragToolBar::OnLButtonDown(UINT nFlags, CPoint point)
{
int nCount = GetToolBarCtrl().GetButtonCount();
for (int i=0; i<nCount; i++) {
CRect rect;
GetItemRect(i, rect);
if (rect.PtInRect(point)) {
PostMessage(WM_COMMAND, GetItemID(i));
return;
}
}
CToolBar::OnLButtonDown(nFlags, point);
}
Теперь во view перехватываем все события,
поступающие от toolbar и переводим программу в режим
перетаскивания:
void CDTBView::OnDragToolBar(UINT nCmdID)
{
m_dragBtn = nCmdID;
BeginDrag ();
}
В этом примере drag and drop работает через CImageList.
Данный метод прекрасно работает. Однако,
существует небольшая проблемма, заключающаяся в
том, что перетаскиваемая кнопка тулбара не
правильно перерисовывается ввиду нарушения
курсора перетаскивания (он фиксирует
изображение кнопки до апдейта, а затем только
перерисовывает его). Поэтому нам потребуется
небольшое улучшение кода.
Вместо того, чтобы входить в режим
перетаскивания после получения сообщения,
программа должна записать событие
перетаскиваемой кнопки и дать немного времени,
чтобы тулбар проапдейтил статус кнопки. Чтобы
гарантировать это, мы фиксируем событие
перемещения мышки, и проверяем как далеко была
перемещена мышка. Если всё ОК, то отправляем
другое сообщение, для того, чтобы программа вошла
в режим перетаскивания:
void CDragToolBar::OnLButtonDown(UINT nFlags, CPoint point)
{
int nCount = GetToolBarCtrl().GetButtonCount();
for (int i=0; i<nCount; i++) {
CRect rect;
GetItemRect(i, rect);
if (rect.PtInRect(point)) {
PostMessage(WM_COMMAND, GetItemID(i));
m_dragMode = TRUE;
m_point = point;
return;
}
}
CToolBar::OnLButtonDown(nFlags, point);
}
void CDragToolBar::OnMouseMove(UINT nFlags, CPoint point)
{
if (m_dragMode &&
abs(m_point.x-point.x)+abs(m_point.y-point.y)>=3) {
PostMessage(WM_COMMAND, ID_START_DRAG);
m_dragMode = FALSE;
}
CToolBar::OnMouseMove(nFlags, point);
}
Во view делаем соответствующие изменения:
void CDTBView::OnDragToolBar(UINT nCmdID)
{
m_dragBtn = nCmdID;
}
void CDTBView::OnStartDrag()
{
BeginDrag();
}
А теперь добавим немного кода, чтобы придать
тулбару немного интеллектуальности.
void CDragToolBar::OnLButtonDown(UINT nFlags, CPoint point)
{
int nCount = GetToolBarCtrl().GetButtonCount();
for (int i=0; i<nCount; i++) {
CRect rect;
GetItemRect(i, rect);
if (rect.PtInRect(point)) {
PostMessage(WM_COMMAND, GetItemID(i));
m_dragMode = TRUE;
m_point = point;
return;
}
}
CToolBar::OnLButtonDown(nFlags, point);
}
void CDragToolBar::OnMouseMove(UINT nFlags, CPoint point)
{
if (m_dragMode &&
abs(m_point.x-point.x)+abs(m_point.y-point.y)>=3) {
PostMessage(WM_COMMAND, ID_START_DRAG);
m_dragMode = FALSE;
}
CToolBar::OnMouseMove(nFlags, point);
}
Ну и во view тоже сделаем немного изменений:
void CDTBView::OnDragToolBar(UINT nCmdID)
{
m_dragBtn = nCmdID;
}
void CDTBView::OnStartDrag()
{
BeginDrag();
}
Downloads
Скачать демонстрационный
проект - 30 Kb
Скачать исходник - 2 Kb
|