Форум: "Компоненты";
Текущий архив: 2006.08.13;
Скачать: [xml.tar.bz2];
ВнизНепонятная ошибка в редакторе компонента Найти похожие ветки
← →
TStas © (2006-01-15 00:23) [0]Написал компонент - диалог поиска в папке. Работает замечательно, два редактора свойств - тоже. Написал редактор компонента, не то, чтобы сильно нужный, но, чтобы просто в 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-15 04:02) [1]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;
Не факт, что это поможет, но писать все равно надо так.
← →
Rouse_ © (2006-01-15 19:32) [2]
> Юрий Зотов © (15.01.06 04:02) [1]
Круто.. У меня 4 обработчика, и что я буду делать вот с этим:if Index = GetVerbCount - 1 then
?
← →
Юрий Зотов © (2006-01-15 20:50) [3]> Rouse_ © (15.01.06 19:32) [2]
case Index - GetVerbCount + 1 of
:o)
← →
jack128 © (2006-01-15 20:56) [4]Rouse_ © (15.01.06 19:32) [2]
Я так понял, ЮЗ хочет, чтобы всё это барахло работало если редакторы насдедуются друг от друга. В этом случае нужно писать что нить типа такого:function TstFolderSearchDialogEditor.GetVerb(Index: Integer): String;
;
begin
case Index - inherited GetVerbCount of
0: ...;
1: ...;
2: ...;
else
Result := inherited GetVerb(Index)
end
end
← →
Юрий Зотов © (2006-01-15 23:55) [5]> jack128 © (15.01.06 20:56) [4]
Точно так, но это даже не главное (даже при наследовании индексация новых пунктов меню у каждого нового наследника все равно начинается с нуля).
Основная суть в том, чтобы функция, которую вызывает среда, всегда возвращала "хорошее" значение, а не случайный мусор, как в [0]. Иначе реакция среды может быть непредсказуемой - и возможно, что причина сабжа как раз в этом и есть.
← →
Rouse_ © (2006-01-16 09:01) [6]
> В этом случае нужно писать что нить типа такого:
Именно так это и пишеться :)
← →
Юрий Зотов © (2006-01-16 14:17) [7]> Rouse_ © (16.01.06 09:01) [6]
Саш, в сабже к меню добавляется 1 пункт. Если у тебя есть непреодолимое желание писать case из одной ветки - пиши. Я не против, чес-слово.
Только другим такое не советуй, плз. Тут я против. И буду применять синий карандаш. Обязан даже.
← →
Rouse_ © (2006-01-16 15:28) [8]Юр, тогда ты противоречишь самому себе. Вот тебе кусок из столь понравившихся тебе 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;
← →
Юрий Зотов © (2006-01-16 15:54) [9]> Rouse_ © (16.01.06 15:28) [8]
Так. Еще раз.
В сабже к меню добавляется 1 пункт. Прописью - один. Еще раз прописью - ОДИН. Жирным - ОДИН. Жирным подчеркнутым - ОДИН.
В случаях, когда добавляется НЕ один пункт - читаем [3]. Несколько раз. До полного прояснения. Пока не станет понятно, что никаких противоречий с кодом DX, слава Богу, не наблюдается.
Потом снова вспоминаем, что в сабже к меню добавляется 1 пункт. Прописью - один. Еще раз прописью - ОДИН. Жирным - ОДИН. Жирным подчеркнутым - ОДИН.
Потом просекаем, что в ЭТОМ случае IF будет лучше, чем CASE. В ЭТОМ. Жирным - в ЭТОМ. Жирным подчеркнутым - в ЭТОМ.
А если кто вдруг решил, что в [1] советовалось писать многоэтажные IF"ы, то стоит вылезти из танка. И начать говорить по ДЕЛУ, а не по детским вопросикам типа "IF vs CASE".
Если, конечно, по ДЕЛУ есть что сказать.
← →
TStas © (2006-01-16 15:56) [10]Сейчас буду исправлять, а что все-таки за файл такой rtl70.bpl?
← →
Юрий Зотов © (2006-01-16 16:03) [11]> TStas © (16.01.06 15:56) [10]
Run-time library, версия для D7. Один из пакетов в составе VCL.
← →
Rouse_ © (2006-01-16 16:13) [12]Эк тебя задело :) Ну ладно-ладно... проехали :)
← →
Юрий Зотов © (2006-01-16 16:26) [13]> Rouse_ © (16.01.06 16:13) [12]
Не задело, а надоело. Не в первый раз подобное потому что. Извини за резкость, конечно, но достало уже. Блин, ты понимаешь, что ты в очередной раз взялся мне детскую азбуку объяснять? Ну ей-богу, как с дуба спрыгнул, Саш, ты чо?
Ладно, согласен, проехали. И давай закроем подобные темы навсегда.
:о)
← →
TStas © (2006-01-16 19:03) [14]Все равно странно. Меню из ОДНОГО пункта. Только что специально одному компоненту редактор написал, специально из одного пункта тоже. Работает все. А здесь какие-то злые чудеса: в RunTime вызывается метод, все в порядке, в DisignTime не хочет и все. Дело 100% не в case :)
← →
Юрий Зотов © (2006-01-16 19:44) [15]> TStas © (16.01.06 19:03) [14]
> Дело 100% не в case
Само собой, case и if тут вообще как сбоку бантик, это просто Розыч к нему с чего-то прицепился. :о)
Читай [5] и проверь, ВСЕГДА ли у тебя функции возвращают значение.
← →
TStas © (2006-01-17 19:34) [16]>Юрий Зотов
Таки всегда возвращает. Я из нее для верности вообще Index убрал, раз пункт 1. То же самое для другого компонента - нормально все.
← →
Юрий Зотов © (2006-01-17 19:57) [17]> TStas © (17.01.06 19:34) [16]
> вообще Index убрал
Это как так? Код показывай.
← →
TStas © (2006-01-17 20:16) [18]Это я из работающего редактора компонента (другого) 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 21:33) [19]Стас, в редакторе все правильно. Скорее всего, ошибка в методе Execute самого компонента. При двойном щелчке на нем среда вызывает метод Edit редактора, тот вызывает ExecuteVerb(0) и выполняется Execute компонента - вот он, по-видимому, и дает ошибку.
← →
DimaBr (2006-01-18 11:53) [20]Разве трудно выловить грабли ?
> procedure TstFolderSearchDialogEditor.ExecuteVerb(Index:
> Integer);
> begin
> if Index = GetVerbCount - 1 then begin
> ShowMessage("Вызываем Extcute");
> TstFolderSearchDialog(Component).Execute
> end
> else
> inherited
>
> end;
← →
TStas © (2006-01-18 19:57) [21]>Юрий Зотов
Я и сам так думал. Только в RunTime она не вылезает упорно.
Execute создает диалоговое окно, показывает его модально и уничтожает.
Может, я просто чего-то такого не знаю? Просто вылезает ошибка по адресу какому-то, но не nil.
← →
Джо © (2006-01-18 20:10) [22]> Просто вылезает ошибка по адресу какому-то, но не nil.
Попробуй включить Use Debug DCU"s и сделать Find Error по этому адресу.
← →
Юрий Зотов © (2006-01-18 21:22) [23]> TStas © (18.01.06 19:57) [21]
> Только в RunTime она не вылезает упорно.
Можно вести интерактивную отладку и в design-time, если пакет деинсталлировать, открыть в IDE, назначить его хостером Delphi32.exe и "запустить". То есть, нужно запустить вторую копию Delphi из-под первой, а в этой второй копии уже инсталлировать пакет и производить отлаживаемые design-time операции. Сам отладчик, понятно, будет работать в первой копии.
> Execute создает диалоговое окно, показывает его модально и уничтожает.
Стас, словесные описания бесполезны. Показывай код Execute и этого самого диалогового окна.
← →
TStas © (2006-01-19 18:03) [24]>Попробуй включить 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-19 18:22) [25]Еще код формы, который отрабатывает при ее создании (если такой есть) - конструктор, AfterCreate, OnCreate и пр.
← →
TStas © (2006-01-19 19:26) [26]Вот 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 20:31) [27]Стас, в методе 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;
Иначе есть риск получить утечку памяти.
Страницы: 1 вся ветка
Форум: "Компоненты";
Текущий архив: 2006.08.13;
Скачать: [xml.tar.bz2];
Память: 0.53 MB
Время: 0.042 c