Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как поймать RecreateWnd у формы? [D6, WinXP]


ancara ©   (2006-03-01 12:00:00) 

Доброго, всем, времени суток!
 Проблема в следующем: на форме лежит мой компонент, порожденный от TWinControl, я использую его DC для создания и эксплуатации :) контекста OpenGL. Если я в процессе работы изменяю у формы св-во BorderStyle, например, то это приводит к вызову RecreateWnd у этой же формы, вследствии чего, форма получает новый handle и, соответственно, новый DC.
После таких событий мой компонент перестает функционировать :(

Вопрос в следующем: как мне этот момент (смены хендлов) поймать и должным образом отреагировать, т.е. переинициализировать контекст OpenGL?

Есть, конечно, запасной вариант - это перед каждой OpenGL-активностью проверять, не обновились ли хендл и DC, но мне кажется это не правильно...

P.S. Перекрыл у свего компонента
   procedure CMRecreateWnd(var Message: TMessage); message CM_RECREATEWND;
эта процедура у него не вызывается, хотя, по моим ожиданиям, должна была...


jack128   (2006-03-03 17:51:00) [1]

ancara ©   (03.03.06 11:44) [8]
Вобщем, жалко мне код засорять.

тогда наследуйся от TCustomControl у которого есть Canvas и не парь любям мозги.
ancara ©   (03.03.06 11:44) [8]
Да и какой смысл постоянно дергать
GetDC, если он большую часть времени остается неизменным

Вся VCL так работает и ничего.. Вроде не тормозит.


ancara   (2006-03-03 11:44:00) [2]


> я бы сказал, что ты где внутри компонента запоминает DC,
>  а это очень порочная и глючная практика. Расскажи про свою
> задачу


В смысле, запоминаю ли я DC своего компонента? Да. DC формы - нет, оно мне не требуется в процессе работы...
 Но до того, как я столкнулся с этим RecreateWnd с моим "запомненным" DC проблем не было, все работало отлично. Да и какой смысл постоянно дергать
GetDC, если он большую часть времени остается неизменным? Да и от Recreate это не спасет, т.к. у моего компонента он не меняется...

Теперь придется запоминать DC формы и постоянно проверять, не обновился ли он... Лишнее поле, лишняя функция... А может пользователь вообще никогда не будет borderstyle этот изменять? Вобщем, жалко мне код засорять.

И еще такой момент, кот. я не понимаю:
 Новый хендл и DC получает форма, а хэндл и DC моего компонента остаются прежними, и почему контекст OpenGL отказывается на нем работать для меня пока загадка...

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


jack128   (2006-03-03 11:12:00) [3]

GuAV ©   (02.03.06 19:19) [6]
почему бы не перекрыть их ?

видимо потому что DestroyWnd вызывется не только при пересоздании, но и при простом удалении окна ;-)

2ancara ©
Вот по этой фразе
ancara ©   (01.03.06 12:00)
вследствии чего, форма получает новый handle и, соответственно, новый DC.
После таких событий мой компонент перестает функционировать :(

я бы сказал, что ты где внутри компонента запоминает DC, а это очень порочная и глючная практика. Расскажи про свою задачу, может чего умного посоветуем ;-)


GuAV   (2006-03-02 19:19:00) [4]


> TWinControl

CM_RECREATEWND вызывает DestroyHandle, он вызывает DestroyHandle всех Child и DestroyWindowHandle и DestroyWnd - эти виртуальные, почему бы не перекрыть их ?


ancara   (2006-03-02 11:38:00) [5]

М-м-да, я теперь даже и не знаю что будет проще, какой вариант получится меньше "багонасыщенным" :)) Буду думать и выбирать меньшее из зол.

to jack128, Юрий Зотов
Всем спасибо за участие!


Юрий Зотов   (2006-03-01 23:02:00) [6]

> ancara ©   (01.03.06 15:21) [3]

Да. Но если на форму будет положено несколько таких компонентов, а потом какие-то из них будут удалены, то начнется бардак. Поэтому нужно предусмотреть меры, его исключающие (например, связанный список WndProc, хотя и это не панацея).


ancara   (2006-03-01 15:21:00) [7]

а, кажись, понял, тыимеешь ввиду, перекрыть WndProc у формы?
И у нее ловить CM_RECREATEWND, так?
Т.е. придется запомнить адрес ее "родной" WndProc, затем назначить ей свою WndProc, в кот. я буду ловить сообщение и затем вызывать "родной" WndProc, так я понимаю?


ancara   (2006-03-01 15:09:00) [8]

jack128
Не понял, поподробней, плиз, с этого места.
Перекрыть-то я перекрою, а по какому сообщению определять этот момент?


jack128   (2006-03-01 14:39:00) [9]

ancara ©   (01.03.06 12:00)
Перекрыл у свего компонента
  procedure CMRecreateWnd(var Message: TMessage); message CM_RECREATEWND;
эта процедура у него не вызывается, хотя, по моим ожиданиям, должна была...


а с чего это вдруг у ТВОЕГО компонента эта процедура должна вызываеться?? Сообщение CM_RECREATEWND передается тому WinControl'у, ХЕНДЛ, которого пересоздается.  Тебе нужно перекрыть оконную процедуру самого WinControl'a.  См метод TWinContorl.WndProc, совйство TWinControl.WindowProc


Наверх

Титульная страница Поиск, карта сайта Написать письмо