![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Проблема с ListBox'ом [D7]
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
Может всё-таки кусок кода выложить?