Поскольку никто не захотел принимать участие в создании синтаксиса, взял эту ответственность на себя. Получилось примерно вот такое:
virtual TNotifyEvent "OnChange" { load = FOnChange; save = FOnChange; }; virtual TConstraintSize "MaxHeight" { load = FMaxHeight; save = SetConstraints(0, Value ); }; virtual TConstraintSize "MaxWidth" { load = FMaxWidth; save = SetConstraints( 1, Value ); };
Имена свойств всегда строка, а не имя и это используется двояко. Во первых компилятор точно знает, что это свойство, во вторых я могу создавать имена, которые невозможно вызвать из кода, например с точкой или стрелочкой. Чтобы они вызывались только из бакэнда VM.
Продолжаю портирование VCL, честно говоря не думал что класс TControl окажется настолько гигантским. Это какой-то суперкласс, антипаттерн, ИМХО.
g-cont
> честно говоря не думал что класс TControl окажется настолько гигантским. Это
> какой-то суперкласс, антипаттерн, ИМХО.
пока не завезли ГУЁвой библиотеки без суперкласса.
skalogryz
> пока не завезли ГУЁвой библиотеки без суперкласса.
Ну супер не супер, но в Delphi TControl действительно перегружен лишним мусором. Я вот просто пробежался по полям объекта, и пометил то, что на мой взгляд что нужно, а что нет:
И вот насколько класс становится короче без ненужных полей:
оффтоп от контролов! НО оказалось что в FPC выражение-case разрешает ключевое слово otherwise (https://ideone.com/Aaj6AF)
var a : integer; begin (* your code goes here *) a := 5; case a of 1: writeln( 'one'); 2: writeln( 'two'); otherwise // D: writeln( a); end; end.
когда это всё успели?!
MrShoor
> Я вот просто пробежался по полям объекта, и пометил то, что на мой взгляд что нужно, а что нет
FIsControl: Boolean; // ---- явный костыль, не нужно
лол... название доставляет, конечно.
Determines whether this object shall be streamed as a control.
Delphi compatible property, affecting only the streaming of Form properties.
а в Delphi нашлось даж такое:
function TCustomForm.IsForm: Boolean; begin Result := not IsControl; end;
и 100500 свойств в форме, которые зависят от IsForm.
skalogryz
otherwise это аналог default: ?
А из класса TControl я выбросил только BiDiMode, это какой-то арабский режим отображения текста справа налево.
g-cont
> otherwise это аналог default:
да. но в делфи ты встретишь только else
Как заставить произвольные контролы рисоваться поверх окна OpenGL(OpenGLControl)? Всякие TSpinEdit-ы и TTrackBar-ы спокойно рисуются поверх, а вот батоны не хотят ни в какую, хоть как не меняй Z-порядок. Нужен вывод батона с полупрозрачным глифом.
ArtProg
TWinControl::PaintTo
Попробовал использовать при отрисовке OpenGL окна по таймеру:
TWinControl(test_speed_button).PaintTo(OpenGLControl.Handle,0,0);
Но вылетает с ошибкой. На этапе компиляции пишет такое: "Class types "TSpeedButton" and "TWinControl" are not related", что впринципе логично.
Такой способ
F_MainForm.PaintTo(OpenGLControl.Handle,0,0);
тоже не помогает.
Обычный баттон рисуется без проблем, но мне как раз нужно вывести контрол с прозрачной картинкой, чего стандартный TButton вроде как не умеет(пробовал подсунуть вместо кнопки TImage с прозрачной картинкой, но тоже на отрисовывается поверх).
ArtProg
Визуальные контролы можно разделить на две больших группы - наследники TWinControl и TGraphicControl.
Первые имеют под собой настоящее окно Windows - HWND и все дела, зачастую заимствуют своё поведение от стандартных контролов Windows из её dll-ек оборачивая в обёртку класса Delphi.
Вторые - "легковесные" и рисуются на канвасе родителя и не имеют под собой HWND, поэтому и легковесные, поэтому полностью реализуются в коде Delphi.
Соответственно первые у тебя нормально рисуются потому что их обрабатывает сама винда.
Вторые нет потому что с OpenGL несовместимы и тупо рисуются на канвасах родителя (OpenGL тут не при делах).
TPanel положи а сверху кнопку\картинку\что тебе надо.
=A=L=X=, да, это многое обьясняет, полезная информация, спасибо!
kipar, таки получилось). Нашел на форуме Лазаруса вот такой костыль:
Panel.ControlStyle:=Panel.ControlStyle-[csOpaque]+[csParentBackground];
Единственное, что после обновления экрана нужно обновлять и саму панель, то есть:
if Panel.Visible then Panel.Invalidate;
ArtProg
> Единственное, что после обновления экрана нужно обновлять и саму панель, то
> есть:
Нужно рендер делать в обработчике WM_PAINT, и тогда не надо будет вручную обновлять.
MrShoor
> Нужно рендер делать в обработчике WM_PAINT, и тогда не надо будет вручную
> обновлять.
да? Я что должен каждый раз дополнительно ещё вызов делать при использовании PeekMessage?
Тема в архиве.