![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как поймать 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