Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Отображение begin .. end другим цветом (D2005)


Страницы:   1 2

Eugene74 ©   (2005-06-09 16:47:00) 

Добрый день.
Подскажите, пожалуйста, можно ли добиться в редакторе Delphi 2005 отображения слов-скобок beginи endдругим цветом? Но только этих двух, а не всех зарезервированых слов! Хочу как раз, чтобы они визуально не смешивались с другими (ведь все отображаются одинаковым черным жирным шрифтом), чтобы улучшилась читаемость кода.

Под предыдущими версиями Delphi этого эффекта можно было добиться с помощью CodeRush:
http://www.devexpress.com/Products/VCL/CoderushDelphi/i/features/StructuralHighlightingCR6.gif

Но версию для D2005 они, похоже, не собираются выпускать, а с помощью стандартных средств, Castalia и GExperts мне этого добиться не удалось. Может где что просмотрел?


КиТаЯц   (2005-06-14 07:19:00) [1]

>-=XP=- ©   (13.06.05 20:18) [19]

Респект! :)


try..finally   (2005-06-14 06:28:00) [2]

А где, интересно, begin..end ©?


Eugene74   (2005-06-14 02:33:00) [3]

record-то был и в Pascal
ага, значит, они уже тогда чувствовали, что не надо совать begin/end куда-ни-попадя :)

Питона я боюсь, так как случайно/намеренно переформатировав код ты изменишь его смысл.
а мне он именно этим нравится, тем более что я форматирую код преимущественно намеренно :) ну а случайности - они при любой системе могут случиться

что мне не очень понравилось
ну, мне это тоже не нравится, но в данном случае я хотел просто показать, как ту же самую конструкцию можно записать более понятным образом.

P.S. В случае чего, сегодня уже не отвечу, ухожу спать...


Просто Джо   (2005-06-14 01:51:00) [4]


> ry/finally/end  или объявлениях классов 'end' уже по сути
> не является закрывающей скобкой для якобы подразумеваемого
> begin,

Ну, record-то был и в Pascal.

А по поводу Питона - ужасть :) Питона я боюсь, так как случайно/намеренно переформатировав код ты изменишь его смысл. Но такая "дискуссия" - не для этой ветки.

Но то, что мне не очень понравилось в твоем Делфовском коде,  присутствует и в псевдо-питонском коде. Например: наличие дублирующегося кода (Handled:=True), два Exit'а, большая (и ненужная) вложенность сравнений (ее можно легко избежать).
Это все, конечно, исключительно без претензий на непогришимость собственного мнения, так, простой имхо.


Eugene74   (2005-06-14 01:45:00) [5]

И, имхо, не стоит так поступать с чек-боксами, пользователь может случайно поставить/наснимать галок, сам того не заметив.
Ну, это я так, в качестве эксперимента :)
Хотя мне самому так управлять чекбоксом очень даже понравилось. Кликать мышкой уже лень :)


Eugene74   (2005-06-14 01:35:00) [6]

Просто Джо
Спасибо. Наверное, такой подход (модульность, разбиение кода на небольшие понятное кирпичики) действительно наиболее правильный.

Хотя это и означает, что синтаксис Delphi может быть понятным только в небольших кусочках линейного кода :(

Как бы то ни было, придется так и переделывать. Так что еще раз спасибо.

Я тем временем тоже еще подумал над своим примером.

Синтаксическая ошибка: отсутствует ';' в самом конце.

Логическая ошибка: else в середине цикла относится не к первому if, а ко второму, т.к. перед else нет ';'. Но если поставить эту ';' - то этим самым не только второй, но и первый if "оформится" в отдельный оператор. Выход: обрамление скобками begin/end всего блока then первого if.

А вот как бы выглядел код цикла в стиле Python:

for I in Self:
   if (I is TsSpinEdit):
       with (I as TsSpinEdit):
           if (Handle = h) or (Button.Handle = h):
               Value += Increment * wd
               Handled = True
               Exit
   elif (I is TsCheckBox):
       with (I as TsCheckBox):
           if (Handle = h):
               if State = cbChecked:
                   State = cbUnchecked
               else
                   State = cbChecked
               Handled = True
               Exit

Насколько меньше знаков! А самое главное: все понятно. Логические отступы и определяют синтаксическую конструкцию!

Ну это так, отвлечение. Понятно, что такие радикальные изменения в Delphi никогда не будут внесены, т.к. нарушится совместимость с TurboPascal/ObjectPascal.

Спасибо Borland и за то, что в новых языковых конструкциях ("новых" - относительно "стариков" if и for из Pascal) типа try/finally/end  или объявлениях классов 'end' уже по сути не является закрывающей скобкой для якобы подразумеваемого begin, а непосредственно закрывает try/type. (По крайней мере я так это понимаю.)


Просто Джо   (2005-06-14 00:48:00) [7]

[29] Просто Джо ©   (14.06.05 00:27)
В процедуре HandleWheel строка Result := False - разумеется, лишняя.

И, имхо, не стоит так поступать с чек-боксами, пользователь может случайно поставить/наснимать галок, сам того не заметив.


Просто Джо   (2005-06-14 00:27:00) [8]

Я бы сделал так:


function InvertCBState (AState: TCheckBoxState): TCheckBoxState;
begin
case AState of
  cbChecked:
    Result := cbUnchecked;
  cbUnchecked:
    Result := cbChecked
  else
    Result := AState;
end;
end;

function HandleSpinEdit (AControl: TControl; AWheelDelta: Integer): Boolean;
begin
Result := AControl is TSpinEdit;
if Result then
  with TSpinEdit(AControl) do
    Value := Value + Sign(AWheelDelta)*Increment;
end;

function HandleCheckBox (AControl: TControl): Boolean;
begin
Result := AControl is TCheckBox;
if Result then
  with TCheckBox(AControl) do
    State := InvertCBState(State);
end;

function HandleWheel (AForm: TForm; Delta: Integer; MousePos: TPoint): Boolean;
var
 AControl: TControl;
begin
 Result := False;
 MousePos := AForm.ScreenToClient(MousePos);

 AControl := AForm.ControlAtPos(MousePos,False,True,True);

 Result := (Assigned(AControl)) and
   (HandleSpinEdit(AControl, Delta) or HandleCheckBox(AControl));
end;

// Собственно, сам обработчик события
procedure TForm1.FormMouseWheel(Sender: TObject; Shift: TShiftState;
WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
begin
 Handled := HandleWheel(Self,WheelDelta,MousePos)
end;


Каждая функция имеет свое четкое назначение, которое (я надеюсь) понятно из названия. Таким образом, вся логика легко выносится в отдельный юнит; место ошибки легко локализовать; необходимость сложных условий и циклов отпадает. Кроме того, очень легко расширить данный пример для обработки других контроллов не меняя уже отлаженную логику.


Eugene74   (2005-06-13 22:58:00) [9]

Да, Delphi 2005 (но это imho влияет только на цикл for по элементам коллекции, которого не было в предыдущих версиях).

Дать переменным хорошие имена. I - переменная цикла, но никак не экземпляр объекта. Это тоже очень важно и способствует пониманию кода.
OK, учту. Хотя, I, в данном случае, как бы и то и другое.

Но ошибка в коде все-таки есть или нет?


Eugene74   (2005-06-13 22:51:00) [10]

Да к тому же, еще и с синтаксическими ошибками.
можно узнать, что это за ошибки (т.е. какое синтаксическое правило нарушено) и в каких именно местах?


Просто Джо   (2005-06-13 22:47:00) [11]

Ах, черт, синтаксическую ошибку снимаю, это же Delphi 2005, насколько я понял?


Просто Джо   (2005-06-13 22:42:00) [12]

Как, минимум, нужно сделать:

1. Устранить синтаксическую ошибку:
for I in Self do begin
  if (I is TsSpinEdit) then

2. Дать переменным хорошие имена. I - переменная цикла, но никак не экземпляр объекта. Это тоже очень важно и способствует пониманию кода.


Eugene74   (2005-06-13 22:39:00) [13]

Просто Джо
Скобки (не важно, в какой форме) отнюдь не предназначены для "улучшения логики" кода.
Но для её выражения.

В приведенном Вами примере код настолько запутан логически, что его нужно упрощать.
Вообще-то я пострался форматированием как раз выразить логику. Но опишу еще раз словами, включая то, что собственно было задумано.

Процедура предназначена для изменения значений SpinEdit- и CheckBox-контролов простой наводкой курсора поверх них и прокруткой колеса мыши.

Процедура вызывается по событию формы OnMouseWheel.
h - хэндл окна под курсором.
Делается цикл по всем child-компонентам формы.
Если текущий компонент - TsSpinEdit и его хэндл или хэндл кнопок прокрутки, встроенных в него (используются AlphaControls), равен h, то значение TsSpinEdit увеличивается или уменьшается в зависимости от направления прокрутки колеса мыши.
Если текущий компонент - TsCheckBox, то выполняется аналогичная проверка на Handle и галочка снимается или убирается.


Просто Джо   (2005-06-13 22:14:00) [14]

Да к тому же, еще и с синтаксическими ошибками.


Просто Джо   (2005-06-13 21:47:00) [15]

2 Eugene74
Скобки (не важно, в какой форме) отнюдь не предназначены для "улучшения логики" кода. В приведенном Вами примере код настолько запутан логически, что его нужно упрощать. Расстановкой скобок здесь, повторю, дела не улучшишь.
Попробуйте выразить приведенный код обычными словами. Сходу это не получится, это и есть верный признак запутанного, иными словами, плохого кода. Используйте любые доступные методы рефакторинга и перепишите его.


Eugene74   (2005-06-13 20:40:00) [16]

еще раз последний кусок предыдущего поста, который получился сплошным курсивом:

begin..end ... - часть программы, выполняющая вполне определенные действия.

так ведь в том то и дело, что они абсолютно никаких действий не выполняют!

Перефразируя: "Представьте, что было бы, если бы в нормальном языке нельзя было бы употреблять "Начало", Конец" в качестве скобокнадо здесь вставить, чтобы сравнение было корректным , а вместо это надо было бы писать (..)". ;)

но это не надо представлять. Оно так и есть :)

Я все время путаюсь в скобках. Особенно в математических выражениях, когда в одном выражении больше 5-6 пар скобок. С begin/end у меня такой путаницы практически не возникает.

Пример такого математического выражения со скобками - в студию, а потом его же с begin/end вместо скобок :)


