Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/21: Рейтинг темы: голосов - 21, средняя оценка - 5.00
18 / 18 / 7
Регистрация: 20.03.2012
Сообщений: 585

Drag'n'Dock Мерцание и тормоза при перерисовки рамки окна

07.11.2012, 18:58. Показов 4664. Ответов 10
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Подскажите, пожалуйста, как избавиться от мерцания и "тормозов" при рисовании рамки окна, когда оно перемещается пользователем (DragKind = dkDock). А еще лучше, чтобы рисовалась не рамка, а прозрачный прямоугольник, как это, например, происходит при перемещении окон "Structure" (и т.п.) среды разработки Embarcadero 2010.
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
07.11.2012, 18:58
Ответы с готовыми решениями:

Drag'n'Dock, bsToolWindow и кнопка "фиксации" окна
Подскажите, пожалуйста, как добавить кнопку "фиксации" окна (которая изображается в виде канцелярской кнопки) и настроить ее поведение,...

Пропадает таб при перетаскивании его в PageControl. Drag & Dock
Здравствуйте! Работаю с Delphi6. Суть проблемы: Я хватаю таб из PageControl и передвигаю его ниже и отпускаю -> этот таб пропадает....

Drag Drop Dock
есть ли толковая литература или интересные статьи по этому методу мне нужно просто реализовать перетаскивание картинки по форме только...

10
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33406 / 21516 / 8236
Регистрация: 22.10.2011
Сообщений: 36,917
Записей в блоге: 12
08.11.2012, 01:04
Лучший ответ Сообщение было отмечено как решение

Решение

Тормозов не вижу, но если надо рисовать не стандартную рамку, а что-то своё - то в событии OnStartDock создавай DragObject как экземпляр наследника TDragDockObjectEx, в котором реализуй ImageList типа TDragImageList. В конструкторе класса просто создавай сам List, и добавляй в него одну-единственную картинку: синий прямоугольник. То есть, сам наследник будет выглядеть как-то так (тестировалось на RAD 2009) :

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class TMyDragDock : public TDragDockObjectEx
{
protected:
    virtual TDragImageList* __fastcall GetDragImages(void)
    {
        // зачем Control->Tag - поймешь, когда тебе понадобится
        // в процедуре EraseDragDockImage того контрола, который перетаскивается,
        // имея только указатель на TDragDockObject, вытащить этот самый DragImageList
        return (TDragImageList*)(Control->Tag);
    }
public:
    __fastcall virtual TMyDragDock(TControl* AControl);
    inline __fastcall virtual ~TMyDragDock(void)
    {
        delete ((TDragImageList*)(Control->Tag));
    }
};
 
__fastcall TMyDragDock::TMyDragDock(TControl* AControl) : TDragDockObjectEx(AControl)
{
    TDragImageList* FDragImageList = new TDragImageList(AControl->Width, AControl->Height);
    FDragImageList->Masked = true;
 
    FDragImageList->Clear();
    std::auto_ptr<Graphics::TBitmap> bmp(new Graphics::TBitmap()); // #include <memory>
    bmp->SetSize(AControl->Width, AControl->Height);
    bmp->Canvas->Brush->Style = bsSolid;
    bmp->Canvas->Brush->Color = clBlue;
    bmp->Canvas->FillRect(bmp->Canvas->ClipRect);
 
    FDragImageList->Add(bmp.get(), 0);
    Control->Tag = (int)FDragImageList;
}
Осталось только переопределить в том контроле, который Dock-ится, необходимые методы. Их, на самом деле, всего 2: EraseDragDockImage, чтобы убрать изображение, когда контрол отпущен, и DefaultDockImage, чтобы не рисовать эту злосчастную стандартную рамку. Вот так я это сделал:

<Unit1.h>
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class TPanel : public Extctrls::TPanel
{
protected:
    DYNAMIC void __fastcall EraseDragDockImage(TDragDockObject* DragDockObject)
    {
        if(DragDockObject->Cancelling)
        {
            ((TDragImageList*)(DragDockObject->Control->Tag))->EndDrag();
        }
    }
    DYNAMIC void __fastcall DefaultDockImage(TDragDockObject* DragDockObject, bool Erase)
    {
        // Не рисовать рамку !!!
    }
};
 
class TForm1 : public TForm
{
__published:    // IDE-managed Components
    TPanel *Panel1;
    ::TPanel *Panel2; // Панель с переопределенными методами !!!
    void __fastcall Panel2StartDock(TObject *Sender, TDragDockObject *&DragObject);
 
private:    // User declarations
public: // User declarations
    __fastcall TForm1(TComponent* Owner);
};
, ну, и реализация OnStartDock панели:
C++
1
2
3
4
void __fastcall TForm1::Panel2StartDock(TObject *Sender, TDragDockObject *&DragObject)
{
    DragObject = new TMyDragDock(Panel2);
}
, теперь при перетягивании появляется нормальный синий прямоугольник:
Миниатюры
Drag'n'Dock Мерцание и тормоза при перерисовки рамки окна  
4
18 / 18 / 7
Регистрация: 20.03.2012
Сообщений: 585
08.11.2012, 18:12  [ТС]
Сделал все как описано, только не с панелями, а с окнами. Есть два нюанса: 1) Прямоугольник рисуется начиная с местоположения мыши, а не с местоположения окна. 2) Прямоугольник вообще не рисуется, когда окно находиться над док-понелью и готово "причалить".
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33406 / 21516 / 8236
Регистрация: 22.10.2011
Сообщений: 36,917
Записей в блоге: 12
08.11.2012, 18:26
Цитата Сообщение от znseday Посмотреть сообщение
Прямоугольник вообще не рисуется, когда окно находиться над док-понелью и готово "причалить".
В этот момент должно работать OnDockOver приемника, то есть, когда форма готова причалить, рисовать место причаливания должен не источник, а приемник.

Вот тут я показывал (правда на Дельфи), как подсветить "причал": Как перетащить и подсветить область, куда перетаскиваем объект
1
18 / 18 / 7
Регистрация: 20.03.2012
Сообщений: 585
08.11.2012, 19:07  [ТС]
Вот тут я показывал (правда на Дельфи), как подсветить "причал":
Такой способ для меня не подойдет, т.к. на панели уже есть пару причаленных окна, а я хочу на нее причалить еще и третье (т.е. произойдет перегруппировка окон). Как подсветить именно ту область, где окажется причаленное окно?
(Хочу реализовать такой же интерфейс, как в среде разработки Embarcadero Studio)
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33406 / 21516 / 8236
Регистрация: 22.10.2011
Сообщений: 36,917
Записей в блоге: 12
08.11.2012, 20:45
Цитата Сообщение от znseday Посмотреть сообщение
Как подсветить именно ту область, где окажется причаленное окно?
Ты вообще у приемника пробовал включать DragMode = dmAutomatic? Попробуй. Тогда система сама будет делать то, что тебе нужно. Прямоугольник, в который будет помещен новый элемент, хранится в Source.DockRect.

Тебе останется в Panel1DockOver просто отрисовывать прямоугольник, заданный этим самым Source.DockRect. Любым способом. Хочешь - создавай временную канву для панели, хочешь - рисуй через WinAPI.
0
18 / 18 / 7
Регистрация: 20.03.2012
Сообщений: 585
09.11.2012, 14:05  [ТС]
Цитата Сообщение от UI Посмотреть сообщение
Ты вообще у приемника пробовал включать DragMode = dmAutomatic? Попробуй.
Попробовал, не помогло. А вот кол-во глюков (которых и без того много) увеличилось, в частности, теперь не работают автоматические сплиттеры изменений размеров окон (когда несколько окон причалено на одну панель и они делят между собой пространство). Причем либо вылетает Access Violation, либо Exception c пустой строкой.

Добавлено через 1 час 0 минут
Цитата Сообщение от znseday Посмотреть сообщение
Сделал все как описано, только не с панелями, а с окнами. Есть два нюанса: 1) Прямоугольник рисуется начиная с местоположения мыши, а не с местоположения окна.
Как можно исправить эту ситуацию?
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33406 / 21516 / 8236
Регистрация: 22.10.2011
Сообщений: 36,917
Записей в блоге: 12
09.11.2012, 18:43
znseday, вот эту программку погоняй, тут по-моему, все реализовано, о чем ты спрашивал. Я ее тестировал под XP, собиралось всё под 2009-ым Билдером.
Вложения
Тип файла: zip dock_test.zip (11.6 Кб, 84 просмотров)
0
18 / 18 / 7
Регистрация: 20.03.2012
Сообщений: 585
09.11.2012, 21:17  [ТС]
Все супер, но после нескольких причаливаний и отчаливаний (общее число окон всегда не больше трех), все равно слетает с Access Vialation когда изменяешь размеры автоматически создаваемыми сплиттерами.
У меня Studio 2010, Win7.

Добавлено через 17 минут
Я обратил внимание, что в Вашем проекте все DragMode = dmManual. Это ли влияет на то, что нельзя изменить порядок расположения причаленных окон (т.е. например причалено два окна, одно расположено сверху, другое снизу). Я хочу мышкой перетащить верхнее окно на место нижнего, чтобы они поменялись местами. В Вашем проекте это можно сделать только если вытащить одно окно (двойным нажатием мыши по заголовку) и причалить его заново на новое место.

Добавлено через 40 минут
Цитата Сообщение от znseday Посмотреть сообщение
Я хочу мышкой перетащить верхнее окно на место нижнего, чтобы они поменялись местами. В Вашем проекте это можно сделать только если вытащить одно окно (двойным нажатием мыши по заголовку) и причалить его заново на новое место.
Задал DragMode = dmAutomatic для Dock-окна, теперь работает так, как хочу, но при отчаливании рисуется гигантский прямоугольник размером с DockPanel и рисуется не там где нужно. Попробую исправить.

Вопрос оффтопом: как перехватить событиe OnClick для pin-button? Или вопрос иначе: как скрывать и отображать всю DockTabSet, когда она пуста и когда появляются на вкладке новое окно, соответсвенно?
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33406 / 21516 / 8236
Регистрация: 22.10.2011
Сообщений: 36,917
Записей в блоге: 12
09.11.2012, 21:45
Цитата Сообщение от znseday Посмотреть сообщение
как скрывать и отображать всю DockTabSet, когда она пуста и когда появляются на вкладке новое окно, соответсвенно?
У DockTabSet есть события OnTabAdded и OnTabRemoved:

C++
1
2
3
4
5
6
7
8
9
void __fastcall TForm1::DockTabSet1TabRemoved(TObject *Sender)
{
    DockTabSet1->Visible = DockTabSet1->Tabs->Count;
}
 
void __fastcall TForm1::DockTabSet1TabAdded(TObject *Sender)
{
    DockTabSet1->Visible = True;
}
0
18 / 18 / 7
Регистрация: 20.03.2012
Сообщений: 585
10.11.2012, 21:42  [ТС]
Цитата Сообщение от znseday Посмотреть сообщение
Задал DragMode = dmAutomatic для Dock-окна, теперь работает так, как хочу, но при отчаливании рисуется гигантский прямоугольник размером с DockPanel и рисуется не там где нужно. Попробую исправить.
Вместо
C++
1
2
    pos.x -= this->Left;
    pos.y -= this->Top;
Нужно написать
C++
1
2
3
4
    TRect rect;
    GetWindowRect(this->Handle, &rect);
    pos.x -= rect.left;
    pos.y -= rect.top;
Тогда все работает как нужно.

Добавлено через 8 минут
Кстати, Access Vailation вылетает, когда меняешь размеры окна в режиме его привязке к DockTabSet, срываешь, причаливаешь, а затем опять пытаешься изменить размеры.

Добавлено через 23 часа 4 минуты
По поводу Access Vailation. Простой эксперимент. Запускаем проект, добавляем два окна, причаливаем их на панель (одно слева, второй справа, появляется вертикальный сплиттер), немного изменяем размеры окон (немного сдвигам сплиттер влево/вправо). Раскрываем главное окно на весь экран. Дотрагиваемся до сплиттера - Access Vailation.

Добавлено через 23 минуты
Все. Разобрался. Access Vailation срабатывает, когда сплиттер отпускаешь (отпускаешь нажатую кнопку мыши) над pin-buttin'ом. Даже сама Embarcadero Studio (2010) ломается, когда делаешь то же самое с ее интерфейсом.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
10.11.2012, 21:42
Помогаю со студенческими работами здесь

Drag@Dock и минимзация
Уважаемые форумчане! Делаю программу для создания и выведения на декстоп стикеров. Есть главная (родительская) форма FMain, и есть...

ТЕСТ НА DELPHI (DRAG&DOCK)
Мне нужно разработать программу на Delphi Тест на технологии Drag and Drop(скорее всего Drag and Dock). Т.е. грубо говоря на вопрос мы...

Drag & Dock для динамически созданных форм
Здравствуйте! Использую Delphi 6. По кнопке создаю несколько форм, в их onCreate прописываю для них: DragKind := dkDock; ...

Мерцание при перерисовке окна
Я хочу заменить одно из дочерних окон Outlook своим. Делаю это так: отлавливаю дескрипторы, мое окно ставлю поверх стандартного, размеры...

Мерцание окна при работе макроса
Здравствуйте! Как убрать мерцание окна, если макрос работает с несколькими книгами? Он сначала открывает все нужные книги, затем открывает...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели 8ATzM_2aurI
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2. Задача: запретить редактирование документа, если он открыт у другого пользователя. / / . . .
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои. А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
Модель ЗдрввоСохранения 7: больше работников, больше ресурсов.
anaschu 08.04.2026
работников и заданий может быть сколько угодно, но настроено всё так, что используется пока что только 20% kYBz3eJf3jQ
Дальние перспективы сервера - слоя сети с космологическим дизайном интефейса карты и логики.
Hrethgir 07.04.2026
Дальнейшее ближайшее планирование вывело к размышлениям над дальними перспективами. И вот тут может быть даже будут нужны оценки специалистов, так как в дальних перспективах всё может очень сильно. . .
Горе от ума
kumehtar 07.04.2026
Эта мне ментальная установка, что вот прямо сейчас, мол, мне для полного счастья не хватает (нужное вписать), и когда я этого достигну - тогда и полный кайф. Одна из самых сильных ловушек на пути. . . .
Использование значений реквизитов справочника в документе, с определенными условиями и правами
Maks 07.04.2026
1. Контроль срока действия договора Алгоритм из решения ниже реализован на примере нетипового документа "ЗаявкаНаРаботу", разработанного в конфигурации КА2. Задача: уведомлять пользователя, если. . .
Доступность команды формы по условию
Maks 07.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: сделать доступной кнопку (команда формы "ЗавершитьСписание") при. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru