Засада с этими HDC контекстами, помогите plz..
От: Dylan  
Дата: 11.04.03 15:56
Оценка:
Уважаемые коллеги, подскажите кто знает!

Дело вобщем такое. Пишу компонент — наследник от TGraphicControl. Надо сохранить часть канвы, занимаемой этим компонентом на Parent окне. Делаю так:
DC:=GetDC(Parent.Handle) — не работает, создает DC, связанный с окном, лежащим под Paren окном!

Делал DC:=GetDC(0) — та же фигня!

Как быть???

И еще, как заставить перерисоваться Parent окно в локальном TRect'e?

С респектами, Дмитрий.
Re: Засада с этими HDC контекстами, помогите plz..
От: tim_ Россия  
Дата: 12.04.03 00:36
Оценка:
Здравствуйте, Dylan, Вы писали:

D>Уважаемые коллеги,...


D>Делал DC:=GetDC(0) — та же фигня!


Ну, это где-то что-то у вас не правильно, т.к. GetDC(0) вегда возвращает контекст экрана.

Касательно вашего вопроса: а вы уверены, что этот самый Parent хранит в контексте себя любимого без всех компонентов, находящихся поверх него? Исследуйте повнимательней алгоритм реагирования TWinControl`а на событие WM_PAINT, а так же WM_ERASEBKGND. В первом случае вообще идет clipping всех регионов дочерних компонентов, т. е. те части TWinControla, которые не видны (находятся под дочерними компонентами) попросту не зарисовываются в обработчике самого Parenta. А вот второе сообщение иногда полезно вообще проигнорировать, т. к. из-за временного интервала между этими сообщениями всегда происходит мелькание изображения.

Хотелось бы узнать, чисто из любопытства, зачем вам необходимо работать с невидимым изображением? Уж не для (полу)прозрачности ли?

D>И еще, как заставить перерисоваться Parent окно в локальном TRect'e?


Parent.PaintTo(..);
Re[2]: Засада с этими HDC контекстами, помогите plz..
От: Dylan  
Дата: 12.04.03 08:02
Оценка:
Здравствуйте, tim_, Вы писали:

D>Делал DC:=GetDC(0) — та же фигня!


_>Ну, это где-то что-то у вас не правильно, т.к. GetDC(0) вегда возвращает контекст экрана.

Чесно говоря не уверен.... Впрочем, может я и заблуждаюсь, я раскопал такой код в исходнике TCustomLabel, там контекст вывода лэйбла получают именно так...

_>Касательно вашего вопроса: а вы уверены, что этот самый Parent хранит в контексте себя любимого без всех компонентов, находящихся поверх него? Исследуйте повнимательней алгоритм реагирования TWinControl`а на событие WM_PAINT, а так же WM_ERASEBKGND. В первом случае вообще идет clipping всех регионов дочерних компонентов, т. е. те части TWinControla, которые не видны (находятся под дочерними компонентами) попросту не зарисовываются в обработчике самого Parenta. А вот второе сообщение иногда полезно вообще проигнорировать, т. к. из-за временного интервала между этими сообщениями всегда происходит мелькание изображения.

Спасибо — очень полезно. Честно говоря, мне следовало бы покапаться самому в этом (я так и сделаю), но щас надо срочно написать компонент, поэтому и гружу, еще раз спасибо.

_>Хотелось бы узнать, чисто из любопытства, зачем вам необходимо работать с невидимым изображением? Уж не для (полу)прозрачности ли?

Да нет, просто надо немного преобразовать кусок фона, на который ложится компонент.
А что если для прозрачности?

D>И еще, как заставить перерисоваться Parent окно в локальном TRect'e?


_>Parent.PaintTo(..);


Вот большое спасибо... — будет время — буду копаться сам в этом, а сейчас Ваша помощь более, чем своевременная.
Re[2]: Засада с этими HDC контекстами, помогите plz..
От: Dylan  
Дата: 12.04.03 08:33
Оценка:
Здравствуйте, tim_, Вы писали:


D>И еще, как заставить перерисоваться Parent окно в локальном TRect'e?


_>Parent.PaintTo(..);


Не, не подходит... Там нужен контекст источника... А у меня его нет! Надо просто попросить Parent, чтобы он перерисовал сам себя в TRect... Как это сделать, вот в чем фишка...
Re[2]: Засада с этими HDC контекстами, помогите plz..
От: Dylan  
Дата: 12.04.03 10:09
Оценка:
Здравствуйте, tim_, Вы писали:

_>Касательно вашего вопроса: а вы уверены, что этот самый Parent хранит в контексте себя любимого без всех компонентов, находящихся поверх него? Исследуйте повнимательней алгоритм реагирования TWinControl`а на событие WM_PAINT, а так же WM_ERASEBKGND. В первом случае вообще идет clipping всех регионов дочерних компонентов, т. е. те части TWinControla, которые не видны (находятся под дочерними компонентами) попросту не зарисовываются в обработчике самого Parenta. А вот второе сообщение иногда полезно вообще проигнорировать, т. к. из-за временного интервала между этими сообщениями всегда происходит мелькание изображения.


Гм... А как это сделать? Т.е. запретить WM_ERASEBKGND?
Re[3]: Засада с этими HDC контекстами, помогите plz..
От: tim_ Россия  
Дата: 18.04.03 23:06
Оценка:
Здравствуйте, Dylan, Вы писали:

D>Здравствуйте, tim_, Вы писали:



D>И еще, как заставить перерисоваться Parent окно в локальном TRect'e?


_>Parent.PaintTo(..);


D>Не, не подходит... Там нужен контекст источника... А у меня его нет! Надо просто попросить Parent, чтобы он перерисовал сам себя в TRect... Как это сделать, вот в чем фишка...


Прошу прощения за запоздалый ответ, не знаю, нужно ли вам еще это, но тем не менее.

Из временного созданного контекста можно делать BitBlt на сам Parent.
Re[3]: Засада с этими HDC контекстами, помогите plz..
От: tim_ Россия  
Дата: 18.04.03 23:14
Оценка:
Здравствуйте, Dylan, Вы писали:

D>Гм... А как это сделать? Т.е. запретить WM_ERASEBKGND?


Зачем запрещать сообщение? Я имел в виду просто его проигнорировать, т.е. в обработчике этого сообщения не вызывать обработчик от TWinControlа, т.е. убрать от туда inherited. Просто вот так:


...

TMyComponent = class(TCustomControl)
private
  ...
  procedure WMEraseBkgnd(var Message: TWmEraseBkgnd); message WM_ERASEBKGND;
  ...
end;

...

implementation

...

procedure WMEraseBkgnd(var Message: TWmEraseBkgnd); message WM_ERASEBKGND;
begin
  // Без inherited
end;



При этом, очистку окна необходимо проводить в самом обработчике OnPaint непосредственно перед перерисовкой. Вот и все.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.