Eugene74   (2005-06-13 20:36:00) [17]

-=XP=-
За Sign спасибо (но для этого надо добавлять модуль Math).
С CheckBox так просто не получится (поправьте, если ошибаюсь). Дело в том, что State - это не булев тип, и там есть еще третий вариант cbGrayed, при котором состояние чекбокса меняться не должно.
За ControlAtPos тоже спасибо, попробую переписать. Btw вопрос. Только что в справке прочитал "ControlAtPos returns an immediate child of the control". Получается, если те же spinedit'ы лежат на панели внутри формы, то этот метод возвратит ссылку на панель, а не на spinedit?

begin..end ... - часть программы, выполняющая вполне определенные действия.
так ведь в том то и дело, что они абсолютно никаких действий не выполняют!
Перефразируя: "Представьте, что было бы, если бы в нормальном языке нельзя было бы употреблять "Начало", Конец" в качестве скобок , а вместо это надо было бы писать (..)". ;)
но это не надо представлять. Оно так и есть :)

Перефразируя: "Представьте, что было бы, если бы в нормальном языке нельзя было бы употреблять "Начало", Конец", а вместо это надо было бы писать (..)". ;)
Пример математического выражения со скобками - в студию, а потом его же с begin/end вместо скобок :)


-=XP=-   (2005-06-13 20:18:00) [18]

Скобки, они ведь на то и скобки, чтобы как раз визуально выделять группы слов. Представьте, что было бы, если бы в нормальном языке нельзя было бы употреблять (), а вместо это надо было бы писать начало .. конец.

Очень, очень дискутивно. Хотя бы исходя из того, что {..} или begin..end называются "операторными скобками". Вот тут вся загвоздка. Вы выделяете слово "скобки". Я же выделяю слово "операторные". Для Вас это - группы слов. Для меня - часть программы, выполняющая вполне определенные действия. Для Вас - участок текста. Для меня - совокупность действий. Для Вас - синтаксис. Для меня - семантика. Вам - выделить. Мне - начать.
Перефразируя: "Представьте, что было бы, если бы в нормальном языке нельзя было бы употреблять "Начало", Конец", а вместо это надо было бы писать (..)". ;)

P.S. Я все время путаюсь в скобках. Особенно в математических выражениях, когда в одном выражении больше 5-6 пар скобок. С begin/end у меня такой путаницы практически не возникает. Мне обратиться к окулисту или к психиатру? :(


-=XP=-   (2005-06-13 20:05:00) [19]

if WheelDelta >= 0 then wd := 1 else wd := -1;
WD := Sign(WheelDelta);

if State = cbChecked then
 State := cbUnchecked
else
 State := cbChecked;

Checked := not Checked;

Кроме того, если вместо WindowFromPoint использовать ControlAtPos(), то весь Ваш код становится намного короче.

:о)


Eugene74   (2005-06-13 19:39:00) [20]

Спасибо вам за ответы. В общем-то я не ратую именно за {} вместо begin/end. Скорее, мне импонирует синтаксис VB/VBS или, еще более прогрессивно, Python.

Eugene74
времени много уходит на проверку логических конструкций

Попробую объяснить, что я имею ввиду. Может, вы мне сможете подсказать, как можно писать более лаконичный и понятный код.

Посмотрите на эту небольшую процедуру (последняя в модуле). Есть ли здесь синтаксические или логические (в данном случае под этим будем понимать противоречие с визуальным форматированием) ошибки? Если да, то где именно и как их исправить? Если не секрет, сколько времени занял анализ, только честно? При любом варианте: как бы вы написали такую процедуру?

procedureTForm1.FormMouseWheel(Sender: TObject; Shift: TShiftState;
 WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
var
 h: hWnd;
 I: TComponent;
 wd: Integer;
begin
 h := WindowFromPoint(MousePos);
  ifWheelDelta >= 0 thenwd := 1 elsewd := -1;
  forI inSelf do begin
    if(I isTsSpinEdit) then
      with(I asTsSpinEdit) do
        if(Handle = h) or(Button.Handle = h) then begin
         Value := Value + Increment * wd;
         Handled := True;
         Exit
        end
    else if(I isTsCheckBox) then
      with(I asTsCheckBox) do
        if(Handle = h) then begin
          ifState = cbChecked then
           State := cbUnchecked
          else
           State := cbChecked;
         Handled := True;
         Exit
        end
  end
end


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо