![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Отображение begin .. end другим цветом (D2005)
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