Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Проблема с ListBox'ом [D7]


Страницы:   1 2

ProgRAMmer Dimonych ©   (2006-09-30 21:35:00) 

Почему-то пропадает прямоугольник фокуса TListBox. Когда пытаюсь повторить те действия, которые выполняются до возникновения проблемы, в новом проекте, всё работает нормально. Действия такие: ListBox очищается через ListBox.Items.Clear, после чего идёт заполнение его Items'ами. Заполнение идёт из динамического массива, для которого получается длина (количество элементов), потом идёт

for i:=0 to Length(Massiv)-1 do
if Massiv[i].Text.Count>0 then
 ListBox.Items.Add(Massiv[i].Text[0]);
end;

где

Massiv=array of TMyRec;
MyRec=record
 Text:TStringList;
 . . . . . . . . . . .
end;

Если надо, могу выложить куски реального кода, а не урезанного, как здесь. Чё-то уже совсем притупился за день работы с Дельфой. :(


ProgRAMmer Dimonych   (2006-10-01 00:30:00) [1]

> > for i:=0 to L-1 do
> > begin
> > RemoveQuest(i); {Удаление элемента массива с освобождением
>
> > памяти}
> > end;
>
> или комментарий неверный или цикл должен быть таким: for
> i:=L-1 downto 0 do
Вообще, RemoveQuest(i) удаляет любой элемент (остальные смещает), но в данном случае, действительно разумнее будет задать обратный порядок...

> Прямоугольник фокуса пропадает навсегда или до каких пор?

"Файл -> Новый" возвращает.


guav   (2006-10-01 00:09:00) [2]

> for i:=0 to L-1 do
> begin
> RemoveQuest(i); {Удаление элемента массива с освобождением
> памяти}
> end;

или комментарий неверный или цикл должен быть таким: for i:=L-1 downto 0 do


> Собственно, if QuestList.Items.Count>0 then ; нужно только
> для того, чтобы менять значение Changed

я не о том. в  QuestList.Items.Count листбоксу посылается сообщение, может в этом причина различий в поведении приведенных методов.

Прямоугольник фокуса пропадает навсегда или до каких пор ?


ProgRAMmer Dimonych   (2006-09-30 23:53:00) [3]

> [21]
Changed - поле, объявленное в разделе private.

> если добавить if QuestList.Items.Count>0 then ; в MTNewClick
> не добавится ли та же ошибка при MTNewClick ?
> что делает StartNew ?

Собственно, if QuestList.Items.Count>0 then ;нужно только для того, чтобы менять значение Changed, если список не пуст (т.е. если очистка списка будет считаться изменением). Просто в StartNew значение Changed меняется.

procedure TMain.StartNew;
var
i,L:Integer;
begin
L:=Length(Test); {Длина массива}
for i:=0 to L-1 do
begin
 RemoveQuest(i); {Удаление элемента массива с освобождением памяти}
end;
SetLength(Test,0); {*}
FileName:=''; Changed:=False; {FileName - имя редактируемого файла}
QuestList.Items.Clear; QuestMemo.Lines.Clear; Vars.Items.Clear;
PC.ActivePageIndex:=0; {QuestMemo, QuestList,Vars,PC - контролы на форме}
HidePanel; {Процедура, которая прячет часть контролов}
end;

* - эта команда, как выяснилось при отладке, выполняется дважды с одинаковыми параметрами (один раз - в RemoveQuest, второй - в StartNew), но вряд ли это создаёт subj'евую проблему...


ProgRAMmer Dimonych   (2006-09-30 23:53:00) [4]

> [21]
Changed - поле, объявленное в разделе private.

> если добавить if QuestList.Items.Count>0 then ; в MTNewClick
> не добавится ли та же ошибка при MTNewClick ?
> что делает StartNew ?

Собственно, if QuestList.Items.Count>0 then ;нужно только для того, чтобы менять значение Changed, если список не пуст (т.е. если очистка списка будет считаться изменением). Просто в StartNew значение Changed меняется.

procedure TMain.StartNew;
var
i,L:Integer;
begin
L:=Length(Test); {Длина массива}
for i:=0 to L-1 do
begin
 RemoveQuest(i); {Удаление элемента массива с освобождением памяти}
end;
SetLength(Test,0); {*}
FileName:=''; Changed:=False; {FileName - имя редактируемого файла}
QuestList.Items.Clear; QuestMemo.Lines.Clear; Vars.Items.Clear;
PC.ActivePageIndex:=0; {QuestMemo, QuestList,Vars,PC - контролы на форме}
HidePanel; {Процедура, которая прячет часть контролов}
end;

* - эта команда, как выяснилось при отладке, выполняется дважды с одинаковыми параметрами (один раз - в RemoveQuest, второй - в StartNew), но вряд ли это создаёт subj'евую проблему...


guav   (2006-09-30 23:43:00) [5]

Changed - поле, переменная, свойство ? если  св-во - какие методы read и write
QuestList - это тот ListBox ? если добавить if QuestList.Items.Count>0 then ;в MTNewClick не добавится ли та же ошибка при MTNewClick ?
что делает StartNew ?


> Т.е. с динамическим массивом?

Не обязательно, но возможно и с ним.


> Такое возможно, если массив имеет размерность 1, максимум
> 2, элемента?

Да.

{$R+} или {$RANGECHECKS ON} или опция Range Checking на закладке Compiler позволяет избежать непредсказуемости при нарушениях диапазона.


ProgRAMmer Dimonych   (2006-09-30 23:38:00) [6]

> [19]
Т.е. с динамическим массивом?
Такое возможно, если массив имеет размерность 1, максимум 2, элемента?


guav   (2006-09-30 23:32:00) [7]

Хотя бы в том что на чтение тривиального кода мне пришлось потратить пару минут.
И ещё, при выборе одного из нескольких вариантов case понятнее и оптимальнее чем if.

По теме, ошибка в другом месте, (возможно, затирание "чужой" памяти, если ошибка трудновоспроизводима).


ProgRAMmer Dimonych   (2006-09-30 23:23:00) [8]

> [17]
А в чём минус моего варианта записи алгоритма?


guav   (2006-09-30 23:21:00) [9]

> По [10] кто-нибудь подскажите, плз.



> Tmp:=MessageBox(Handle,'Вы хотите сохранить изменения?',
> 'Изменения не сохранены!!!',35);
> if Tmp=2 then Exit;
> if Tmp=6 then MTSave.Click;

ужасный код. программы с таким кодом ведут себя непредсказуемо.

надо что-то вроде
case MessageBox(Handle, 'Вы хотите сохранить изменения?', 'Изменения не сохранены!!!', MB_YESNOCANCEL or MB_ICONQUESTION) of
 IDCANCEL: Exit;
 IDNYES: MTSave.Click;
end;


ProgRAMmer Dimonych   (2006-09-30 23:16:00) [10]

> [15]

ListBox.Style=lbStandard

Художества отсутствуют...


guav   (2006-09-30 23:14:00) [11]

Style какой ?
Есть ли рисование на канве ?


ProgRAMmer Dimonych   (2006-09-30 23:12:00) [12]

По [10] кто-нибудь подскажите, плз.


default   (2006-09-30 23:09:00) [13]

ProgRAMmer Dimonych   (30.09.06 22:58) [12]
пардон, с другим контролом перепутал


ProgRAMmer Dimonych   (2006-09-30 22:58:00) [14]

> [11]
Хотелось бы формулировку поточн ее...


default   (2006-09-30 22:28:00) [15]

ну накрайняк можно при потере фокуса листбоксом сохранять начало и конец выделенного текста, при получении фокуса восстанавливать выделение(если я правильно понял проблему)


ProgRAMmer Dimonych   (2006-09-30 22:27:00) [16]

Да, ещё одно наблюдение.

Есть две процедуры: StartNew (урезает Massiv до длины 1 и его единственному нулевому элементу присваивает значение, обусловленное программой) и RefreshListContents (которая, собственно и была приведена; там идёт заполнение ListBox'а).

Кроме этого есть два обработчика событий.

procedure TMain.QClearClick(Sender: TObject);
{Пункт выпадающего меню Очистить список}
begin
if QuestList.Items.Count>0 then
begin
 StartNew;
 Changed:=True;
end
else
 StartNew;
RefreshListContents;
end;

procedure TMain.MTNewClick(Sender: TObject);
{Пункт главного меню Файл -> Новый}
var
Tmp:Integer;
begin
if Changed then
begin
 Tmp:=MessageBox(Handle,'Вы хотите сохранить изменения?','Изменения не сохранены!!!',35);
 if Tmp=2 then Exit;
 if Tmp=6 then MTSave.Click;
end;
StartNew;
RefreshListContents;
end;

Разница в том, что Файл -> Новый должен проверить значение Changed:Boolean и если оно True, то предложить сохраниться, а Очистить список просто очищает список. Но после Файл -> Новый subj'евый прямоугольник остаётся, а после Очистить список - исчезает.


Kolan   (2006-09-30 22:23:00) [17]


>
> Может всё-таки кусок кода выложить?

Ну дык давай. Конференция резиновая :)


ProgRAMmer Dimonych   (2006-09-30 22:19:00) [18]

> [7]
Не помогло :(


Percent   (2006-09-30 22:10:00) [19]

for i := 0 to Length(Massiv) - 1 do
 if (Massiv[i].Text.Count > 0) then
   ListBox.Items.Add(Massiv[i].Text[0]);

if (ListBox.Items.Count > 0) then
 ListBox.ItemIndex := 0;


Это?


ProgRAMmer Dimonych   (2006-09-30 22:02:00) [20]

> [5]
Ничего, бывает...

2 All

Может всё-таки кусок кода выложить?


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо