![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Непонятная ошибка в редакторе компонента
TStas © (2006-01-15 00:23:00)Написал компонент - диалог поиска в папке. Работает замечательно, два редактора свойств - тоже. Написал редактор компонента, не то, чтобы сильно нужный, но, чтобы просто в DesignTime'е диалог вызывал, как у других диалоговых компонетов. В меню появился, ошибок компиляции нет, но при двойном щелчке на компоненте в DesignTime'е вылезает ошибка, что в модуле rtl70.bpl ошибка по какому-то адресу (но не nil). Вот код модуля:
unit stFolderSearchDialogEditor;
interface
uses
DesignIntf, DesignEditors;
type
TstFolderSearchDialogEditor = Class(TComponentEditor)
public
function GetVerbCount: Integer; override;
function GetVerb(Index: Integer): String; override;
procedure ExecuteVerb(Index: Integer); override;
end;
procedure Register;
implementation
uses stFolderSearchDialog, SysUtils;
procedure Register;
begin
RegisterComponentEditor(TstFolderSearchDialog, TstFolderSearchDialogEditor)
end;
{ TstFolderSearchDialogEditor }
procedure TstFolderSearchDialogEditor.ExecuteVerb(Index: Integer);
begin
case Index of
0: TstFolderSearchDialog(Component).Execute;
end;
end;
function TstFolderSearchDialogEditor.GetVerb(Index: Integer): String;
begin
case Index of
0: Result := 'Test dialog';
end;
end;
function TstFolderSearchDialogEditor.GetVerbCount: Integer;
begin
Result := 1;
end;
end.
Нашел файл rtl70.bpl. Он живет в папке System32, что он там делает - не знаю, я его не писал. И в чем может быть дело?
Юрий Зотов (2006-01-19 20:31:00) [1]Стас, в методе Execute компонента строку
FolderSearchDialogForm:=TFolderSearchDialogForm.Create(Self);
замени такой строкой
FolderSearchDialogForm:=TFolderSearchDialogForm.Create(Application);
или такой строкой
FolderSearchDialogForm:=TFolderSearchDialogForm.Create(nil);
и все должно заработать.
Отгадку причины оставляю в качестве самостоятельного упражнения.
:о)
PS
Свойство (или поле) "OK" из формы выкинь, а код ее показа измени на такой:
Result := FolderSearchDialogForm.ShowModal = mrOK;
И еще ОЧЕНЬжелательно весь код Execute от создания формы до ее уничтожения взять в блок "try-finally". Тогда уничтожение формы будет гарантировано даже при ошибках:
FolderSearchDialogForm:=TFolderSearchDialogForm.Create(nil);
try
... // Работаем с формой
finally
FolderSearchDialogForm.Free;
end;
Иначе есть риск получить утечку памяти.
TStas (2006-01-19 19:26:00) [2]Вот OnCreate только выше моего понимания, чего он в Дизайн не работает а в ран - вполне
procedure TFolderSearchDialogForm.FormCreate(Sender: TObject);
begin
UseRussian:=false;
FindList:=TFindList.Create;
ItemsFileName:=ExtractFilePath(Application.ExeName)+Owner.Name+'.dat';
if FileExists(ItemsFileName) then
ComboBox1.Items.LoadFromFile(ItemsFileName);
InitialDir:=ExtractFileDir(Application.ExeName);
FFilterList:=TStringList.Create;
Filter:=defFilter;
FOK:=false;
FilesFound:=TStringList.Create;
end;
Юрий Зотов (2006-01-19 18:22:00) [3]Еще код формы, который отрабатывает при ее создании (если такой есть) - конструктор, AfterCreate, OnCreate и пр.
TStas (2006-01-19 18:03:00) [4]>Попробуй включить Use Debug DCU's и сделать Find Error по этому адресу.
Спасибо, Джо, только я пока не знаю, как это сделать все :)
>Юрий Зотов
Вот метод:
Делается в нем следующее: в соответствии с опциями устанавливаются на созданной форме флажки. Но все равно, в рантайме работает, а в дизайтайме - нет.
function TstFolderSearchDialog.Execute: Boolean;
var
NewOptions: TDirSearchOptions;
begin
FolderSearchDialogForm:=TFolderSearchDialogForm.Create(Self);
FolderSearchDialogForm.UseRussian:=UseRussian;
FolderSearchDialogForm.Filter:=Filter;
if Title<>'' then FolderSearchDialogForm.Caption:=Title;
FolderSearchDialogForm.cbSubFolders.Checked := dsSubfolders in FOptions;
FolderSearchDialogForm.cbWholeWords.Checked := dsWholeWord in FOptions;
FolderSearchDialogForm.cbCase.Checked := dsCaseSensitive in FOptions;
FolderSearchDialogForm.BrowseBtn.Enabled := not (dsNoChangeDir in FOptions);
FolderSearchDialogForm.ComboBox2.ItemIndex:=FFilterIndex;
FolderSearchDialogForm.InitialDir:=InitialDir;
FolderSearchDialogForm.CanOpen:=dsCanOpen in FOptions;
FolderSearchDialogForm.ShowModal;
Result:=FolderSearchDialogForm.OK;
if Result then
begin
NewOptions:=[];
if dsNoChangeDir in FOptions then
Include(NewOptions, dsNoChangeDir);
if FolderSearchDialogForm.cbSubFolders.Checked
then Include(NewOptions, dsSubfolders);
if FolderSearchDialogForm.cbWholeWords.Checked then
Include(NewOptions, dsWholeWord);
if FolderSearchDialogForm.cbCase.Checked then
Include(NewOptions, dsCaseSensitive);
FOptions := NewOptions;
InitialDir := FolderSearchDialogForm.InitialDir;
FFilterIndex := FolderSearchDialogForm.ComboBox2.ItemIndex;
FFilesFound.Assign(FolderSearchDialogForm.FilesFound);
end;
FreeAndNil(FolderSearchDialogForm);
end;
PS. Связь тормозит, с третьего раза отвелил :(
Юрий Зотов (2006-01-18 21:22:00) [5]> TStas © (18.01.06 19:57) [21]
> Только в RunTime она не вылезает упорно.
Можно вести интерактивную отладку и в design-time, если пакет деинсталлировать, открыть в IDE, назначить его хостером Delphi32.exe и "запустить". То есть, нужно запустить вторую копию Delphi из-под первой, а в этой второй копии уже инсталлировать пакет и производить отлаживаемые design-time операции. Сам отладчик, понятно, будет работать в первой копии.
> Execute создает диалоговое окно, показывает его модально и уничтожает.
Стас, словесные описания бесполезны. Показывай код Execute и этого самого диалогового окна.
Джо (2006-01-18 20:10:00) [6]> Просто вылезает ошибка по адресу какому-то, но не nil.
Попробуй включить Use Debug DCU's и сделать Find Error по этому адресу.
TStas (2006-01-18 19:57:00) [7]>Юрий Зотов
Я и сам так думал. Только в RunTime она не вылезает упорно.
Execute создает диалоговое окно, показывает его модально и уничтожает.
Может, я просто чего-то такого не знаю? Просто вылезает ошибка по адресу какому-то, но не nil.
DimaBr (2006-01-18 11:53:00) [8]Разве трудно выловить грабли ?
> procedure TstFolderSearchDialogEditor.ExecuteVerb(Index:
> Integer);
> begin
> if Index = GetVerbCount - 1 then begin
> ShowMessage('Вызываем Extcute');
> TstFolderSearchDialog(Component).Execute
> end
> else
> inherited
>
> end;
Юрий Зотов (2006-01-17 21:33:00) [9]Стас, в редакторе все правильно. Скорее всего, ошибка в методе Execute самого компонента. При двойном щелчке на нем среда вызывает метод Edit редактора, тот вызывает ExecuteVerb(0) и выполняется Execute компонента - вот он, по-видимому, и дает ошибку.
TStas (2006-01-17 20:16:00) [10]Это я из работающего редактора компонента (другого) Index убрал, раз тоже 1 пункт. А вот неработающий после последней правки. У компилятора замечаний нет, но в рантайме лажа происходит см [1]
unit stFolderSearchDialogEditor;
interface
uses
DesignIntf, DesignEditors;
type
TstFolderSearchDialogEditor = Class(TComponentEditor)
public
function GetVerbCount: Integer; override;
function GetVerb(Index: Integer): String; override;
procedure ExecuteVerb(Index: Integer); override;
end;
procedure Register;
implementation
uses stFolderSearchDialog, SysUtils, Controls;
procedure Register;
begin
RegisterComponentEditor(TstFolderSearchDialog, TstFolderSearchDialogEditor)
end;
{ TstFolderSearchDialogEditor }
procedure TstFolderSearchDialogEditor.ExecuteVerb(Index: Integer);
begin
if Index = GetVerbCount - 1 then
TstFolderSearchDialog(Component).Execute
else
inherited
end;
function TstFolderSearchDialogEditor.GetVerb(Index: Integer): String;
begin
if Index = GetVerbCount - 1 then
Result := 'Test dialog'
else
Result := inherited GetVerb(Index)
end;
function TstFolderSearchDialogEditor.GetVerbCount: Integer;
begin
Result := inherited GetVerbCount + 1
end;
end.
Юрий Зотов (2006-01-17 19:57:00) [11]> TStas © (17.01.06 19:34) [16]
> вообще Index убрал
Это как так? Код показывай.
TStas (2006-01-17 19:34:00) [12]>Юрий Зотов
Таки всегда возвращает. Я из нее для верности вообще Index убрал, раз пункт 1. То же самое для другого компонента - нормально все.
Юрий Зотов (2006-01-16 19:44:00) [13]> TStas © (16.01.06 19:03) [14]
> Дело 100% не в case
Само собой, case и if тут вообще как сбоку бантик, это просто Розыч к нему с чего-то прицепился. :о)
Читай [5] и проверь, ВСЕГДА ли у тебя функции возвращают значение.
TStas (2006-01-16 19:03:00) [14]Все равно странно. Меню из ОДНОГО пункта. Только что специально одному компоненту редактор написал, специально из одного пункта тоже. Работает все. А здесь какие-то злые чудеса: в RunTime вызывается метод, все в порядке, в DisignTime не хочет и все. Дело 100% не в case :)
Юрий Зотов (2006-01-16 16:26:00) [15]> Rouse_ © (16.01.06 16:13) [12]
Не задело, а надоело. Не в первый раз подобное потому что. Извини за резкость, конечно, но достало уже. Блин, ты понимаешь, что ты в очередной раз взялся мне детскую азбуку объяснять? Ну ей-богу, как с дуба спрыгнул, Саш, ты чо?
Ладно, согласен, проехали. И давай закроем подобные темы навсегда.
:о)
Rouse_ (2006-01-16 16:13:00) [16]Эк тебя задело :) Ну ладно-ладно... проехали :)
Юрий Зотов (2006-01-16 16:03:00) [17]> TStas © (16.01.06 15:56) [10]
Run-time library, версия для D7. Один из пакетов в составе VCL.
TStas (2006-01-16 15:56:00) [18]Сейчас буду исправлять, а что все-таки за файл такой rtl70.bpl?
Юрий Зотов (2006-01-16 15:54:00) [19]> Rouse_ © (16.01.06 15:28) [8]
Так. Еще раз.
В сабже к меню добавляется 1 пункт. Прописью - один. Еще раз прописью - ОДИН. Жирным - ОДИН. Жирным подчеркнутым - ОДИН .
В случаях, когда добавляется НЕ один пункт - читаем [3]. Несколько раз. До полного прояснения. Пока не станет понятно, что никаких противоречий с кодом DX, слава Богу, не наблюдается.
Потом снова вспоминаем, что в сабже к меню добавляется 1 пункт. Прописью - один. Еще раз прописью - ОДИН. Жирным - ОДИН. Жирным подчеркнутым - ОДИН .
Потом просекаем, что в ЭТОМ случае IF будет лучше, чем CASE. В ЭТОМ. Жирным - в ЭТОМ. Жирным подчеркнутым - в ЭТОМ .
А если кто вдруг решил, что в [1] советовалось писать многоэтажные IF'ы, то стоит вылезти из танка. И начать говорить по ДЕЛУ, а не по детским вопросикам типа "IF vs CASE".
Если, конечно, по ДЕЛУ есть что сказать.
Rouse_ (2006-01-16 15:28:00) [20]Юр, тогда ты противоречишь самому себе. Вот тебе кусок из столь понравившихся тебе DevExpress-ов
function TdxNavBarComponentEditor.GetVerb(Index: Integer): string;
begin
case Index of
0: Result := sdxEditor;
2: Result := sdxProductText;
3: Result := sdxCompanyWebPage;
4: Result := sdxCompanyName;
else
Result := '-';
end;
end;
function TdxNavBarComponentEditor.GetVerbCount: Integer;
begin
Result := 6;
end;