Перетаскивание элементов из 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
|