Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/8: Рейтинг темы: голосов - 8, средняя оценка - 4.50
98 / 81 / 14
Регистрация: 26.07.2013
Сообщений: 594

Не перемещается TShape

04.04.2016, 10:27. Показов 1663. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
- Здравствуйте уважаемые участники форума! Столкнулся с проблемой.
Задача состоит в следующем:
1) Нажимаем клавишу мыши на основной форме. Прямо под курсором мыши (на основной форме) должен динамически
создаваться экземпляр TShape.
2) Далее, не отпуская клавиши мыши, перемещаем ее курсор по форме. Изображение TShape должно перемещаться
вместе с ним.
3) При отпускании клавиши мыши, экземпляр TShape должен уничтожаться.

- Пытаюсь добиться желаемого результата с помощью кода:
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
34
35
36
37
38
39
40
41
42
// указатель на динамически создаваемый Шейп.
TShape*  shp = NULL;
// радиус Шейпа по оси x.
const int  shp_rad_x = 3;
// радиус Шейпа по оси y.
const int  shp_rad_y = 12;
 
// .........
void __fastcall  TForm1::FormMouseDown( TObject*  Sender, TMouseButton  Button, TShiftState  Shift,
    int  X, int  Y )
{
  // *** динамический "Шейп". ***
  // создать динамический "Шейп".
  shp = new  TShape( this );
  shp->Parent = this;
  // размеры.
  shp->Width = shp_rad_x*2;
  shp->Height = shp_rad_y*2;
  // положение.
  shp->Top = Y - shp_rad_y;
  shp->Left = X - shp_rad_x;
  // цвет.
  shp->Brush->Color = clAqua;
  // подключение динамических обработчиков.
  shp->OnMouseDown  = &shpMouseDown;
  shp->OnMouseMove  = &shpMouseMove;
  shp->OnMouseUp      = &shpMouseUp;
//  // .........(появляется на основной форме и без этого.)
//  shp->Show();
  // эмуляция нажатия клавиши мыши на динамическом Шейпе.
  //(координаты мыши на основной форме пересчитываются в координаты мыши на Шейпе.)
  shpMouseDown( Sender, Button, Shift,              //(TObject*, TMouseButton, TShiftState,)
                X - shp->Left, Y - shp->Top );  //(int, int)
}
 
// .........
void __fastcall  TForm1::FormMouseUp( TObject*  Sender, TMouseButton  Button, TShiftState  Shift,
    int  X, int  Y )
{
  // уничтожение динамического Шейпа.
  delete  shp;  shp = NULL;
}
- Обработчики нажатия и перемещения мыши на Шейпе, которые привязываются к динамическому Шейпу, не
привожу. Там все стандартно, как для перемещения Шейпа по форме.

- В жизни первый пункт благополучно выполняется (динамический Шейп создается под курсором мыши). Но
при перетаскивании нажатой мыши по основной форме изображение Шейпа не едет за мышью !
- Подскажите пожалуйста, чего я не доделал? Или, может быть, такого вообще нельзя сделать в Билдере
простыми средствами?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
04.04.2016, 10:27
Ответы с готовыми решениями:

OnDblClick на TShape
Прошу помощи: Как реализовать OnDblClick на TShape?

динамический TShape
динамически создаю компоненты TShape.потом хочу левым кликом мыши по одному компоненту сохранить его координаты,а правым кликом по другой...

особенности TShape
При рисовании по форме зарисовывается Shape и его приходистя обновлять. При этом автоматически вызывается обработчик Form1->OnPaint, в...

9
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33376 / 21500 / 8236
Регистрация: 22.10.2011
Сообщений: 36,896
Записей в блоге: 11
04.04.2016, 10:44
Цитата Сообщение от Staut Посмотреть сообщение
Обработчики нажатия и перемещения мыши на Шейпе, которые привязываются к динамическому Шейпу, не привожу
Лучше было не просто привести код ПОЛНОСТЬЮ, а прикрепить проект, чтобы можно было взять, откомпилировать, и убедиться, что именно твой код не работает. А то я вот сейчас напишу свой обработчик, а он возьмет и заработает. И чего тогда? У меня ошибка?

Добавлено через 9 минут
Ну вот что я говорил:
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// ---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
}
 
bool IsMouseDown = false;
 
// указатель на динамически создаваемый Шейп.
TShape* shp = NULL;
// радиус Шейпа по оси x.
const int shp_rad_x = 3;
// радиус Шейпа по оси y.
const int shp_rad_y = 12;
 
int OldX, OldY;
 
// ---------------------------------------------------------------------------
void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button,
    TShiftState Shift, int X, int Y)
{
    // *** динамический "Шейп". ***
    // создать динамический "Шейп".
    shp = new TShape(this);
    shp->Parent = this;
    // размеры.
    shp->Width = shp_rad_x * 2;
    shp->Height = shp_rad_y * 2;
    // положение.
    shp->Top = Y - shp_rad_y;
    shp->Left = X - shp_rad_x;
    // цвет.
    shp->Brush->Color = clAqua;
    // подключение динамических обработчиков.
    shp->OnMouseDown = &Shape1MouseDown;
    shp->OnMouseMove = &Shape1MouseMove;
    shp->OnMouseUp = &Shape1MouseUp;
    // // .........(появляется на основной форме и без этого.)
    // shp->Show();
    // эмуляция нажатия клавиши мыши на динамическом Шейпе.
    // (координаты мыши на основной форме пересчитываются в координаты мыши на Шейпе.)
    Shape1MouseDown(Sender, Button, Shift,
        // (TObject*, TMouseButton, TShiftState,)
        X - shp->Left, Y - shp->Top); // (int, int)
}
 
// ---------------------------------------------------------------------------
void __fastcall TForm1::FormMouseUp(TObject *Sender, TMouseButton Button,
    TShiftState Shift, int X, int Y)
{
    // уничтожение динамического Шейпа.
    delete shp;
    shp = NULL;
}
 
// ---------------------------------------------------------------------------
void __fastcall TForm1::Shape1MouseDown(TObject *Sender, TMouseButton Button,
    TShiftState Shift, int X, int Y)
{
    OldX = X;
    OldY = Y;
    IsMouseDown = true;
}
 
// ---------------------------------------------------------------------------
void __fastcall TForm1::Shape1MouseMove(TObject *Sender, TShiftState Shift,
    int X, int Y)
{
    if (IsMouseDown)
    {
        TShape *shape = static_cast<TShape*>(Sender);
        shape->Left += X - OldX;
        shape->Top += Y - OldY;
    }
}
 
// ---------------------------------------------------------------------------
void __fastcall TForm1::Shape1MouseUp(TObject *Sender, TMouseButton Button,
    TShiftState Shift, int X, int Y)
{
    IsMouseDown = false;
}
 
// ---------------------------------------------------------------------------
void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift,
    int X, int Y)
 
{
    if (shp && IsMouseDown)
    {
        Shape1MouseMove(shp, Shift, X - shp->Left, Y - shp->Top);
    }
}
// ---------------------------------------------------------------------------
? Нормально все перемещается.
1
98 / 81 / 14
Регистрация: 26.07.2013
Сообщений: 594
04.04.2016, 10:46  [ТС]
- volvo, спасибо за быстрый ответ! Дело в том, что это махонький кусочек из большого проекта. Я сейчас
попытаюсь сделать маленькое пробное приложение с этой проблемой и тогда перешлю сюда целиком ...
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33376 / 21500 / 8236
Регистрация: 22.10.2011
Сообщений: 36,896
Записей в блоге: 11
04.04.2016, 10:48
Не надо ничего присылать, я выше дал фрагмент кода, который работает. Исправляй к своим реалиям.
0
98 / 81 / 14
Регистрация: 26.07.2013
Сообщений: 594
04.04.2016, 11:19  [ТС]
- Вот тестовое приложение.
Вложения
Тип файла: rar Test_ShapeMove.rar (6.20 Мб, 6 просмотров)
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33376 / 21500 / 8236
Регистрация: 22.10.2011
Сообщений: 36,896
Записей в блоге: 11
04.04.2016, 12:20
Ну я же написал выше, что нужно сделать:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void __fastcall  TForm1::shpMouseUp( TObject*  Sender, TMouseButton  Button, TShiftState  Shift,
    int  X, int  Y )
{
    IsMouseDown = false;
    // .........
// Следующие 2 строки не нужны, убери их:
//  FormMouseUp( Sender, Button, Shift, //(TObject*, TMouseButton, TShiftState)
//          X, Y ); //(int, int)
}
 
//##############################################################################
 
// А вот этот обработчик OnMouseMove формы добавь:
void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift, int X, int Y)
 
{
    if (shp && IsMouseDown)
    {
        shpMouseMove(shp, Shift, X - shp->Left, Y - shp->Top);
    }
}
Все прекрасно перемещается.
0
98 / 81 / 14
Регистрация: 26.07.2013
Сообщений: 594
04.04.2016, 13:17  [ТС]
- Насколько я понял, Вы делаете следующие вещи:
- 1) В среде создаете фиктивный Шейп Shape1 (можно даже с 0-ми размерами, чтобы не был виден).
- 2) Опять же в среде создаете для него обработчик Shape1MouseMove.
- 3) А потом в обработчике перемещения мыши на форме управление передается обработчику перемещения мыши
на фиктивном Шейпе (с объектом - динамический Шейп).
С отладчиком убедился, что работают только следующие обработчики:
FormMouseDown();
FormMouseMove();
FormMouseUp();

