Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Компоненты";
Текущий архив: 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
2-1153663394
Bambucha
2006-07-23 18:03
2006.08.13
Shell Extensions


1-1151730788
SDF
2006-07-01 09:13
2006.08.13
Работа с растровыми изображениями


15-1152871615
DevilDevil
2006-07-14 14:06
2006.08.13
Локальные переменные в C++


15-1152874361
nikShev
2006-07-14 14:52
2006.08.13
Пиринговые сети


15-1153094770
Ketmar
2006-07-17 04:06
2006.08.13
никому не нужен удалёный программист?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский