Поиск:

Ответ в темуСоздание новой темы Создание опроса
> drag и drop елементов управления, как таскать объекты CWnd по форме..... 
:(
    Опции темы
OverBug
Дата 21.11.2006, 10:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 13.4.2006
Где: г.Пенза, Пензенск ой обл.

Репутация: нет
Всего: 1



Здрасти.... Пытался найти подобную тему в истории тем.... не нашел... вернее нашел драг ГДИ объектов.... но это нето...

я пытаюсь своими силами склепать нестандартные элементы управления... делаю их из набора объектов CWnd... эти окна прорисовываются на форме и вот такой вопрос... как их сделать так чтобы можно их таскать по форме... просто перемещать... искал событие OnDrag и др в событиях CWnd.. не нашел... но они есть, как я понял, у CView и дочерних от него классов. и можно ли вообще перемещать объекты CWnd? я посмотрел один примерчик с даргом и там создаются объеты на базе CCmdTarget и создаются они в объекте ScrollView... 
PM MAIL ICQ   Вверх
OverBug
Дата 21.11.2006, 14:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 13.4.2006
Где: г.Пенза, Пензенск ой обл.

Репутация: нет
Всего: 1



кажись перевелись спецы по drag&drop..... очередной раз искал и не нашел подобных тем...
Уважаемые форумчане!!!!!
ктонибудь что нибудь знает по данной тематике.... 
PM MAIL ICQ   Вверх
Earnest
Дата 21.11.2006, 15:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Есть OLE drag & drop, если желаешь - разбирайся. Смотри классы COleDataSource, COleDropSourse и т.д.

Но мне лично кажется, что для реализации в рамках твоей задачи это слишком громоздко. Я бы сделала ручками: на WM_LBUTTONDOWN определяем таскаемый объект, ставим Capture, меняем курсор ..., на WM_MOUSEMOVE перемещаем, на WM_LBUTTONUP - отпускаем. Всего-то делов.


--------------------
...
PM   Вверх
OverBug
Дата 21.11.2006, 17:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 13.4.2006
Где: г.Пенза, Пензенск ой обл.

Репутация: нет
Всего: 1



Sorry.... what is capture and where он должен быть или есть.... smile 
PM MAIL ICQ   Вверх
Earnest
Дата 21.11.2006, 17:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



SetCapture, читай MSDN.


--------------------
...
PM   Вверх
Любитель
Дата 21.11.2006, 17:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Программист-романтик
****


Профиль
Группа: Комодератор
Сообщений: 3645
Регистрация: 21.5.2005
Где: Воронеж

Репутация: 7
Всего: 92



Енто означает возможность ловли всех перемещений мыхи вне твоего окна.


--------------------
PM MAIL ICQ Skype   Вверх
OverBug
Дата 22.11.2006, 10:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 13.4.2006
Где: г.Пенза, Пензенск ой обл.

Репутация: нет
Всего: 1



вообщем я вчера  smile  smile  smile  smile  smile ... чувствую себя чайником... запутался в трех канаплях... судите сами....

Код

..... OnLButtonDown( .... , CPoint point){
      this->SetCapture();
     CWnd::JnLButtonDown(...);
}

..... OnMouseMove(...., CPoint point){
      if((this->GetCapture()))
    {
            this->MoveWindow(point.x,point.y,17,70);
            this->OnPaint();
    }
......
}

..... OnLButtonUp(....){
     ReleaseCapture();
.....
}



помоему так... писал по памяти... вообщем когда я начинаю таскать объект то он не идет за курсором мыши а находится гдето между координатой 0,0 парента и положением курсора плюс к этому из этой же координаты идет еще один... т.е. их два... видно два... на самом деле ИМХО координата скачет в два места... пытался преоблазовывать point.x в int... и ни как... я вообще правильно все делаю?

Это сообщение отредактировал(а) OverBug - 22.11.2006, 10:21
PM MAIL ICQ   Вверх
Earnest
Дата 22.11.2006, 17:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Не if (this->GetCapture()), а if (GetCapture() == this).

Но лучше поставь флаг в OnLButtonDown.
Т.к. Capture может пропасть по независящим от тебя причинам.
По этому поводу нужно еще обрабатывать WM_CAPTURECHANGED - примерно так, как сброс драга.

А с координатами ты уж сам разбирайся - есть, в конце концов, отладчик и отладочная печать ...
Разве что... обрати внимание на то, в какой системе координаты у тебя: дочернее окно хочет получать координаты клиентской области парента (MoveWindow).


--------------------
...
PM   Вверх
OverBug
Дата 22.11.2006, 23:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 13.4.2006
Где: г.Пенза, Пензенск ой обл.

Репутация: нет
Всего: 1



я так понял что:
1)т.е. такой флаг: nFlags == MK_LBUTTON
2)при обработке "WM_CAPTURECHANGED - примерно так, как сброс драга", т.е. выполнить ReleaseCapture();

я еще забыл сказать что когда перетаскиваемый объект перекрывает другие объекты такого же класса, то они не перерисовываются.... почему такое? может что-то я упустил?
PM MAIL ICQ   Вверх
Earnest
Дата 23.11.2006, 10:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Цитата(OverBug @  23.11.2006,  00:52 Найти цитируемый пост)
1)т.е. такой флаг: nFlags == MK_LBUTTON

Нет... введи управляющий флаг в классе, например m_bInDrag. Который будешь устанавливать в true на LButtonDown, если начат драггинг, т.е. ткнули в объект, который можно таскать. И сбрасывай при завершении драггинга. Capture- это всего лишь механизм, причем не только тобой контролируемый, поэтому не стоит использовать его как признак драггинга.

Еще заметила... Не надо вызывать OnPaint после MoveWindow. Это такая штука... OnPaint должна вызывать сама система, причем тогда, когда ей удобно...
Ты должен вызывать InvalidateRect. Причем у парента и дважды: для старой позиции контрола и для новой. 


--------------------
...
PM   Вверх
OverBug
Дата 27.11.2006, 10:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 13.4.2006
Где: г.Пенза, Пензенск ой обл.

Репутация: нет
Всего: 1



вообщем... пока получилось следующее (даю исходник с целью критики... и может быть кому исче понадобится)
Код

void CMyRamka::OnLButtonDown(UINT nFlags, CPoint point)
{
    if(point.y <7)    
        this->SetCapture();
    CWnd::OnLButtonDown(nFlags, point);
}

void CMyRamka::OnMouseMove(UINT nFlags, CPoint point)
{
    RECT rc,prc;

    this->GetWindowRect(&rc);
    this->GetParent()->GetWindowRect(&prc);

    if((this->GetCapture()))
    {
        this->MoveWindow(rc.left - prc.left + point.x - 3, rc.top - prc.top + point.y - 23, 17, 70);

    }

    CWnd::OnMouseMove(nFlags, point);
}
void CMyRamka::OnLButtonUp(UINT nFlags, CPoint point)
{
    ReleaseCapture();
    this->GetParent()->RedrawWindow();
    CWnd::OnLButtonUp(nFlags, point);
}

void CMyRamka::OnCaptureChanged(CWnd *pWnd)
{
    ReleaseCapture();
    CWnd::OnCaptureChanged(pWnd);
}



работа такого кода меня устраивает.... и скоординатами разобрался... когда перетаскиваю окно... то оно само прорисовывается и для этого не надо было вызывать перерисовку самому... smile 
сейчас бьюсь над тем чтобы окно понимало что на него перетаскивают что-то.....

Это сообщение отредактировал(а) OverBug - 27.11.2006, 10:24
PM MAIL ICQ   Вверх
Earnest
Дата 27.11.2006, 15:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



OverBug, ты читаешь через строку: здесь вижу, здесь нет.
Еще раз повторяю: код 
Цитата(OverBug @  27.11.2006,  11:06 Найти цитируемый пост)
if((this->GetCapture()))
 не правильный, т.к. GetCapture возвращает окно, которое захватило мышь. Ведь захватить мышь может не только твое окно.
Если уж проверяешь Capture то сравнивай с this.
И не используй Capture как признак драггинга, неужели флажок трудно ввести?
Твой код работает только в исключительно благоприятных ситуациях. Попробуй хотя бы, не закончив таскать объект, переключится в другое приложение и что-нибуль там поделать.
Кроме того, драг&дроп удобнее реализовывать на уровне парента. Примерно так:

Код

void CMyDialog::StartDragging (CPoint pt)
{
    m_pDragWnd = FindDrag(pt);   // эта функция ищет контрол по pt и проверяет, можно ли его таскать
}

// ok показывает как завершился драг - с подтверждением или отказом, скажем по потере capture
void CMyDialog::StopDragging (bool bOk)
{
    m_pDragWnd = 0;
}

void CMyDialog::OnLButtonDown(...)
{
   StartDragging(pt);  
}

void CMyDialog::OnMouseMove(...)
{
   if (m_pDragWnd)
  {
     // рисуем таскаемый объект
  }
}

void CMyDialog::OnLButtonUp(...)
{
   StopDrag(true);
}

void CMyDialog::OnCaptureChanged(...)
{
   StopDrag(false);
}

// можно еще по ESC завершать перетаскивание 
void CMyDialog::OnRButtonDown(...)
{
   StopDrag(false);
}



--------------------
...
PM   Вверх
OverBug
Дата 27.11.2006, 16:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 13.4.2006
Где: г.Пенза, Пензенск ой обл.

Репутация: нет
Всего: 1



а как задать области где перетаскиваемый объект можно бросать? тут без оли можно обойтись или нет?

Это сообщение отредактировал(а) OverBug - 27.11.2006, 16:18
PM MAIL ICQ   Вверх
Earnest
Дата 27.11.2006, 16:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Области окна, в котором осуществляется драг? Элементарно. На MouseMove проверяй, где мышь, и, если вне области дозволенного дропа, показывай курсор-дулю (ну такой стандартный перечеркнутый круг) вместо перерисовки контрола. А при нормальной позиции - не забудь его спрятать. На дроп придется проверить то же самое, или флаг веди.


--------------------
...
PM   Вверх
OverBug
Дата 27.11.2006, 16:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 13.4.2006
Где: г.Пенза, Пензенск ой обл.

Репутация: нет
Всего: 1



т.е.,как я понял, в условии драггинга появятся два условия: одно - если область дозволенная, другое - все остальные случаи.... и проверять на дозволенность позиции можно сразу по нескольким областям....

а в случае между окнами, хотябы двух копий одного и тогоже приложения.... или его тулвиндовов???
PM MAIL ICQ   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




[ Время генерации скрипта: 0.0640 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.