Shape1MouseMove();
shpMouseDown();
- Все остальные обработчики НЕ РАБОТАЮТ (не вызываются вообще). Я их вообще выключил или удалил!
Переменные X_Save и Y_Save (мои) и OldX и OldY (Ваши) - НЕ РАБОТАЮТ вообще. Я их закомментировал или удалил!
- И тем не менее проект работает правильно.

- Показываю листинг последнего (облегченного) проекта, хотя полного понимания, как оно все работает нет:
Файл 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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
//##### ..... #####
// .........
class   TForm1  : public    TForm
{
 
__published:    // IDE-managed Components
    TShape *Shape1;
    void __fastcall FormMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift,
          int X, int Y);
    void __fastcall FormMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift,
          int X, int Y);
 
//- void __fastcall Shape1MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift,
//-          int X, int Y);
    void __fastcall Shape1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y);
//- void __fastcall Shape1MouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift,
//-          int X, int Y);
    void __fastcall FormMouseMove(TObject *Sender, TShiftState Shift, int X, int Y);
 
 
 
private:    // User declarations
    // указатель на динамический Шейп.
    TShape*     shp;
 
    //##### ..... #####
//- // для сохранения координат Мыши.
//- int     X_Save;
//- int     Y_Save;
    // признак Нажатия левой клавиши Мыши.
    bool    IsMouseDown;
 
    // обработчик нажатия клавиши мыши на Шейпе.
    void __fastcall  TForm1::shpMouseDown( TObject*  Sender, TMouseButton  Button, TShiftState  Shift,
        int  X, int  Y );
//- // обработчик перемещения клавиши мыши на Шейпе.
//- void __fastcall  TForm1::shpMouseMove( TObject*  Sender, TShiftState  Shift,
//-     int  X, int  Y );
//- // обработчик отпускания клавиши мыши на Шейпе.
//- void __fastcall  TForm1::shpMouseUp( TObject*  Sender, TMouseButton  Button, TShiftState  Shift,
//-     int  X, int  Y );
 
public:     // User declarations
    // конструктор.
    __fastcall  TForm1(TComponent* Owner);
 
};
//------------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//------------------------------------------------------------------------------
Файл Unit1.cpp:
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
//##### ..... #####
// радиус динамического Шейпа по оси X.
int     shp_rad_x = 4;
// радиус динамического Шейпа по оси Y.
int     shp_rad_y = 12;
 
 
//##### ..... #####
// конструктор.
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    // фиктивный Шейп - НЕ имееи размеров.
    Shape1->Width = 0;
    Shape1->Height = 0;
    // фиктивный Шейп - невидим.
    Shape1->Visible = false;
    // указатель на динамический Шейп.
    shp = NULL; //(TShape*)
 
    // признак Нажатия левой клавиши Мыши.
    IsMouseDown = false;    //(bool)
}
 
//##############################################################################
// .........    //(РАБОТАЕТ !)
void __fastcall  TForm1::FormMouseDown( TObject*  Sender, TMouseButton  Button, TShiftState  Shift,
    int  X, int  Y )
{
    // *** динамический "Шейп". ***
    // создать динамический "Шейп".
    shp = new   TShape( this );
    shp->Parent = this;
    // размеры.
    shp->Width = shp_rad_x*2;
    shp->Height = shp_rad_y*2;
    // положение.
    shp->Top = Y - shp_rad_y;
    shp->Left = X - shp_rad_x;
    // цвет.
    shp->Brush->Color = clAqua;
    // динамические обработчики.
    shp->OnMouseDown    = &shpMouseDown;
//- shp->OnMouseMove    = &shpMouseMove;
//- shp->OnMouseUp      = &shpMouseUp;
    // .........
    shpMouseDown( Sender, Button, Shift,    //(TObject*, TMouseButton, TShiftState,)
            X - shp->Left, Y - shp->Top );  //(int, int)
}
 
// .........    //(РАБОТАЕТ !)
void __fastcall     TForm1::FormMouseMove( TObject*  Sender, TShiftState  Shift, int  X, int  Y )
 
{
    if ( shp    && IsMouseDown )
    {
        Shape1MouseMove(
            shp, Shift,
            X - shp->Left - shp_rad_x,  //(чтобы курсор мыши бы все время
            Y - shp->Top - shp_rad_y ); // посередине динамического Шейпа.)
    }
}
 
// .........    //(РАБОТАЕТ !)
void __fastcall  TForm1::FormMouseUp( TObject*  Sender, TMouseButton  Button, TShiftState  Shift,
    int  X, int  Y )
{
    // .........
    delete  shp;
    shp = NULL;
}
 
//##############################################################################
// .........    //(РАБОТАЕТ !)
void __fastcall  TForm1::shpMouseDown( TObject*  Sender, TMouseButton  Button, TShiftState  Shift,
    int  X, int  Y )
{
//- X_Save = X;
//- Y_Save = Y;
    IsMouseDown = true;
}
 
//##############################################################################
//-int      OldX = 0;
//-int      OldY = 0;
 
// .........    //(РАБОТАЕТ !)
void __fastcall TForm1::Shape1MouseMove(TObject *Sender, TShiftState Shift, int X,
          int Y)
{
    if ( IsMouseDown )
    {
        TShape*     shape = static_cast<TShape*>(Sender);
        shape->Left += X;   // - OldX;
        shape->Top += Y;    // - OldY;
    }
}
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33376 / 21500 / 8236
Регистрация: 22.10.2011
Сообщений: 36,896
Записей в блоге: 11
04.04.2016, 13:23
Блин, да ничего я не делаю. Я взял твой проект, убрал из него 2 указанных строки, и добавил еще один обработчик. Все. Прекрасно перемещается Shape цианидного цвета. Мне что, видео записать?

Вот он, твой же исправленный проект, развлекайся. Я даже exe не стал убирать, чтобы ты потом не сказал, что перекомпилировать не можешь, и мой код не работает:
Вложения
Тип файла: 7z Test_ShapeMove.7z (132.8 Кб, 5 просмотров)
1
98 / 81 / 14
Регистрация: 26.07.2013
Сообщений: 594
04.04.2016, 14:48  [ТС]
- Обработчик Shape1MouseMowe даже проще:
C++
1
2
3
4
5
6
7
8
9
10
11
// .........    //(РАБОТАЕТ !)
void __fastcall TForm1::Shape1MouseMove(TObject *Sender, TShiftState Shift, int X,
          int Y)
{
  if ( IsMouseDown )
  {
    shp = static_cast<TShape*>(Sender);
    shp->Left += X;    // - OldX;
    shp->Top += Y;    // - OldY;
  }
}
Добавлено через 28 минут
- Прошу прощения volvo, просто я не успеваю за Вами. Пока я что-то делаю, проверяю и пишу ответ, Вы уже делаете что-то новое, чего я еще не знаю. Откуда такое недоверие ко мне? Разве я упрекнул Вас в чем-то хоть словом?
- Просто в Ваших первых постах я увидел объект (Shape1). Я же не видел всего Вашего кода и предположил, что этот объект создан в среде, а не динамически. Мое последнее приложение (которое я показал в виде 2-х файлов) работает точно так же, как и Ваше приложение (только что пробовал Ваш exe-шник).
- Сейчас буду разбираться с Вашим приложением. Чем оно отличается от моего ...

Добавлено через 41 минуту
- Вот теперь разобрался во всем. Я в обработчике FormMouseDown() передал управление в обработчик shpMouseDown().
А в обработчике FormMouseMowe() не передал управление в обработчик shpMouseMove(). Там должно было быть:
C++
1
2
3
4
5
6
  // .........
  if ( shp && IsMouseDown )
  {
    // .........
    shpMouseMove( shp, Shift, X - shp->Left, Y - shp->Top );
  }
А обработчик shpMouseUp - вообще не нужен.
0
98 / 81 / 14
Регистрация: 26.07.2013
Сообщений: 594
05.04.2016, 10:54  [ТС]
- Если кому интересно, вот последний вариант найденного мной решения:
Вложения
Тип файла: rar Test_ShapeDraw.rar (83.5 Кб, 9 просмотров)
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
05.04.2016, 10:54
Помогаю со студенческими работами здесь

Наследование от TShape
Пишу класс наследник от TShape. Не получается переопределить конструктор... Выдает ошибку: Cannot find default conctructor to...

Компонент TShape
Здравствуйте всем) Скажите, пожалуйста, можно ли закрашивать Shape не полностью, а в процентном соотношении? (то есть 30% от фигуры...

Вращение TShape
Доброго времени суток! Возникла такая проблема... Пишу в Builder. На форме динамически создаются прямоугольники TShape и пользователь...

Равномерное движение TShape
Появилась проблемка. Есть фигура, которая движется по прямой, задающейся 2 точками. Высчитал приращения, но в 98% случаях приращение...

Движение TShape вместе с TImage
Изображение движется с помощью мыши. ПКМ ставит TShape на изображении. Нужно что бы при движении изображения вмести с ним двигались и...


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru