Модераторы: Poseidon, Snowy, bems, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Такая вот загадка... WM_PAINT у TControl 
:(
    Опции темы
Limonadni Joe
Дата 19.6.2005, 22:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 311
Регистрация: 1.11.2002
Где: Москва

Репутация: нет
Всего: 2



Посмотрим на код обработчика события WM_PAINT в классе TWinControl:

Код

  if not FDoubleBuffered or (Message.DC <> 0) then
  begin
    if not (csCustomPaint in ControlState) and (ControlCount = 0) then
>>    inherited   <<
    else
      PaintHandler(Message);
  end
  else
  ...

На сколько я смог отследить, именно за счёт этого inherited рисуется фон компонента. А загадка в том, что обработчика события WM_PAINT у класса TControl нет, хотя именно на него ссылается inherited. Как такое может быть? Может я что-то путаю? Или кривыми руками искал событие?

Помогите разобраться откуда берётся серый фон у TWinControl. У компонента-брата TGraphicControl этого фона нет, хотя он тоже наследует от TControl.
PM MAIL ICQ YIM MSN   Вверх
Yanis
Дата 19.6.2005, 23:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2937
Регистрация: 9.2.2004
Где: Москва

Репутация: 72
Всего: 111



Inherited говорит, что сначала вступает в работу переопределённый метод родителя.


--------------------
user posted image *щёлк*
PM MAIL WWW ICQ   Вверх
p0s0l
Дата 20.6.2005, 01:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 58
Всего: 112



В случае с обработчиками сообщений (message-методы), если в предках не находится обаботчика нужного сообщения (в данном случае WM_PAINT нет у предков TControl..TObject), то вызывается виртуальный метод DefaultHandler...
А идейное отличие TControl от TWinControl заключается в том, что TWinControl имеет своё окно, свой DC, может содержать дочерние контролы. Тогда как TGraphicControl рисует не на своём окне (которого у него нет вообще), а на окне родителя (Parent).




--------------------
С уважением, г-н Посол.
PM   Вверх
Limonadni Joe
Дата 20.6.2005, 14:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 311
Регистрация: 1.11.2002
Где: Москва

Репутация: нет
Всего: 2



Цитата
В случае с обработчиками сообщений (message-методы), если в предках не находится обаботчика нужного сообщения (в данном случае WM_PAINT нет у предков TControl..TObject), то вызывается виртуальный метод DefaultHandler...

Спасибо, не знал. Но вот что получается. Это код метода DefaultHandler для TControl:
Код

procedure TControl.DefaultHandler(var Message);
var
  P: PChar;
begin
  with TMessage(Message) do
    case Msg of
      WM_GETTEXT:
        begin
          if FText <> nil then P := FText else P := '';
          Result := StrLen(StrLCopy(PChar(LParam), P, WParam - 1));
        end;
      WM_GETTEXTLENGTH:
        if FText = nil then Result := 0 else Result := StrLen(FText);
      WM_SETTEXT:
        begin
          P := StrNew(PChar(LParam));
          StrDispose(FText);
          FText := P;
          SendDockNotification(Msg, WParam, LParam);
        end;
    end;
end;

и в нём, как видим, нет упоминания о WM_PAINT. Где же этот WM_PAINT тогда обрабатывается?
PM MAIL ICQ YIM MSN   Вверх
p0s0l
Дата 20.6.2005, 18:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 58
Всего: 112



DefaultHandler - метод виртуальный smile
Ищи не в TControl, а например, в TWinControl или TGraphicControl, смотря какой у тебя созданный объект
Но не стоит надеятся найти что-то интересное, т.к. оба этих класса лишь основа для создания более сложных классов.
TGraphicControl в обработчике WM_PAINT вызывает виртуальный метод Paint, который у самого TGraphicControl абсолютно ничего не делает, а в наследниках, например, в TImage выводит картинку.
TWinControl в обработчике WM_PAINT вызывает стандартную оконную процедуру, которая обрабатывает это сообщение (заливая фоном)...



--------------------
С уважением, г-н Посол.
PM   Вверх
Rennigth
Дата 20.6.2005, 19:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 21.6.2004
Где: Moscow

Репутация: 49
Всего: 76



Цитата

Помогите разобраться откуда берётся серый фон у TWinControl

а он не помоему не серый, он по умолчанию ничего не рисует на себе, прозрачный он.


--------------------
(* Honesta mors turpi vita potior *)
PM MAIL ICQ   Вверх
Limonadni Joe
Дата 21.6.2005, 09:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 311
Регистрация: 1.11.2002
Где: Москва

Репутация: нет
Всего: 2



p0s0l, посмотрел DefaultHandler у TWinControl, проследил цепочку кода, но так и не нашёл места где ловится WM_PAINT smile. Вообще, поиск в юните Controls по строке "WM_PAINT:" ничего не даёт. Что же это такое получается?

Rennigth, ан-нет, я специально проверил: создал чистый компонент на основе TWinControl, кинул на форму и положил под него TextBox, и на TextBox'е покорно отобразилась часть серого фона от моего контрола. Хотя поначалу я тоже думал, что он прозрачный, пока не сделал ему Bring to Front smile .
PM MAIL ICQ YIM MSN   Вверх
p0s0l
Дата 21.6.2005, 15:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 58
Всего: 112



Зайди в Project-Options->Complier, поставь Use Debug DCUs
Теперь, сделай так:
Код
wc : TWinControl;
...
wc.Perform(WM_PAINT, 0, 0);
Жми F7 на Perform и смотри что куда идёт...




--------------------
С уважением, г-н Посол.
PM   Вверх
Limonadni Joe
Дата 21.6.2005, 17:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 311
Регистрация: 1.11.2002
Где: Москва

Репутация: нет
Всего: 2



Дошёл до вызова функции CallWindowProc:
Код
Result := CallWindowProc(FDefWndProc, FHandle, Msg, WParam, LParam);
а дальше - ни-ни, это - WinAPI. Подозрение именно на эту строчку, т.к. всё, что я встречал на пути следования отладчика - это отказы "согласиться" хоть на один if или else, и больше ничего.

Что же получается - серый фон рисует винда? Хотя, это вполне вероятно. Ведь у некоторых контролов (табов, например) градиентный фон, не будет же Delphi заниматься его прорисовкой. Мои догадки верны?
PM MAIL ICQ YIM MSN   Вверх
Girder
Дата 21.6.2005, 17:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй 2
***


Профиль
Группа: Участник Клуба
Сообщений: 1993
Регистрация: 12.5.2004

Репутация: 31
Всего: 155



Код
procedure TWinControl.WMPaint(var Message: TWMPaint);
var
  DC, MemDC: HDC;
  MemBitmap, OldBitmap: HBITMAP;
  PS: TPaintStruct;
begin
  if not FDoubleBuffered or (Message.DC <> 0) then
  begin
    if not (csCustomPaint in ControlState) and (ControlCount = 0) then
      inherited
    else
      PaintHandler(Message);
  end
  else
  begin
    DC := GetDC(0);
    MemBitmap := CreateCompatibleBitmap(DC, ClientRect.Right, ClientRect.Bottom);
    ReleaseDC(0, DC);
    MemDC := CreateCompatibleDC(0);
    OldBitmap := SelectObject(MemDC, MemBitmap);
    try
      DC := BeginPaint(Handle, PS);
      Perform(WM_ERASEBKGND, MemDC, MemDC);
      Message.DC := MemDC;
      WMPaint(Message);
      Message.DC := 0;
      BitBlt(DC, 0, 0, ClientRect.Right, ClientRect.Bottom, MemDC, 0, 0, SRCCOPY);
      EndPaint(Handle, PS);
    finally
      SelectObject(MemDC, OldBitmap);
      DeleteDC(MemDC);
      DeleteObject(MemBitmap);
    end;
  end;
end;



--------------------
Как слышим, так и пишим.
Истина где-то там...
PM   Вверх
Limonadni Joe
Дата 21.6.2005, 17:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 311
Регистрация: 1.11.2002
Где: Москва

Репутация: нет
Всего: 2



Girder, это ты к чему написал? Я вроде и сам видел этот код.
PM MAIL ICQ YIM MSN   Вверх
Rrader
Дата 21.6.2005, 18:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Inspired =)
***


Профиль
Группа: Экс. модератор
Сообщений: 1535
Регистрация: 7.5.2005

Репутация: 70
Всего: 191



Цитата

Что же получается - серый фон рисует винда? Хотя, это вполне вероятно. Ведь у некоторых контролов (табов, например) градиентный фон, не будет же Delphi заниматься его прорисовкой. Мои догадки верны?

Что касается табов, то они полностью отрисовываются Windows, в Delphi даже событий перерисовки у них нет. Думаю, что твои догадки насчёт TWinControl'а верны. smile


--------------------
Let's do this quickly!
Rest in peace, Vit!
PM MAIL Skype   Вверх
p0s0l
Дата 21.6.2005, 20:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 58
Всего: 112



Цитата(Limonadni @ 21.6.2005, 17:10)
Что же получается - серый фон рисует винда? Хотя, это вполне вероятно. Ведь у некоторых контролов (табов, например) градиентный фон, не будет же Delphi заниматься его прорисовкой. Мои догадки верны?
Надо было читать внимательнее:
Цитата(p0s0l @ 20.6.2005, 18:48)
TWinControl в обработчике WM_PAINT вызывает стандартную оконную процедуру, которая обрабатывает это сообщение (заливая фоном)...

smile


--------------------
С уважением, г-н Посол.
PM   Вверх
Limonadni Joe
Дата 21.6.2005, 20:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 311
Регистрация: 1.11.2002
Где: Москва

Репутация: нет
Всего: 2



p0s0l, да, спасибо. Просто я тогда не имел богатого представления о том, что такое стандартная оконная процедура и что (как я понял?) принадлежит она целиком и полностью винде.
PM MAIL ICQ YIM MSN   Вверх
Girder
Дата 22.6.2005, 00:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй 2
***


Профиль
Группа: Участник Клуба
Сообщений: 1993
Регистрация: 12.5.2004

Репутация: 31
Всего: 155



Цитата(Limonadni @ 21.6.2005, 18:38)
Girder, это ты к чему написал? Я вроде и сам видел этот код.
Ты же спрашивал где обрабатывается WM_Paint smile

По сабжу: Глянул исходники Controls... т.в. там регистрируется класс окна с _WNDCLASSEX.hbrBackground равным 0... а енто значит:
Цитата
When this member is NULL, an application must paint its own background whenever it is requested to paint in its client area. To determine whether the background must be painted, an application can either process the WM_ERASEBKGND message or test the fErase member of the PAINTSTRUCT structure filled by the BeginPaint function.


Т.е. вот оно (FillRect):
Код
procedure TWinControl.WMEraseBkgnd(var Message: TWMEraseBkgnd);
begin
  with ThemeServices do
  if ThemesEnabled and Assigned(Parent) and (csParentBackground in FControlStyle) then
    begin
      { Get the parent to draw its background into the control's background. }
      DrawParentBackground(Handle, Message.DC, nil, False);
    end
    else
    begin
      { Only erase background if we're not doublebuffering or painting to memory. }
      if not FDoubleBuffered or
         (TMessage(Message).wParam = TMessage(Message).lParam) then
        FillRect(Message.DC, ClientRect, FBrush.Handle);
    end;

  Message.Result := 1;
end;



--------------------
Как слышим, так и пишим.
Истина где-то там...
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0591 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.