Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

строка в ячейке stringgrid

27K
20 января 2010 года
alexmalyaev
35 / / 25.07.2008
Здравствуйте
StringGrid1->Cells[0][0] = "слово1 слово2 слово3"
Помогите пожалуйста вывести каждое слово с новой строки
416
20 января 2010 года
MaitreDesir
380 / / 02.01.2008
Цитата: alexmalyaev
Здравствуйте
StringGrid1->Cells[0][0] = "слово1 слово2 слово3"
Помогите пожалуйста вывести каждое слово с новой строки



Либо используем функцию типа split для разделения строки по символу "пробел", либо ручками в цикле определяем pos (strpos?) символа #32 и раздираем строку до следующего #32 или конца строки.

27K
21 января 2010 года
alexmalyaev
35 / / 25.07.2008
Спасибо, что откликнулись!
У меня ячейка формируется из строки, которая в свою очередь формируется из нескольких полей БД. В подсознании я понимаю, что надо разделить строку по какому нибудь делителю и вывести каждый кусок с сновой строки. Вообщем как это реализовать в StringGrid1DrawCell не знаю и в инете ничего нет. Сделал все и раскрасил как надо и фокус обвел как задумывал, а тут уперся. Прогу то почти доделал.
Понимающих прошу откликнутья!
1.9K
21 января 2010 года
GreenRiver
451 / / 20.07.2008
Цитата: alexmalyaev
Спасибо, что откликнулись!
У меня ячейка формируется из строки, которая в свою очередь формируется из нескольких полей БД. В подсознании я понимаю, что надо разделить строку по какому нибудь делителю и вывести каждый кусок с сновой строки. Вообщем как это реализовать в StringGrid1DrawCell не знаю и в инете ничего нет. Сделал все и раскрасил как надо и фокус обвел как задумывал, а тут уперся. Прогу то почти доделал.
Понимающих прошу откликнутья!


Года два назад пробовал сделать тоже самое, не нашел штатного решения.
Только вручную определять какой высоты будет текст, если ограничить его по ширине, ресайзить высоту строки и вручную рисовать его...
Кстати, какая версия билдера? Возможно в последней есть такой функционал.
Либо можно попробовать другие сторонние гриды... Стандартный в Builder 6 через чур примитивен...

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

27K
21 января 2010 года
alexmalyaev
35 / / 25.07.2008
builder 6
Я уже столько сделал и мне осталось только вот этот функционал реализовать. Нашел только в дельфи, может кто поможет перевести в ВСВ

Многострочные ячейки в StringGrid.
Сперва необходимо установить свойство DefaultDrawing в False

procedure TForm1.StringGrid1DrawCell(Sender: TObject;
Col, Row: Longint;
Rect: TRect;
State: TGridDrawState);
var
Line1: string;
Line2: string;
ptr: integer;
padding: integer;
hGrid: TStringGrid;

begin
hGrid:= (Sender as TStringGrid);
ptr := Pos(';', hGrid.Cells[Col, Row]);
if ptr > 0 then
begin
Line1 := Copy(hGrid.Cells[Col, Row], 1, ptr - 1);
Line2 := Copy(hGrid.Cells[Col, Row], ptr + 1,
Length(hGrid1.Cells[Col,Row]) - ptr);
end
else Line1 := hGrid.Cells[Col, Row];
hGrid.Canvas.FillRect(Rect);
hGrid.Canvas.TextOut(Rect.Left, Rect.Top + 2, Line1);
if ptr > 0 then
hGrid.Canvas.TextOut(Rect.Left, Rect.Top -
hGrid.Canvas.Font.Height + 3, Line2);
end;
1.9K
21 января 2010 года
GreenRiver
451 / / 20.07.2008
Что здесь переводить-то? Библиотека VCL, что в Delphi что в Builder'е одна и та же... Код получится один в один почти.
К рисованию имеет отношение этот кусок:
 
Код:
TStringGrid *hGrid = (TStringGrid*)Sender;
hGrid->Canvas->FillRect(Rect);
hGrid->Canvas->TextOut(Rect->Left, Rect->Top + 2, Line1);
hGrid->Canvas->TextOut(Rect->Left, Rect->Top + hGrid->Canvas->Font->Height + 3, Line2);

Кстати в примере не раскрыта тема высоты строки.
27K
21 января 2010 года
alexmalyaev
35 / / 25.07.2008
высота строки и ширина колонки у меня фиксированные, т.к. я заранее знаю длину записей.
Попробовал этот пример в разных настройках.
Байда какая-то - первая строка отрисовывается нормально,
вторая то появляется то исчезает
27K
21 января 2010 года
alexmalyaev
35 / / 25.07.2008
Вот вариант через API

TStringGrid *hGrid = (TStringGrid*)Sender;
char *Line1 = new char[100];
Line1="11111111! 111111111111111111111111! 111111111! 111111111!";

hGrid->Canvas->FillRect(Rect);
DrawText(hGrid->Canvas->Handle,(Line1), strlen(Line1), &Rect,DT_WORDBREAK);

Работает без глюков но не переносит по разделителю.
Все равно что-нибудь вымучаю
27K
21 января 2010 года
alexmalyaev
35 / / 25.07.2008
проблема решена!

TStringGrid *hGrid = (TStringGrid*)Sender;
char *Line1 = new char[100];
Line1="test\r\ntest\r\ntest\r\ntest\r\ntest\r\n";

hGrid->Canvas->FillRect(Rect);
DrawText(hGrid->Canvas->Handle,(Line1), strlen(Line1), &Rect,DT_WORDBREAK);

Спасибо кто поддержал!
297
23 января 2010 года
koodeer
1.2K / / 02.05.2009
Цитата: alexmalyaev
проблема решена!

char *Line1 = new char[100];
Line1="test\r\ntest\r\ntest\r\ntest\r\ntest\r\n";



Решив одну проблему, автор создал себе другую: утечка памяти детектед.

12K
23 января 2010 года
Ghox
297 / / 26.07.2009
Цитата: koodeer
Решив одну проблему, автор создал себе другую: утечка памяти детектед.


Предложу вариант, как можно сделать правильно (чтобы утечки памяти не было):

 
Код:
char *Line1 = new char[100];
    strcpy(Line1, "test\r\ntest\r\ntest\r\ntest\r\ntest\r\n");
7
23 января 2010 года
@pixo $oft
3.4K / / 20.09.2006
Эммм…а разве выделение памяти по new не освобождает от её освобождения?(тавтология,ну да бог с ней)
1
23 января 2010 года
kot_
7.3K / / 20.01.2000
Цитата: Ghox
Предложу вариант, как можно сделать правильно (чтобы утечки памяти не было):
 
Код:
char *Line1 = new char[100];
    strcpy(Line1, "test\r\ntest\r\ntest\r\ntest\r\ntest\r\n");


и что же здесь "правильного"?

12K
23 января 2010 года
Ghox
297 / / 26.07.2009
Цитата: @pixo $oft
Эммм…а разве выделение памяти по new не освобождает от её освобождения?(тавтология,ну да бог с ней)


Нет, от освобождения памяти не избавляет. Но, как я понимаю, проблема утечки памяти здесь не в том, что автор выделил память с помощью new, а потом не удалил с помощью delete[] (тем более что автор привел не весь код программы, и мог сделать удаление позже). Проблема в том, что после выполнения присваивания

 
Код:
Line1="test\r\ntest\r\ntest\r\ntest\r\ntest\r\n";

указатель Line1 указывает уже не на ту область памяти, которая была до этого выделена с помощью new, а на начало константной строки "test\r\ntest\r\ntest\r\ntest\r\ntest\r\n", содержащейся в коде программы (или в области памяти, в которой хранятся констатные данные программы). И выделенная с помощью new область памяти теперь уже никак не связана с указателем. И освободить ее уже в принципе нельзя, даже если потом выполнить delete[]. Т.е. память выделена, а освободить ее (или как-то использовать) - нельзя.

Небольшой тест иллюстрирующий вышесказанное:
Код:
#include <iostream>
#include <cstring>
using namespace std;

void testNewDelete()
{
    char *Line1 = new char[10000000];
    Line1 = "test\r\ntest\r\ntest\r\ntest\r\ntest\r\n";
    // а если заменить на
    // strcpy(Line1, "test\r\ntest\r\ntest\r\ntest\r\ntest\r\n");
    // то утечки нет
    delete[] Line1;
}

int main()
{
    unsigned int i = 0;
    while(i++ < 1000)
        testNewDelete();
}

При его выполнении, программа вылетает из-за нехватки памяти. Если произвести описанную в коде замену - то программа отрабатывает нормально.

Цитата: kot_
и что же здесь "правильного"?


Ну скажем так, ИМХО этот вариант более правильный, чем у автора, в том плане что в нем нет проблем которые есть в том варианте, который был у автора (хотя может быть конечно, что есть другие промахи):

1. Нет описанной утечки памяти, и есть возможность освободить память с помощью delete.

2. Указатель остается указателем на область памяти, содержимое которой можно менять, и по этому указателю можно потом записывать новое содержимое - перезаписывать строку (например, использовать указатель для передачи в какую-нибудь функцию в качестве аргумента, которая записывает по переданному указателю строку - результат своего выполнения). Чего нельзя сделать (будет какой-нибудь access violation) после присваивания указателю начала константной строки.

Но если автору перезаписывать строку не требуется (требуется передать строку в функцию один раз и все) - то тогда можно присвоить указатель константной строке (но тогда без использования new):

 
Код:
char *Line1 = "test\r\ntest\r\ntest\r\ntest\r\ntest\r\n";

    hGrid->Canvas->FillRect(Rect);
    DrawText(hGrid->Canvas->Handle,(Line1), strlen(Line1), &Rect,DT_WORDBREAK);
27K
25 января 2010 года
alexmalyaev
35 / / 25.07.2008
в оригинале у меня так:

void __fastcall TFrmMain::FormActivate(TObject *Sender)
{
.....

// Заполняем Стринггрид
for(int i = 0; i < StringGrid1->RowCount; i++) {
for(int j = 0; j < StringGrid1->ColCount; j++) {
if(quancells == Queue->RecordCount) break;
AnsiString text;
text = Queue->FieldByName("condition")->AsString;
text = text + " ";
text = text + Queue->FieldByName("number")->AsString;
text = text + "\nпозывной - ";
text = text + Queue->FieldByName("sign")->AsString;
text = text + "\nрайон дис. - ";
text = text + Queue->FieldByName("region")->AsString;
text = text + "\nвыполн. заявок - ";
text = text + Queue->FieldByName("quantity")->AsString;
text = text + "\nн.с. - ";
text = text + Queue->FieldByName("inittime")->AsString;
StringGrid1->Cells[j] = text;
Queue->Next(); quancells++;
}
}
....
}
//-----------------------------------------------------------

void __fastcall TFrmMain::StringGrid1DrawCell(TObject *Sender, int ACol,
int ARow, TRect &Rect, TGridDrawState State)
{
// Здесь прорисовка текста
DrawText(StringGrid1->Canvas->Handle,
StringGrid1->Cells[ACol][ARow].c_str(), strlen(StringGrid1->Cells[ACol][ARow].c_str()),
&Rect, DT_WORDBREAK); // Выводим текст в ячейку используя ф-цию WinAPI
}
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог