Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Проверьте правильность кода!


Автор: Pakshin A. S. 5.6.2005, 14:02
Вот написал человеку код:
Код

uses Registry;

const
 n = 50;
 
 Keys: array [1..n] of string = (
 '\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer',
 '\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer',
 '\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer',
 '\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System',
 '\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System',
 '\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Network',
 ...
 );

 Names: array [1..n] of string = ( 
 'KeyName1',
 'KeyName2',
 'KeyName3',
 'KeyName4',
 'KeyName5',
 'KeyName6',
 ...
 );

 Root: HKEY = (*раздел*);

 prefix = 'CheckBox'; 


type
 TBaseBox = TCheckBox; 


var
 reg: TRegistry;


procedure LoadRegistry;
var
 i:integer;
 b:TBaseBox;
begin
 reg:=TRegistry.Create;
 reg.RootKey:=Root;
 for i:=1 to n do
  with reg, Form1 do
   begin
    OpenKey(Keys[i], false);
    b:=FindComponent(prefix + IntToStr(i)) as TBaseBox;
    try
     b.Checked:=ReadBool(Names[i]);
    except
     b.Enabled:=false;
    end;
    b.Free;    
    CloseKey
   end;
 reg.Free
end;

procedure SaveRegistry;
var
 i:integer;
 b:TBaseBox;
begin
 reg:=TRegistry.Create;
 reg.RootKey:=Root;
 for i:=1 to n do
  with reg, Form1 do
   begin
    OpenKey(Keys[i], false);
    b:=FindComponent(prefix + IntToStr(i)) as TBaseBox;
    if b.Enabled
     then
      WriteBool(Names[i], b.Checked);
    b.Free;
    CloseKey
   end;
 reg.Free
end;


Он говорит, что этот код не верен... Так ли это? Что исправить?

Суть всей затеи...
Есть 50 Чеков... В них ставятся галочки в соответствии с параметрами реестра... Соответсвие между ними всеми ставится через константы... индексы...

Автор: Quadr0 5.6.2005, 14:12
...

Автор: The MASTER 5.6.2005, 14:24
Так, что подскажешь делать?

Кстати, при запуске проги, выдаёт ошибку дебагера:
Код

Project Project1.exe raised exception class ERegistryException with message 
'Faild to get data for NoFind'. Process stopped. Use Step or Run to continue.

Автор: RA 5.6.2005, 14:45
Вобще лень это тестировать, а на первый взгляд видна ошибка

{
'\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer',
'\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer',
'\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer',
'\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System',
'\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System',
'\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Network',
}

должно быть без символа "\" в начале.

'SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer',
'SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer',
'SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer',
'SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System',
'SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System',
"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Network',

Автор: The MASTER 5.6.2005, 14:55
Цитата(Quadr0 @ 5.6.2005, 14:12)
все без имён, вот он ничего и не найдёт.

В каком смысле без имён, ведь смотри, prefix = имени компонента без цифры, а i = это номера компонентов и получается в итоге CheckBox1, CheckBox2 и т.д.

Автор: Dynamic 5.6.2005, 15:08
Цитата(Pakshin @ 5.6.2005, 14:02)
b:=FindComponent(prefix + IntToStr(i)) as TBaseBox;
    if b.Enabled

Это что за конструкция?? Может все таки
Код

if b <> nil then........
??
и OpenKey надо проверять на возвращаемое значение.

Автор: <Spawn> 5.6.2005, 15:16
Кстати, я массив ключей реестра по другому записал бы - зачем так память неэффективно расходовать)) Т.е. вот это:

Код

Keys: array [1..n] of string = (
 '\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer',
 '\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer',
 '\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer',
 '\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System',
 '\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System',
 '\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Network',
 ...
 );


Поменял бы на(А может и '\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\' стоит отуда выкинуть, если у тебя все ветки реестра находятся там):

Код

Keys: array [1..m] of string = (
 '\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer',
 '\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System',
 '\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Network',
 ...
 );


И добавил бы промежуточный индексный массив:

Код

KeyIndexes: array[1..n] of integer = (1, 1, 1, 2, 2, 3 ...);

Автор: The MASTER 5.6.2005, 15:29
Ты же сказал, что "\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\" откинешь?
Добавлено @ 15:30
Код

KeyIndexes: array[1..n] of integer = (1, 1, 1, 2, 2, 3 ...);


Рассталкуй пожалуйста неопытному что это значит?

Автор: Pakshin A. S. 5.6.2005, 19:24
Высказываю негодование...
1) 2Quadr0
Зачем в const... да затем... если компонентов будет на 50, а 3... менять в двух местах!!!! НЕХОРОШО!!!
Тип TBaseBox нужен для поиска соответствующих компонетов... Смотри внимательнее и читай поиск компонентов...
Ты наивный человек или незнающий... Почему это не найдет? Почему без имен?!
2) 2Dynamic
Конструкция не ясна? Может на первый взгляд да, но компоненты все всегда находятся... поэтому незачем проверять то, что найден компонент или нет... Здесь фишка в том, что у меня разделов в реестре таковых почти нету (не все есть)... поэтому что читать и изменять,е сли такого нету... поэтмоу при загрузки программы те параметры, которые отсуствуют не берутся в овнимание и соответствующие чеки становятся неактивными... аналогично неактивные чеки не рассматриваются при сохранении инфы...
OpenKey... не очень-то надо... при попытке чтения стоит try... автоматически исключается при этом попытка чтения/записи в несуществующий раздел, т. к. все отлажено через try и Enabled

P. S.
Вот... реальная доработка от Spawn'а... жаль сам не догадался... smile
Добавлено @ 19:24
Так... кто еще попытается найти серьезный баг в коде... СТАВЛЮ ПЛЮС!!!

Автор: Pakshin A. S. 5.6.2005, 19:41
Хех... объяснить что ли идею <Spawn>'а...

1) У нас все конечные ключи имеют одно и то же начало =>
Код

const
 KeyPrefix = 'SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\';

И уже будем обращаться так:
Код

 OpenKey(KeyPrefix + Keys[i], false);

Соответственно в Keys'ах сократится запись...
2) Действительно массив Keys занимает место... это нехорошо действительно...
Поэтому мы забодим константу, в которой будем хранить вообще все имена ключей, которые будем использовать
Код

const
 KeyNames: array [1..3] of string =(
 'Explorer',
 'System',
 'NetWork');

А в Keys'ах напишем порядковые номера имен ключей из константы KeyNames в соответствующем порядке...
Код

 Keys: array[1..n] of integer = (1, 1, 1, 2, 2, 3 ...);

Итого имеется экономия написания и места...
Вот теперь со всеми доработками будем писать обращение:
Код

 OpenKey(KeyPrefix + KeyNames[Keys[i]], false);

Автор: p0s0l 5.6.2005, 20:05
А зачем там b.Free ? smile
По смыслу, после LoadRegistry (и после записи) никаких чекбоксов не останется smile... Или я чего не понял опять ?...

Автор: Pakshin A. S. 5.6.2005, 20:31
Не наю... действительно вроде ничего... Аааа... вспомнил для чего така делал... Так память освобождается?
Добавлено @ 20:32
Или не так... короче вроде не мешает... smile

Автор: Albinos_x 5.6.2005, 20:35
Цитата
Он говорит, что этот код не верен...


Человек говорит или Не запускается?

Автор: Pakshin A. S. 5.6.2005, 20:41
А черт его знает... может он неверно константы записал... или еще что-нить...

Скорее всего трабл в константах...
Добавлено @ 20:41
Т. к. все вроде логически верно построено...

Автор: Albinos_x 5.6.2005, 21:02
Цитата
Т. к. все вроде логически верно построено...


согласен...

если только...

Код

with reg, Form1 do    
   begin    
    OpenKey(Keys[i], false);    
    b:=FindComponent(prefix + IntToStr(i)) as TBaseBox;    
    try    
     b.Checked:=ReadBool(Names[i]);    
    except    
     b.Enabled:=false;    
    end;    
    b.Free;     
    CloseKey    
   end;


...except...
не нравится, а не прервётся ли выполнение процедуры, если возникнет ошибка... (следовательно процедура выполнится не до конца)?

Добавлено @ 21:05
у себя я обычно пользуюсь KeyExists(key), а для проверки существования параметров в ключе отдельная функция написана

Автор: Pakshin A. S. 5.6.2005, 21:06
Неее... не должно... в других проектах такого у меня никогда не было... ТЕм более как оно может обрваться? Из-за чего?
Добавлено @ 21:08
Кстати... может и OpenKey засунуть в try... для верности... я ен очень хорошо помню работу данной функции...

Автор: Albinos_x 5.6.2005, 21:29
Цитата
OpenKey засунуть в try..


Не из-за неё ошибки не возникнет... Она просто вернёт false, если открыть не удалось...

Автор: Pakshin A. S. 5.6.2005, 21:30
Аааа... значит верно написал... smile

Автор: Albinos_x 5.6.2005, 21:35
Может он чего-то не правильно забил?

По крайней мере у меня компилится...

Автор: Pakshin A. S. 5.6.2005, 21:36
Угу скорее всего... У меня вообще таких параметров в реестре нету... smile А то мог бы проверить...

Автор: Albinos_x 5.6.2005, 21:39
Цитата
У меня вообще таких параметров в реестре нету...


Аналогично...

Автор: Pakshin A. S. 5.6.2005, 21:42
Хех... откуда он такую инфу взял.. smile И нафиг тогда прогу пишет... smile smile

Автор: Albinos_x 5.6.2005, 21:46
Цитата
И нафиг тогда прогу пишет..


Он начинающий?

Я вот тут подумал, может из-за не опытности, ему кто пример привел (без конкретных параметров), а он за истину принял?

Автор: sergejzr 5.6.2005, 21:52
Цитата(Pakshin @ 5.6.2005, 18:41)
Действительно массив Keys занимает место...

Экономить пару байт дешёвой памяти и расходовать драгоценный процессор на сложение...
Ну тут вопрос вкуса smile
<Spawn> имел ввиду, что одинаковые строки несколько раз писать не надо smile

Автор: p0s0l 6.6.2005, 00:00
Цитата(Pakshin @ 5.6.2005, 20:31)
Не наю... действительно вроде ничего... Аааа... вспомнил для чего така делал... Так память освобождается?
Добавлено @ 20:32
Или не так... короче вроде не мешает...
Ню-ню smile
Метод Free уничтожает объект. Объектом в данном случае является что ?... Правильно! Твой найденный FindComponent'ом чекбокс... То бишь, исчезнет он бесследно в небытие...
Во что потом тыкать мышкой-то будешь, если убъешь все CheckBoxы ? smile

Reg.Free - это правильно. А вот b.Free - совсем не к месту...

Автор: Dynamic 6.6.2005, 06:21
Цитата(Pakshin @ 5.6.2005, 19:24)
Высказываю негодование...

Не стОит, тебе же помочь пытаются.
Цитата(Pakshin @ 5.6.2005, 19:24)
компоненты все всегда находятся... поэтому незачем проверять то, что найден компонент или нет

В один прекрасный день может и не найтись. Если автор решит убрать один или несколько checkbox'ов, то ему придется: 1. Запомнить номера удаляемых компонентов 2.удалить связанные с ними Names 3. Добавить новые checkbox'ы и переименовать их в соответствии с номерами удаленных 4. Добавить новые Names.................
Цитата(Pakshin @ 5.6.2005, 19:24)
аналогично неактивные чеки не рассматриваются при сохранении инфы...

А если пользователь ручками добавит/удалит ключи или это сделает сама система при изменении каких-либо параметров, то до перезапуска прога их и искать не будет.
Цитата(Pakshin @ 5.6.2005, 19:24)
OpenKey... не очень-то надо... при попытке чтения стоит try... автоматически исключается при этом попытка чтения/записи в несуществующий раздел, т. к. все отлажено через try и Enabled

try/except вообще-то придумали не для отладки программы, а для обработки непредвиденных ситуаций, которые программист не может предусмотреть при разработке программы. Ф-я OpenKey сама по себе работает корректно + сообщает тебе о существовании/отсутствии ключа, но ты ее результат игнорируешь и проверяешь сам.

Все вышеизложенное - имхо.

ЗЫ. А вообще такие вещи легче программировать при пом. CheckListBox, но это, опять же, - ИМХО.

Автор: Pakshin A. S. 6.6.2005, 08:39
Dynamic, вот именно ИМХО... на работоспособность не влияет...

p0s0l... Ну раз так, то плюс... а я ухожу из раздела... не быть мне программистом... smile

Автор: Quadr0 6.6.2005, 09:30
...

Автор: p0s0l 6.6.2005, 17:17
Цитата
try/except вообще-то придумали не для отладки программы, а для обработки непредвиденных ситуаций, которые программист не может предусмотреть при разработке программы.
Не совсем понял твою мысль... Поподробнее... Если я делаю StrToInt(Edit1.Text) - то как быть тут ? Я заведомо знаю, что юзер может ввести вместо числа всякую хрень, значит, т.к. я предвижу тут возможную ошибку, я не могу использовать try..except ?

Цитата(Pakshin @ 6.6.2005, 08:39)
p0s0l... Ну раз так, то плюс... а я ухожу из раздела... не быть мне программистом...
Эй! Ты чего?! Все ошибаются smile...
Каюсь, даже я ошибаюсь! (а уж если Я ошибаюсь... то что говорить про других простых смертных! smile
(шучу) )...
Так что брось это... Если б ты был плохим программистом, то тебя бы не взяли комодератором...

Или это была шутка ? smile


Автор: Quadr0 6.6.2005, 17:48
...

Автор: Pakshin A. S. 6.6.2005, 17:54
>>Или это была шутка ?
Ну шутка... просто так... ради "красного словца" сказанул...

>>Из такого форума врят ли кто уйдёт
Верно! Если захотите избавиться, то это удет очень тяжело!!! smile smile

Автор: badaninslava 6.6.2005, 23:05
Pakshin A. S., мне нравится идентифицировоть все компоненты при поиске с помошью тегов- у меня была форма с 150(!) эдитами(пользоваться чем-либо другим запретили). Очень удобно было их заполнять из файла и наоборот и т.п. и необходимость знать имя отпала... В комментариях записал какому эдиту(по смыслу) какой тэг и всё...

Автор: The MASTER 7.6.2005, 20:53
Можно лучше было юзать тэги компонентов сразу.

Автор: Dynamic 8.6.2005, 07:43
Цитата(p0s0l @ 6.6.2005, 17:17)
Не совсем понял твою мысль... Поподробнее... Если я делаю StrToInt(Edit1.Text) - то как быть тут ? Я заведомо знаю, что юзер может ввести вместо числа всякую хрень, значит, т.к. я предвижу тут возможную ошибку, я не могу использовать try..except ?

Ну, во-первых, что значит "не могу"? Ты можешь делать все, что допускает синтаксис языка, включая goto в тело цикла for ;) (не так давно обсуждалось).
Во-вторых, для защиты от неверного ввода ("всякой хрени"), кроме try/except, есть StrToIntDef(), Val(), компонент MaskEdit.

А теперь посмотри на этот код:
Код
    try
     b.Checked:=ReadBool(Names[i]);
    except
     b.Enabled:=false;
    end;
Как ты думаешь - выполнится ли когда-нибудь код в секции except? Даже если ключ не существует? И в чем здесь смысл try/except?

Автор: p0s0l 8.6.2005, 10:45
Цитата(Dynamic @ 8.6.2005, 07:43)
Ну, во-первых, что значит "не могу"? Ты можешь делать все, что допускает синтаксис языка, включая goto в тело цикла for ;) (не так давно обсуждалось).
Ну давай так, не "не могу", а "судя по твоим словам, должен (лучше) использововать что-то другое"... Только не нужно про StrToIntDef и т.д. - вопрос не про это совсем smile. Вопрос про твои слова на счет try..except, а не про перевод строки в число smile. Попытайся ответить.
Цитата
А теперь посмотри на этот код:
А чего смотреть-то ? smile Я вопрос задал совсем не про код Пакшина...
Ну а раз спросил... На счет его кода - рекомендую посмотреть работу TRegistry, тогда бы ты такое, наверное, не сказал smile. Смысл его кода в том, что если какого-то значения не существует в реестре, то нужный чекбокс станет отключенным. Я бы конечно немного по-другому сделал, но его код одноразово-почти-рабочий, как ни крути, и смысл есть smile. Может ты думаешь, что TRegistry не генерирует исключения ? Тогда ошибаешься....
Цитата(Dynamic @ 8.6.2005, 07:43)
Как ты думаешь - выполнится ли когда-нибудь код в секции except?
Да
Возможно, ты сам поймешь, что тут и как, когда попробуешь написать этот же код без try..except (и заранее, а то ведь напишешь smile, без ValueExists).

ЗЫ: Возможно ошибаюсь, но у меня складывается впечатление, что ты немного путаешь (вернее не различаешь) понятия "ключ" (key) и "значение" (value). Поэтому ты и заблуждаешься на счет кода Пакшина (либо плохо посмотрел код)...

Автор: Dynamic 10.6.2005, 19:34
Цитата(p0s0l @ 8.6.2005, 10:45)
ЗЫ: Возможно ошибаюсь, но у меня складывается впечатление, что ты немного путаешь (вернее не различаешь) понятия "ключ" (key) и "значение" (value). Поэтому ты и заблуждаешься на счет кода Пакшина (либо плохо посмотрел код)...

Блин, точно, все в кучу смешал. Сорри всем, кого обидел smile smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)