Форум программистов, компьютерный форум, киберфорум
Наши страницы
C++ Builder
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 5.00/5: Рейтинг темы: голосов - 5, средняя оценка - 5.00
Sergey_03
20 / 8 / 4
Регистрация: 15.12.2014
Сообщений: 630
1

Реализация через PopupMenu функций copy and paste в DrawGrid

14.03.2016, 13:06. Просмотров 971. Ответов 42
Метки нет (Все метки)

Доброго дня! Встала задача реализовать данный сабж в пределах одного DrawGrid. При выделение одной, а еще лучше диапазона ячеек. В голову приходит некий еще один, временный DrawGrid (промежуточный хранитель). Как это правильно реализовать вообще? Может есть пример где - не найти. Спасибо.
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.03.2016, 13:06
Ответы с готовыми решениями:

Реализация Copy/Paste
Добрый день!!!!! уважаемые форумчане подскажите кто как реализует copy/paste?????? Есть грид,...

Copy >> Paste
Тянет ли копи паст под низкочастотники? Не в ту категорию пост запихал ( Как исправить?

Copy/Paste
доброго! вот у меня тут возник такой вопрос: 1.Сopy 2.Paste итак вот вопросы 1.Как сделать...

Copy-Paste VIM
Как выделить и сделать копи-пейст?

RichTextBox и Copy/Paste
В общем столкнулся с проблемой копирования и вставки данных из буфера обмена в поле RichTextBox. ...

42
volvo
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
28036 / 18691 / 7366
Регистрация: 22.10.2011
Сообщений: 32,744
Записей в блоге: 6
14.03.2016, 13:23 2
Что есть в DrawGrid на момент копирования?
1
Sergey_03
20 / 8 / 4
Регистрация: 15.12.2014
Сообщений: 630
14.03.2016, 13:26  [ТС] 3
Цитата Сообщение от volvo Посмотреть сообщение
Что есть в DrawGrid на момент копирования
или пусто, или картинки 50 на 50
0
volvo
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
28036 / 18691 / 7366
Регистрация: 22.10.2011
Сообщений: 32,744
Записей в блоге: 6
14.03.2016, 13:34 4
Ну в таком случае (поскольку сами картинки не хранятся, а только отображаются в гриде, по какому-то признаку выбираясь из контейнера - это либо имя файла, либо индекс в ImageList-е) я бы просто при выборе Copy запоминал бы две вещи: 1 - размер выделенной части грида, 2 - содержимое выделенных ячеек (собственно, те самые признаки, по которым потом в DrawCell рисуется картинка). А потом, при Paste, 1) проверять, совпадает ли размер выделенной области с тем, который был запомнен при копировании, и 2) если да - то проходить по ячейкам и копировать информацию из запоменной...
1
14.03.2016, 13:34
Sergey_03
20 / 8 / 4
Регистрация: 15.12.2014
Сообщений: 630
14.03.2016, 13:43  [ТС] 5
Цитата Сообщение от volvo Посмотреть сообщение
в таком случае
признак выбора картинок - имя файла
Цитата Сообщение от volvo Посмотреть сообщение
запоминал бы две вещи:
если не затруднит - как это в С++ реализовать правильно. Хотя бы примерный алгоритм событий и операторов.
Спасибо!
0
volvo
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
28036 / 18691 / 7366
Регистрация: 22.10.2011
Сообщений: 32,744
Записей в блоге: 6
14.03.2016, 15:14 6
Как-то вот так:
C++
1
2
3
4
5
6
// в классе формы:
private:    // User declarations
    String GridData[12][10]; // у меня на форме грид размером 12х10
 
    TPoint CopySize;
    TStringList *CopyData;
и реализации:
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
// ---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
    GridData[0][0] = "box_in.bmp"; // начальные установки, для теста
    GridData[3][3] = "box_out.bmp";
    CopyData = new TStringList();
}
 
// ---------------------------------------------------------------------------
void __fastcall TForm1::DrawGrid1DrawCell(TObject *Sender, int ACol, int ARow,
    TRect &Rect, TGridDrawState State)
{
    if (!GridData[ACol][ARow].IsEmpty())
    {
        std::auto_ptr<Graphics::TBitmap>bm(new Graphics::TBitmap);
        bm->LoadFromFile(ExtractFilePath(ParamStr(0)) + "pics\\" + GridData[ACol][ARow]);
        DrawGrid1->Canvas->Draw(Rect.Left, Rect.Top, bm.get());
    }
}
// ---------------------------------------------------------------------------
 
void __fastcall TForm1::Copy1Click(TObject *Sender)
{
    TGridRect sel = DrawGrid1->Selection;
    CopySize = Point(sel.Right - sel.Left + 1, sel.Bottom - sel.Top + 1);
 
    CopyData->Clear();
    for (int i = sel.Left; i <= sel.Right; i++)
        for (int j = sel.Top; j <= sel.Bottom; j++)
        {
            CopyData->Add(GridData[i][j]);
        }
}
// ---------------------------------------------------------------------------
 
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
    delete CopyData;
}
 
void __fastcall TForm1::Paste1Click(TObject *Sender)
{
    TGridRect sel = DrawGrid1->Selection;
    if (sel.Right - sel.Left + 1 == CopySize.X &&
        sel.Bottom - sel.Top + 1 == CopySize.Y)
    {
        int k = 0;
        for (int i = sel.Left; i <= sel.Right; i++)
            for (int j = sel.Top; j <= sel.Bottom; j++)
                GridData[i][j] = CopyData->Strings[k++];
        DrawGrid1->Invalidate();
    }
    else
        ShowMessage(L"Несовпадающие по размеру области грида");
}
1
Sergey_03
20 / 8 / 4
Регистрация: 15.12.2014
Сообщений: 630
14.03.2016, 16:05  [ТС] 7
Спасибо! А возможно копировать не по признаку, а просто канву - выделенную область ячеек в область ячеек начиная с заново выделенной ячейки? Можно в общем то и так сделать, но картинки разные и вычислить ранее заданные условия, которые были при начальном заполнении, очень трудно. А все признаки я потом распихал бы по структурам путем копирования привязанных к изначально выделенным элементам.

Добавлено через 30 минут
У меня там есть признак при выделении одной или нескольких ячеек
C++
1
DrawGrid1->Canvas->Pen->Color=clYellow;
может его можно как то использовать?
0
volvo
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
28036 / 18691 / 7366
Регистрация: 22.10.2011
Сообщений: 32,744
Записей в блоге: 6
14.03.2016, 16:12 8
Цитата Сообщение от Sergey_03 Посмотреть сообщение
А возможно копировать не по признаку, а просто канву
Нет. Именно по той причине, которую я озвучил выше: грид не хранит данные, а только их отображает. При малейшей необходимости перерисовать грид (или его часть), то, что ты накопируешь бесследно исчезнет.

Добавлено через 3 минуты
Цитата Сообщение от Sergey_03 Посмотреть сообщение
У меня там есть признак
Это признак того, что ячейки были выделены. Тебя для копирования должно интересовать, как именно представлены твои рисунки, что они у тебя отображаются в правильных ячейках при рисовании грида. Вот именно эту информацию и нужно копировать.
1
Sergey_03
20 / 8 / 4
Регистрация: 15.12.2014
Сообщений: 630
14.03.2016, 17:07  [ТС] 9
Цитата Сообщение от volvo Посмотреть сообщение
Нет. Именно по той причине,
я понял. спасибо. Создал тестовый проект - ругается.
Часть ошибок убрал(большие X,Y на маленькие - было уже - 2009 бульдер)
дальше на
C++
1
std::auto_ptr<Graphics::TBitmap>bm(new Graphics::TBitmap);
ругается
C++
1
2
3
4
5
[BCC32 Error] Unit1.cpp(31): E2108 Improper use of typedef 'TBitmap'
[BCC32 Error] Unit1.cpp(31): E2268 Call to undefined function 'bm'
[BCC32 Error] Unit1.cpp(32): E2288 Pointer to structure required on left side of -> or ->*
[BCC32 Error] Unit1.cpp(33): E2294 Structure required on left side of . or .*
[BCC32 Error] Unit1.cpp(33): E2285 Could not find a match for 'TCanvas::Draw(long,long,undefined)'
Добавлено через 8 минут
ошибся конечно. ругается на
C++
1
std::auto_ptr<Graphics::TBitmap>bm(new Graphics::TBitmap);
Добавлено через 8 минут
получилось
C++
1
2
3
4
5
static Graphics::TBitmap *bm;
        bm = new Graphics::TBitmap;
       //   std::auto_ptr<Graphics::TBitmap>bm(new Graphics::TBitmap);
        bm->LoadFromFile(ExtractFilePath(ParamStr(0)) + GridData[ACol][ARow]);
        DrawGrid1->Canvas->Draw(Rect.Left, Rect.Top, bm);
0
volvo
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
28036 / 18691 / 7366
Регистрация: 22.10.2011
Сообщений: 32,744
Записей в блоге: 6
14.03.2016, 17:10 10
Ну, насколько я помню, у меня и в 2009 подобная конструкция работала:
C++
1
std::auto_ptr<TBitmap> bm(new TBitmap);
1
Sergey_03
20 / 8 / 4
Регистрация: 15.12.2014
Сообщений: 630
14.03.2016, 17:14  [ТС] 11
а возможно не сравнивать выделенные области? просто вставлять выделенный диапазон с выбранной ячейки и далее?
C++
1
2
CopySize.x =sel.Right - sel.Left + 1;
        CopySize.y=sel.Bottom - sel.Top + 1 ;
не хочет.
0
nick42
Практикантроп
4485 / 2445 / 445
Регистрация: 23.09.2011
Сообщений: 5,250
14.03.2016, 17:31 12
Цитата Сообщение от Sergey_03 Посмотреть сообщение
ошибся конечно. ругается на
C++Выделить код
1
std::auto_ptr<Graphics::TBitmap>bm(new Graphics::TBitmap);
А #include <vector> добавлено? (потому что у меня с ним "не ругается").
1
Sergey_03
20 / 8 / 4
Регистрация: 15.12.2014
Сообщений: 630
14.03.2016, 17:35  [ТС] 13
Цитата Сообщение от nick42 Посмотреть сообщение
#include <vector> добавлено?
конечно не добавил. Сейчас добавил - все ок стало. Спасибо.
0
volvo
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
28036 / 18691 / 7366
Регистрация: 22.10.2011
Сообщений: 32,744
Записей в блоге: 6
14.03.2016, 17:39 14
Цитата Сообщение от Sergey_03 Посмотреть сообщение
не хочет
Что значит "не хочет"?
1
Sergey_03
20 / 8 / 4
Регистрация: 15.12.2014
Сообщений: 630
14.03.2016, 17:48  [ТС] 15
Цитата Сообщение от volvo Посмотреть сообщение
Что значит "не хочет"?
одна ячейка заполняется, которая выделена.
я попробовал просто, но это не верно вообще по моему.
Видимо как то нужно при вставке определять ему Selection ячеек, начиная с выделенной такое же, что и при начальном выделении при копирование.
0
volvo
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
28036 / 18691 / 7366
Регистрация: 22.10.2011
Сообщений: 32,744
Записей в блоге: 6
14.03.2016, 17:49 16
Ты бы проект прикрепил свой. Или мне сделать проект на BCB6, чтобы ты его смог открыть?
1
Sergey_03
20 / 8 / 4
Регистрация: 15.12.2014
Сообщений: 630
14.03.2016, 17:55  [ТС] 17
так у меня 2009. все работает и на XE тоже самое я думаю, просто единственный момент, что хотел не привязываться к выделенной области для вставки, а иметь возможность вставить, начиная с выделенной ячейки. проблема может возникнуть, что выделил например 10 ячеек, а вставляю в место, где с права меньше 10 - тогда на новую строку переносить бы...там еще будет куча условий и обработок - потом прикручу к этой основе.
0
volvo
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
28036 / 18691 / 7366
Регистрация: 22.10.2011
Сообщений: 32,744
Записей в блоге: 6
14.03.2016, 18:30 18
Цитата Сообщение от Sergey_03 Посмотреть сообщение
иметь возможность вставить, начиная с выделенной ячейки
Вот так тогда:
C++
1
2
3
4
5
6
7
8
9
void __fastcall TForm1::Paste1Click(TObject *Sender)
{
    TGridRect sel = DrawGrid1->Selection;
    int k = 0;
    for (int i = 0; i < CopySize.x; i++)
        for (int j = 0; j < CopySize.y; j++)
            GridData[DrawGrid1->Selection.Left + i][DrawGrid1->Selection.Top + j] = CopyData->Strings[k++];
    DrawGrid1->Invalidate();
}
1
Sergey_03
20 / 8 / 4
Регистрация: 15.12.2014
Сообщений: 630
14.03.2016, 19:29  [ТС] 19
Цитата Сообщение от volvo Посмотреть сообщение
Вот так тогда:
да, работает,спасибо.
Цитата Сообщение от Sergey_03 Посмотреть сообщение
выделил например 10 ячеек, а вставляю в место, где с права меньше 10 - тогда на новую строку переносить бы..
это проблема, или можно как то
0
volvo
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
28036 / 18691 / 7366
Регистрация: 22.10.2011
Сообщений: 32,744
Записей в блоге: 6
14.03.2016, 20:08 20
Да тут вообще ничего не проблема:
C++
1
2
3
4
5
6
7
8
9
10
void __fastcall TForm1::Paste1Click(TObject *Sender)
{
    TGridRect sel = DrawGrid1->Selection;
    int k = 0;
    for (int i = 0; i < CopySize.x; i++)
        for (int j = 0; j < CopySize.y; j++)
            GridData[(DrawGrid1->Selection.Left + i) % 12]
                    [(DrawGrid1->Selection.Left + i) / 12 + DrawGrid1->Selection.Top + j] = CopyData->Strings[k++];
    DrawGrid1->Invalidate();
}
, только следи, чтобы за нижнюю границу не переваливало 12 у меня - это DrawGrid1->ColCount
1
14.03.2016, 20:08
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
14.03.2016, 20:08

Запрет на copy/paste
как сделать так чтоб при открытии ексель запускалась прога которая блокирует копирование и вставку ?

Не работает Copy\paste
Доброго времени суток. Не ожидал что увижу такое... в базе не работает Copy\Paste Посмотрел...

Copy/Paste текста в Word
Уважаемые! Не сочтите за труд, подскажите - что не так делаю? Нужно: - открыть в фоновом режиме...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.