WindowProc всередині об’єкта

Всім доброго доби! У мене таке запитання: Чи можна призначити вікну віконну процедуру всередині об'єкта?

Я правильно зрозумів питання.

private OldProc: TWndMethod; процес NewProc(var msg: TMessage);

procedure TForm1.FormCreate(Sender: TObject); begin OldProc := ScrollBox1.WindowProc; ScrollBox1.WindowProc := NewProc; end;

procedure TForm1.NewProc(var msg: TMessage); begin OldProc(msg); case msg.Msg of WM_VSCROLL: label1.caption:="vert"; WM_HSCROLL: label1.caption: = "horiz"; end; end;

Правильно, лише реалізація не та. Я мав на увазі (чому відразу не написав?

Справа в тому, що я не використовую VCL.

Я може неправильно зрозумів, але у вихідниках TApplication у конструкторі (виклик CreateHandle) створюється вікно з віконною функцією WndProc, яка є методом самого TApplication. Хоча, можливо, я не нищу, адже TApplication це VCL. Подивися, може, допоможе.

З методом об'єкта не вийде через неявний параметр Self.

Але якщо Ви не використовуєте VCL, то чому б не призначити вікну звичайну функцію, не метод об'єкта (SetWindowLong з GWL_WNDPROC)? Це точно пройде.

"З методом об'єкта не вийде через неявний параметр Self."

А детальніше не можна? Начебто, в TApplication.CreateHandle саме SetWindowLong викликається з методом класу TApplication.

Загалом це можна зробити, але я не знаю як. Метод об'єкта, адже він теж містить код, значить можна якось дістати покажчик на цей код. ?

так млинець, WndProc - метод TApplication

FObjectInstance := MakeObjectInstance(WndProc); FHandle :=CreateWindow(WindowClass.lpszClassName, PChar(FTitle), ляля SetWindowLong(FHandle, GWL_WNDPROC, Longint(FObjectInstance));

те, що відбувається в MakeObjectInstance вище мого розуміння :)

http://delphi.mastak.ru/cgi-bin/forum.pl?look=1&id=1028003759&n=0 тут до речі є код :) треба в чужі питання іноді заглядати :)

Так, такий спосіб також відомий. В кінці не забудьте відновити все назад і викликати FreeObjectInstance.

Але незрозуміло - Ви ж кажете, що не використовуєте VCL, то звідки ж об'єкт з'явився?

Це теж до VCL? :-)))

Слово "Visual" не повинно вводити в оману. Це всього лише не цілком точна назва, аСУТЬ- у коді.

Чи я щось не так зрозумів?

До речі, писати у верхньому регістрі очевидно неправильні речі не варто було б :))

TObject - це основний елемент мови Object Pascal, і розробники помістили його у модулі бібліотеки часу виконання, описується він у модулі System і до VCL жодного відношення не має.

У MakeObjectInstance віконна процедура пов'язується з об'єктом. У пам'яті динамічно створюється код, який приймає параметри віконної процедури, створює запис типу TMessage і передає їх "віконної" функції об'єкта, яка вже шукає потрібний обробник повідомлення для об'єкта. Весь цей код знаходиться в модулі Forms, отже, вся VCL все одно потрапить у програму. Щоб цього уникнути, потрібно видерти з модуля Forms весь код, пов'язаний з MakeObjectInstance.

> розробники помістили його у модулі бібліотеки часу виконання

І що з того? Від цього він перестав бути частиною VCL?

У run-time модулях можуть жити і візуальні об'єкти. Вони також перестають бути частиною VCL?

Хіба VCL -це тільки те, що входить до палітри компонентів IDE?

А те, що вони входять в RTL, говорить тільки про те, що VCL складається як з run-time, так і design-time модулів. От і все.

Отже, "очевидно неправильні речі", згідно з структурою довідки Delphi, є не менш очевидно правильними. У будь-якому регістрі. :о)

Виявляється, я все життя говорив прозою.

Занадто вже ємним поняття VCL виходить. VCL, VCL і нічого крім VCL :-(

> Старий паскаліст (03.08.02 16:33)

Ще раз подивився в тій же довідці - модулі Windows, ShellAPI і подібні до них в VCL не числяться.

Так що не все так погано, колега - системні бібліотеки частиною VCL все ж таки не є. :о)

Що дає нам, старим паскалістам, певну віддушину.

1) використання класів саме собою використання VCL не означає. VCL – це бібліотека, класи – частина синтаксису Object Pascal, з використанням якої, зокрема, написана VCL. Тип tObject визначений у модулі системи. За всієї поваги до Ю.Зотова, змушений підтримати "Ги-ги..".

2) Метод у класі – штука досить кумедна. По-перше, має неявний параметр Self, по-друге, процедурна змінна procedure/function(. )of object - це, на відміну від звичайної процедурної змінної, не покажчик на точку входу, а масив із двох покажчиків - на точку входу і на блок даних. Виходячи з викладеного, очевидно, що використовувати метод як WndProc практично неможливо.

> VCL – це бібліотека, класи – частина синтаксису Object Pascal

Безперечно. Тому, якщо ми використовуємо СВОЮ ієрархію класів, ні від чого не успадковану, а повністю і самого нуля написану ручками - то ми використовуємо ТІЛЬКИ мову і нічого більше. Але як тільки ми успадкували хоча б один свійклас від TObject з модуля System, або від будь-якого його нащадка – ми використовуємо VCL.

Тому я написав - "Якщо Ви мали на увазі TMyObject = class (TObject)".

2Юрій Зотов: Знову не можу з Вами погодитися. Модуль System не є частиною VCL, він відноситься до RTL і практично необхідний для будь-якої програми, що хоч використовує VCL, хоч не використовує. А тип tObject визначений саме у модулі System. Вирази type tX=class end; та type tY=class(tObject) end; насправді еквівалентні, і клас tX є неявним нащадком tObject і містить у собі той самий набір властивостей і методів, як і tY. А з Вашого твердження, таким чином, випливає, що будь-яке використання будь-яких класів у програмі означає використання VCL, що суперечить вами ж висловленому судженню про ієрархію класів, що ні від чого не залежить, як шляхи невикористання VCL.

2Юрій Зотов а якщо він мав на увазі просто "TMyObject = class"? :-)))))

Взагалі кажучи, важко на Дельфі написати ієрархію класів, не успадковану від TObject. (Пережитки турбопаскаля поза рахунок).

Проте Борланд подолав це вузьке місце – див. вище.

> А з Вашого твердження, таким чином, випливає, що використання будь-яких класів у програмі означає використання VCL.

Саме так. На підтвердження я навів структуру довідки Delphi - з неї випливає, що сама Borland розглядає модуль System як частину VCL. Якщо ж це так, то вся RTL є частиною VCL - а тоді, навіть написавши у програмі не те що слово "class", а просто виклик будь-якої вбудованої функції, ми вже використовуємо VCL.

> . що суперечить вами ж висловленому судженню про ієрархію класів, що ні від чого не залежить, як шляхи невикористання VCL.

Ні, не суперечить.Тому що це судження, звісно, ​​суто гіпотетичне. Реалізувати таку незалежну ієрархію практично неможливо, бо сам компілятор вже " заточений " під TObject, як базовий клас.

> а якщо він мав на увазі просто "TMyObject = class"?

. то це, як усі ми знаємо, абсолютно одне й те саме.

Панове, я пропоную припинити цю теоретичну дискусію. Ми чудово розуміємо одне одного і питання зводиться лише до того, чи є RTL частиною VCL, чи ні. Відповідаючи "так", ми маємо визнати правоту однієї сторони, відповідаючи "ні" - іншій стороні.

Ми дивимося на це по-різному і навряд чи хтось зможе переконати когось. Розсудити нас, мабуть, може лише Borland, а звертатися до неї щодо термінології навряд чи має сенс.

Але від суперечки я отримав насолоду. Дякую.

Я тут залізу з приводу, що рахувати VCL, а що ні. Імху свою висловлю. :o) Це краще у Borland запитати. Але можна і на структуру каталогу джерел подивитися - там чітко видно, що Borland вважає RTL, що VCL, що CLX і т.д.

Цитата з довідки Delphi5 :Когда ви збираєтеся Classs of your own in Object Pascal, вони повинні бути переміщені відTObject. Використовуючи нові класи відVCL's base class(або один з його послідовників), ви надаєте свої класи з принциповою функціональністю і надійністю, що вони працюють з VCL.

Таким чином, Borland називає TObjectбазовим класом VCL. Оскільки всі класи успадковуються від TObject, то використання класів є використання VCL.

АЛЕ, об'єкти в Object Pascal можна оголосити і майже забутою директивоюobject. І ось тут VCL вже не до того, т.к. за такого визначення об'єкт перестав бути спадкоємцем TObject, отжене використовує VCL.