void __fastcall TForm1::Edit1KeyPress(TObject *Sender, char &Key)
{
if (Key != '+')
Key = 0;
}
лагает C++Builder
конечно (как всегда) переустановил, непомогло. потом ось переустановил, непомогло. и главное непонятно чего? рама берет 50 мб, комп тоже не слабый. в проекте 1 форма, на ней пока 202 едита, примерно стоко же лейб и одна кнопка.
может подскажет ктото...
Тормоза, как мне кажется, вызванны именно таким огромным количеством компонентов на форме. IMHO нужно перепроектировать приложение, с тем чтобы избавиться от такого монстрообразного окна. Так нельзя делать даже из-за элементрарных соображений юзабилити. Психологи говорят, что человек с трудом воспринимает более пяти элементов. Работать с таким объемом информации на одной форме - крайне неэффективный раздражающий процесс. Я думаю, что более рациональным решением в данном случае будет создание некого wizard'а, много форм, но с ограниченным, адекватно воспринимаемым объемом информации. Это позволит и пользователю удобно работать с программой, и Builder тормозить меньше будет.
вставил во вложение архив со скрином. я её делаю по рисунку в книге (можно сказать таки копия), это токо половина
Судя по скриншоту, наверняка ДевелоперСтудио2006... жутко баговое... лучше уж 6.0 или 2007 (по поводу где достать - в личку)...
Цитата: flat
Тормоза, как мне кажется, вызванны именно таким огромным количеством компонентов на форме. IMHO нужно перепроектировать приложение, с тем чтобы избавиться от такого монстрообразного окна. Так нельзя делать даже из-за элементрарных соображений юзабилити. Психологи говорят, что человек с трудом воспринимает более пяти элементов. Работать с таким объемом информации на одной форме - крайне неэффективный раздражающий процесс. Я думаю, что более рациональным решением в данном случае будет создание некого wizard'а, много форм, но с ограниченным, адекватно воспринимаемым объемом информации. Это позволит и пользователю удобно работать с программой, и Builder тормозить меньше будет.
+1. сделать визард или разбить всё по Tab'ам (TPageControl), ну а если уж прям НАДО сделать всё на 1 форме... и в одном окне, то делай это динамически, при создании формы создавай кучу элементов... тока удалить не забудь потом ;)
А по положению курсора и клика кнопкой подставлять для ввода 1 объект TEdit. Будет всего один метод - перерисовки формы, одна структура данных или класс с массивами, и один TEdit.
Вообщето тормоза не из-за количества компонентов (я и с болишим количеством работал на 6-ом). Но если это все-таки из-за количества, то попробуй просто разнести компоненты по панелям, а уже панели ложить на форму. Ребята правы - глючность Builder 2006 просто поражает. Я вижу что на этой форме нет ни скинов не других рюшечек, а это значит можно и просто в Visualn C++ MFC использовать - результат: тормозить 100% не будет;
можно не извращаться, а просто положить TStringGrid или что-то подобное, но удобнее и покрасивее.
Цитата: Snikex
Ребята правы - глючность Builder 2006 просто поражает.
Может попробывать установить все сервис паки и заплатки c официального сайта, которые выпущены для Builder 2006?
для всех "квадратиков" надо
Код:
и потом еще для каждого (пример 1 едит)
Код:
void __fastcall TForm1::Edit1Change(TObject *Sender)
{
if (Edit1->Text.Length()==1)
{
Edit6->Clear();
Edit11->Clear();
Edit16->Clear();
Edit21->Clear();
}
{
if (Edit1->Text.Length()==1)
{
Edit6->Clear();
Edit11->Clear();
Edit16->Clear();
Edit21->Clear();
}
кнопка все это дело считает (пример токо для одного блока (25 едитов))
Код:
double z1,z2,z3,z4,z5;
int i1,j1,u1,o1,p1;
int i2,j2,u2,o2,p2;
int i3,j3,u3,o3,p3;
int i4,j4,u4,o4,p4;
int i5,j5,u5,o5,p5;
z1=0; z2=0; z3=0; z4=0; z5=0;
i1=0; i2=0; i3=0; i4=0; i5=0;
j1=0; j2=0; j3=0; j4=0; j5=0;
u1=0; u2=0; u3=0; u4=0; u5=0;
o1=0; o2=0; o3=0; o4=0; o5=0;
p1=0; p2=0; p3=0; p4=0; p5=0;
if (Edit1->Text=="+") {i1=2;}
else {i1=0; }
if (Edit2->Text=="+") {j1=2;}
else {j1=0; }
if (Edit3->Text=="+") {u1=2;}
else {u1=0; }
if (Edit4->Text=="+") {o1=2;}
else{o1=0; }
if (Edit5->Text=="+") {p1=2;}
else {p1=0; }
z1=(i1+j1+u1+o1+p1);
if (Edit6->Text=="+") {i2=1;}
else {i2=0; }
if (Edit7->Text=="+") {j2=1;}
else {j2=0; }
if (Edit8->Text=="+") {u2=1;}
else {u2=0; }
if (Edit9->Text=="+") {o2=1;}
else{o2=0; }
if (Edit10->Text=="+") {p2=1;}
else {p1=0; }
z2=(i2+j2+u2+o2+p2);
if (Edit11->Text=="+") {i3=0;}
else {i3=0; }
if (Edit12->Text=="+") {j3=0;}
else {j3=0; }
if (Edit13->Text=="+") {u3=0;}
else {u3=0; }
if (Edit14->Text=="+") {o3=0;}
else{o3=0; }
if (Edit15->Text=="+") {p3=0;}
else {p3=0; }
z3=(i3+j3+u3+o3+p3);
if (Edit16->Text=="+") {i4=-1;}
else {i4=0; }
if (Edit17->Text=="+") {j4=-1;}
else {j4=0; }
if (Edit18->Text=="+") {u4=-1;}
else {u4=0; }
if (Edit19->Text=="+") {o4=-1;}
else{o4=0; }
if (Edit20->Text=="+") {p4=-1;}
else {p4=0; }
z4=(i4+j4+u4+o4+p4);
if (Edit21->Text=="+") {i5=-2;}
else {i5=0; }
if (Edit22->Text=="+") {j5=-2;}
else {j5=0; }
if (Edit23->Text=="+") {u5=-2;}
else {u5=0; }
if (Edit24->Text=="+") {o5=-2;}
else{o5=0; }
if (Edit25->Text=="+") {p5=-2;}
else {p5=0; }
z5=(i5+j5+u5+o5+p5);
Label1->Caption=((z1+z2+z3+z4+z5)/5);
int i1,j1,u1,o1,p1;
int i2,j2,u2,o2,p2;
int i3,j3,u3,o3,p3;
int i4,j4,u4,o4,p4;
int i5,j5,u5,o5,p5;
z1=0; z2=0; z3=0; z4=0; z5=0;
i1=0; i2=0; i3=0; i4=0; i5=0;
j1=0; j2=0; j3=0; j4=0; j5=0;
u1=0; u2=0; u3=0; u4=0; u5=0;
o1=0; o2=0; o3=0; o4=0; o5=0;
p1=0; p2=0; p3=0; p4=0; p5=0;
if (Edit1->Text=="+") {i1=2;}
else {i1=0; }
if (Edit2->Text=="+") {j1=2;}
else {j1=0; }
if (Edit3->Text=="+") {u1=2;}
else {u1=0; }
if (Edit4->Text=="+") {o1=2;}
else{o1=0; }
if (Edit5->Text=="+") {p1=2;}
else {p1=0; }
z1=(i1+j1+u1+o1+p1);
if (Edit6->Text=="+") {i2=1;}
else {i2=0; }
if (Edit7->Text=="+") {j2=1;}
else {j2=0; }
if (Edit8->Text=="+") {u2=1;}
else {u2=0; }
if (Edit9->Text=="+") {o2=1;}
else{o2=0; }
if (Edit10->Text=="+") {p2=1;}
else {p1=0; }
z2=(i2+j2+u2+o2+p2);
if (Edit11->Text=="+") {i3=0;}
else {i3=0; }
if (Edit12->Text=="+") {j3=0;}
else {j3=0; }
if (Edit13->Text=="+") {u3=0;}
else {u3=0; }
if (Edit14->Text=="+") {o3=0;}
else{o3=0; }
if (Edit15->Text=="+") {p3=0;}
else {p3=0; }
z3=(i3+j3+u3+o3+p3);
if (Edit16->Text=="+") {i4=-1;}
else {i4=0; }
if (Edit17->Text=="+") {j4=-1;}
else {j4=0; }
if (Edit18->Text=="+") {u4=-1;}
else {u4=0; }
if (Edit19->Text=="+") {o4=-1;}
else{o4=0; }
if (Edit20->Text=="+") {p4=-1;}
else {p4=0; }
z4=(i4+j4+u4+o4+p4);
if (Edit21->Text=="+") {i5=-2;}
else {i5=0; }
if (Edit22->Text=="+") {j5=-2;}
else {j5=0; }
if (Edit23->Text=="+") {u5=-2;}
else {u5=0; }
if (Edit24->Text=="+") {o5=-2;}
else{o5=0; }
if (Edit25->Text=="+") {p5=-2;}
else {p5=0; }
z5=(i5+j5+u5+o5+p5);
Label1->Caption=((z1+z2+z3+z4+z5)/5);
Почему бы тогда не использовать TCheckBox?
А по поводу "обмана зрения" Я это вижу так:
1) создать на форме объект TDrawGrid, т.к. на его Canvas можно рисовать, отдельно в каждой ячейке; Установить 2 колонки, задать ширину и высоту.
2) описываешь обработчик перерисовки:
как я вижу по скриншоту все элементы разбиты на блоки. Значит один такой блок можно "нарисовать" в одной строке. Ячейка первой колонки будет содержать надписи ( +2, литературна ...), Ячейка второй колонки будет отображать квадратики. Прорисовка квадратиков проста - в цикле, с постоянным смещением по горизонтали и по вертикали.
3) описываешь обработчик OnMouseMove, OnMouseDown чтобы по клику мыши в область "нарисованного" квадратика подставить TEdit. Но! Если это нужно только для того, чтобы поставить "+" или убрать его, то и TEdit не нужен! Опиши массивы, в которых хранишь эти "+". И по клику мыши меняй значение и перерисовывай. Вот и всё.
если не более одного отмеченного, то TRadioBox'ы. и не надо изобретать трёхколёсный велик ;)
Код:
// на форме создай TDrawGrid - 1 солонка, 100 строк, ширина колонки по умолчанию - 400, высота - 130
// и TLabel с именем DrawGridLabel
// строка
struct sLine{
AnsiString Name;
bool Value[5];
};
typedef struct sLine* psLine;
// один блок из 5 строк
struct rLine{
sLine Line[5];
};
typedef struct rLine* prLine;
// список блоков
TList* RSList;
void CreateRSList ( void );
void DeleteRSList ( void );
void CreateRSList ( void )
{
RSList = new TList();
prLine p1;
// создадим 100 блоков
for ( int i = 0; i < 100; i++ )
{
p1 = new rLine;
RSList->Add( p1 );
for ( int j = 0; j < 5; j++ )
{
p1->Line[j].Name = "Name [" + IntToStr(i+1) + "][" + IntToStr(j+1) + "]";
p1->Line[j].Value[0] = false;
p1->Line[j].Value[1] = false;
p1->Line[j].Value[2] = false;
p1->Line[j].Value[3] = false;
p1->Line[j].Value[4] = false;
// для примера 1 квадратик отметим
p1->Line[j].Value[j] = true;
}
}
}
void DeleteRSList ( void )
{
prLine p1;
for ( int i = 0; i < 100; i++ )
{
p1 = (prLine)RSList->Items;
delete p1;
}
delete RSList;
}
void __fastcall TfTest::DrawGrid1DrawCell(TObject *Sender, int ACol,
int ARow, TRect &Rect, TGridDrawState State)
{
// проверка, если строк в DrawGrid больше чем "блоков"
if ( ARow >= RSList->Count ) return;
// получим адрес блока, чьи данные рисуем
prLine p1;
p1 = (prLine)RSList->Items[ARow];
// отображаем надпись
for ( int j = 0; j < 5; j++ )
{
TRect TempRect( Rect.Left, Rect.Top + 5 + j*25, Rect.Left + 200, Rect.Top + 5 + j*25 + 20 );
DrawGrid1->Canvas->TextRect( TempRect, TempRect.Left + 2, TempRect.Top + 2, p1->Line[j].Name );
}
// рисуем квадратики
for ( int j = 0; j < 5; j++ )
{
for ( int i = 0; i < 5; i++ )
{
TRect TempRect( Rect.Left + 200 + 5 + i*25, Rect.Top + 5 + j*25, Rect.Left + 200 + 5 + i*25 + 20, Rect.Top + 5 + j*25 + 20 );
DrawGrid1->Canvas->Brush->Color = clBlack;
if ( p1->Line[j].Value )
DrawGrid1->Canvas->FillRect(TempRect);
else
DrawGrid1->Canvas->FrameRect(TempRect);
}
}
}
//---------------------------------------------------------------------------
void __fastcall TfTest::DrawGrid1MouseDown(TObject *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
// покажем координаты
DrawGridLabel->Caption = "X = " + IntToStr(X) + ", Y = " + IntToStr(Y);
// там ли "кликнули"
if ( ( X < 200 ) || ( X > 350 ) ) return;
// Row - текущая строка, TopRow - верхняя отображаемая строка
// получим адрес блока, чьи данные меняем
prLine p1;
p1 = (prLine)RSList->Items[DrawGrid1->Row];
// ищем "квадратик"
for ( int j = 0; j < 5; j++ )
{
for ( int i = 0; i < 5; i++ )
{
int xLeft = 200 + 5 + i*25;
int xRight = xLeft + 20;
int yTop = ( DrawGrid1->Row - DrawGrid1->TopRow ) * DrawGrid1->DefaultRowHeight + 5 + j*25;
int yBottom = yTop + 20;
if ( ( X >= xLeft )&&( X <= xRight )&&( Y <= yBottom )&&( Y >= yTop ) )
{
// изменим значение
p1->Line[j].Value = !p1->Line[j].Value;
// перерисуем
DrawGrid1->Repaint();
// покажем "квадратик"
DrawGridLabel->Caption = IntToStr(DrawGrid1->Row) + ": [" + IntToStr(j) + "][" + IntToStr(i)+ "]";
// уходим
break;
}
}
}
}
//---------------------------------------------------------------------------
// и TLabel с именем DrawGridLabel
// строка
struct sLine{
AnsiString Name;
bool Value[5];
};
typedef struct sLine* psLine;
// один блок из 5 строк
struct rLine{
sLine Line[5];
};
typedef struct rLine* prLine;
// список блоков
TList* RSList;
void CreateRSList ( void );
void DeleteRSList ( void );
void CreateRSList ( void )
{
RSList = new TList();
prLine p1;
// создадим 100 блоков
for ( int i = 0; i < 100; i++ )
{
p1 = new rLine;
RSList->Add( p1 );
for ( int j = 0; j < 5; j++ )
{
p1->Line[j].Name = "Name [" + IntToStr(i+1) + "][" + IntToStr(j+1) + "]";
p1->Line[j].Value[0] = false;
p1->Line[j].Value[1] = false;
p1->Line[j].Value[2] = false;
p1->Line[j].Value[3] = false;
p1->Line[j].Value[4] = false;
// для примера 1 квадратик отметим
p1->Line[j].Value[j] = true;
}
}
}
void DeleteRSList ( void )
{
prLine p1;
for ( int i = 0; i < 100; i++ )
{
p1 = (prLine)RSList->Items;
delete p1;
}
delete RSList;
}
void __fastcall TfTest::DrawGrid1DrawCell(TObject *Sender, int ACol,
int ARow, TRect &Rect, TGridDrawState State)
{
// проверка, если строк в DrawGrid больше чем "блоков"
if ( ARow >= RSList->Count ) return;
// получим адрес блока, чьи данные рисуем
prLine p1;
p1 = (prLine)RSList->Items[ARow];
// отображаем надпись
for ( int j = 0; j < 5; j++ )
{
TRect TempRect( Rect.Left, Rect.Top + 5 + j*25, Rect.Left + 200, Rect.Top + 5 + j*25 + 20 );
DrawGrid1->Canvas->TextRect( TempRect, TempRect.Left + 2, TempRect.Top + 2, p1->Line[j].Name );
}
// рисуем квадратики
for ( int j = 0; j < 5; j++ )
{
for ( int i = 0; i < 5; i++ )
{
TRect TempRect( Rect.Left + 200 + 5 + i*25, Rect.Top + 5 + j*25, Rect.Left + 200 + 5 + i*25 + 20, Rect.Top + 5 + j*25 + 20 );
DrawGrid1->Canvas->Brush->Color = clBlack;
if ( p1->Line[j].Value )
DrawGrid1->Canvas->FillRect(TempRect);
else
DrawGrid1->Canvas->FrameRect(TempRect);
}
}
}
//---------------------------------------------------------------------------
void __fastcall TfTest::DrawGrid1MouseDown(TObject *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
// покажем координаты
DrawGridLabel->Caption = "X = " + IntToStr(X) + ", Y = " + IntToStr(Y);
// там ли "кликнули"
if ( ( X < 200 ) || ( X > 350 ) ) return;
// Row - текущая строка, TopRow - верхняя отображаемая строка
// получим адрес блока, чьи данные меняем
prLine p1;
p1 = (prLine)RSList->Items[DrawGrid1->Row];
// ищем "квадратик"
for ( int j = 0; j < 5; j++ )
{
for ( int i = 0; i < 5; i++ )
{
int xLeft = 200 + 5 + i*25;
int xRight = xLeft + 20;
int yTop = ( DrawGrid1->Row - DrawGrid1->TopRow ) * DrawGrid1->DefaultRowHeight + 5 + j*25;
int yBottom = yTop + 20;
if ( ( X >= xLeft )&&( X <= xRight )&&( Y <= yBottom )&&( Y >= yTop ) )
{
// изменим значение
p1->Line[j].Value = !p1->Line[j].Value;
// перерисуем
DrawGrid1->Repaint();
// покажем "квадратик"
DrawGridLabel->Caption = IntToStr(DrawGrid1->Row) + ": [" + IntToStr(j) + "][" + IntToStr(i)+ "]";
// уходим
break;
}
}
}
}
//---------------------------------------------------------------------------
Код:
// помести на форму TCheckBox с именем DrawGridCheckBox
...
if ( ( X >= xLeft )&&( X <= xRight )&&( Y <= yBottom )&&( Y >= yTop ) )
{
// изменим значение
if ( DrawGridCheckBox->Checked )
{
if ( !p1->Line[j].Value )
{
// очистим все
p1->Line[j].Value[0] = false;
p1->Line[j].Value[1] = false;
p1->Line[j].Value[2] = false;
p1->Line[j].Value[3] = false;
p1->Line[j].Value[4] = false;
// установим выбраный
p1->Line[j].Value = true;
}
}
else
{
p1->Line[j].Value = !p1->Line[j].Value;
}
...
...
if ( ( X >= xLeft )&&( X <= xRight )&&( Y <= yBottom )&&( Y >= yTop ) )
{
// изменим значение
if ( DrawGridCheckBox->Checked )
{
if ( !p1->Line[j].Value )
{
// очистим все
p1->Line[j].Value[0] = false;
p1->Line[j].Value[1] = false;
p1->Line[j].Value[2] = false;
p1->Line[j].Value[3] = false;
p1->Line[j].Value[4] = false;
// установим выбраный
p1->Line[j].Value = true;
}
}
else
{
p1->Line[j].Value = !p1->Line[j].Value;
}
...
Так же можно установить цвет DrawGrid = clBtnFace.
В этом случае красивее будут смотрется "пустые - белые" квадратики.
Код:
...
if ( p1->Line[j].Value )
DrawGrid1->Canvas->FillRect(TempRect);
else
{
DrawGrid1->Canvas->Brush->Color = clWhite;
DrawGrid1->Canvas->FillRect(TempRect);
DrawGrid1->Canvas->Brush->Color = clBlack;
DrawGrid1->Canvas->FrameRect(TempRect);
}
...
if ( p1->Line[j].Value )
DrawGrid1->Canvas->FillRect(TempRect);
else
{
DrawGrid1->Canvas->Brush->Color = clWhite;
DrawGrid1->Canvas->FillRect(TempRect);
DrawGrid1->Canvas->Brush->Color = clBlack;
DrawGrid1->Canvas->FrameRect(TempRect);
}
...
всем большое спасибо. щас буду пробовать все предложенные варинты :)
чуваки, а в рантайме нарожать компонентов вы не можете ?
Какая разница как он их создает если у него такая бешенная обработка событий...
На каждый Change по двадцать пять Clear, а каждый Clear естественно вызовет свой Change... а если хоть в одном месте случайно сослался по кругу на вызвавший компонент машина зависнет а виноват опять будет мелкий софт...
Как будто нельзя было обойтись без Change и все Clear записать в KeyPress...