Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.08.13;
Скачать: CL | DM;

Вниз

Непонятная ошибка в редакторе компонента   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.053 c
15-1153049303
X9
2006-07-16 15:28
2006.08.13
Выбор мобилки


15-1153252165
Ketmar
2006-07-18 23:49
2006.08.13
всё -- досисадминился


2-1153984203
Crazy monkey
2006-07-27 11:10
2006.08.13
Вопрос по Access


6-1143447618
Некто_Аполло
2006-03-27 12:20
2006.08.13
Дозвон без соединения


15-1153147494
StriderMan
2006-07-17 18:44
2006.08.13
кросс-платформенные приложения