Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2002.03.04;
Скачать: [xml.tar.bz2];

Вниз

Вопрос к гуру от почти гуру. Доступ к protected методам   Найти похожие ветки 

 
cpp   (2002-02-15 11:32) [0]

Вот процедура формы Пример из справки Delphi

procedure TForm1.SaveAsBmpClick(Sender: TObject);
var
Source: TComponent;
SysPal : LogPal;
tempCanvas: TCanvas;
sourceRect, destRect: TRect;
image2save: TImage;
notUsed: HWND;
begin
Source := FindComponent(Edit1.Text);
if (not Source is TControl) or
((not Source is TWinControl) and ((Source as TControl).Parent = nil)) then
begin
Beep;
ShowMessage(Edit1.Text + " is not a valid control.");
Exit;
end;
tempCanvas := TCanvas.Create;
try
with Source as TControl do
tempCanvas.Handle := GetDeviceContext(notUsed);

Обратите внимание метод GetDeviceContext - protected !
не проходят конструкции типа

tempCanvas.Handle := (Source as TControl).GetDeviceContext(notUsed);
tempCanvas.Handle := TControl(Source).GetDeviceContext(notUsed);

В чём дело?


 
troits   (2002-02-15 11:36) [1]

TMyClass = class(TWinControl)
public
function GetDeviceContext(var WindowHandle: HWnd): HDC; override;
end;

function TMyClass.GetDeviceContext(var WindowHandle: HWnd): HDC;
begin
result := inherited;
end;

...

tempCanvas.Handle := TMyClass(Source).GetDeviceContext(notUsed);



 
troits   (2002-02-15 11:48) [2]

Да... А в примере баги явные - например, перед else ;
Так что торопились, наверное - не проверяли...


 
Юрий Федоров   (2002-02-15 11:56) [3]

Не надо писать своего потомка, потому что сам класс
TForm1 является потомком TControl и TWinControl.
То есть типизировать можно под TForm1 :

tempCanvas.Handle := TForm1(Source).GetDeviceContext(notUsed);
Только без использования As


 
Digitman (M)   (2002-02-15 12:11) [4]

Пример, видимо, с ошибкой. либо когда-то Борланд объявил его в public, а затем, по каким-то причинам (в принципе - по вполне понятным) решил перенести в protected, а хэлп не подредактировал в соответствии с изменениями. Что ж , и великий Борланд имеет право на ошибку, согласись ?

Ну, что тут можно сделать ? Попробуй "выдрать" участки кода, реализующие функ-ть этого метода, из модуля Controls прямо в свой код. Не так уж там и много : собственно тело TControl.GetDeviceContext() и тело TWinControl.GetDeviceContext(), которое исполняется для объекта, являющегося Parent для текущего контрола. Всего-то в общ.сложности - дюжина доп.строчек. Можно даже прямо на WinAPI их реализовать. Мороки, конечно, чуть больше, но, если оч.нужно, то не так уж и проблематично получить тот же результат "через задний кирильцо")


 
troits   (2002-02-15 12:16) [5]

>Юрий Федоров
Честно говоря, я не вижу никаких преимуществ Вашего способа. Все равно придется переносить GetDeviceContext в public. А объявлением вспомогательного класса пример становится более понятным - мы не "замусориваем" класс TForm.


 
Digitman (M)   (2002-02-15 12:39) [6]

А вообще-то GetDeviceContext() здесь вызывается не для TControl(Source) , а для self. Компилятор, не обнаружив public-метода у Source as TControl, справедливо подставил вызов собственного protected-метода объекта Self. Скомпилировано будет без ошибок (здесь не рассматриваем явные синтакс.ляпы в примере), но работать, конечно же, будет неверно : в *.BMP будет сохранен совершенно не тот BMP-образ, который ожидался (хотя размер образа будет совпадать с размерами контрола на форме)


 
Юрий Зотов (M)   (2002-02-15 12:42) [7]

troits © (15.02.02 12:16)

Ничего никуда переносить не нужно. И никаких своих потомков писать тоже не нужно. Общий способ доступа к protected-секции любого класса - это объявить в своем юните потомка этого класса (только объявить, больше ничего не требуется). Например:

type
TFriendClass = class(TSomeClass);

После этого в своем юните Вы получаете доступ к protected-секции класса TSomeClass, приводя его к TFriendClass.

А поскольку класс TForm1 у Вас уже и так объявлен, то можно приводить к TForm1.


 
troits   (2002-02-15 12:45) [8]

Да. Был не прав.


 
Digitman (M)   (2002-02-15 13:14) [9]

Да, <Юрий Зотов> прав. Все, что надо здесь - это объявить дружественный класс как вспомогательный тип. К нему-то и следует, в конечном итоге, приводить тип найденного по FindComponent() контрола. Сойдемся на том, что в своем примере Борланд все же допустил ошибку, связанную с отсутствием декларации друж.класса и некорректного приведения типа.

С учетом всех этих замечаний участок проблемного кода в примере должен будет выглядеть так :


type
TFriendControl = class(TControl);//дружественный класс
...

tempCanvas.Handle := TFriendControl(Source).GetDeviceContext(notUsed);

вот и все, вот и заработало как надо)


 
cpp   (2002-02-15 13:19) [10]

Пример без ошибок и Digitman (M) прав.


 
cpp   (2002-02-15 13:21) [11]

когда говорил что

Компилятор, не обнаружив public-метода у Source as TControl, справедливо подставил вызов собственного protected-метода объекта Self.



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2002.03.04;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.006 c
1-9166
VSoft
2002-02-14 07:49
2002.03.04
Кол-во файлов и их имена в определенном каталоге


3-9085
HDD
2002-02-06 01:27
2002.03.04
Помогите пожалуйста срочно нужно. Очень срочно


1-9183
USAtyj
2002-02-12 18:21
2002.03.04
Про массивы и про High() (+)


4-9330
Hair_Fly
2001-12-17 13:38
2002.03.04
МАСТЕРА, плз, помогите разобраться с CreateProcessWithLogonW!


1-9108
Igl
2002-02-15 21:50
2002.03.04
Как можно сделать эквалайзер?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский