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

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

07.11.2012, 18:58. Показов 4572. Ответов 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
33195 / 21491 / 8233
Регистрация: 22.10.2011
Сообщений: 36,879
Записей в блоге: 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
33195 / 21491 / 8233
Регистрация: 22.10.2011
Сообщений: 36,879
Записей в блоге: 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
33195 / 21491 / 8233
Регистрация: 22.10.2011
Сообщений: 36,879
Записей в блоге: 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
33195 / 21491 / 8233
Регистрация: 22.10.2011
Сообщений: 36,879
Записей в блоге: 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
33195 / 21491 / 8233
Регистрация: 22.10.2011
Сообщений: 36,879
Записей в блоге: 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
Ответ Создать тему
Новые блоги и статьи
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США. Нашел на реддите интересную статью под названием «Кто-нибудь знает, где получить бесплатный компьютер или. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru