Автор вопроса: mc-black | Web-сайт:mc-black.narod.ru/dzp.htm | ICQ: 308-534-060
Изменяется ли hWnd окна после его создания?
В циклах создаю много контролов через CreateWindowEx, возвращаемый ими результат (hWnd) сохраняю в массив. Потом когда мне надо убрать их с главного окна я прохожусь по массиву и удаляю через DestroyWindow. Но удаляется около половины контролов.. Местами возвращается ошибка Invalide Handle - они-то и остаются целыми. Такое чувство, что hWnd некоторых окон может поменяться при UpdateWindow или ещё где-то.. Как мне заполнить массив актуальными hWnd?
P.S. Код мне не нужен, делаю в MASM32, нужны практические советы..
Либо с адресацией что-то не так.
Выкладывай в debug.print хэндлы при создании и при удалении окон. И проверь наличие удаляемых хэндлов в списке созданных. Если удаляемых хэндлов нет в списке созданных - значит код запортил массив.
Возможно, твой код получает доступ к массиву в результате ошибки и модифицирует его содержимое.
этого я больше всего и боялся, возможно, что да..
3.
Мой массив в стеке, он создается перемещением esp вне процедур, т.е. "в глобальном контексте".. или если я не позаботился сохранять регистры общего назначения перед вызовами api, а они их модифицируют в циклах при создании контролов.
И проверь наличие удаляемых хэндлов в списке созданных
IsWindow - проверял, нет таких
Самое смешное, при удалении не удаляются контролы строго по какому-то закону, почти по диагонали.. немного врассыпную. Каждый раз одинаково.
В стеке такие вещи не держат. При выходе из процедуры в которой инициализировался массив, сохранность содержимого стека не гарантируется. Т.е. винда область стека, в которой размещен массив, может передать под стек в любую процедуру, и твой массив будет затерт параметрами этой процедуры или её локальными переменными.
Выдели память virtualalloc и там держи свой массив.
, спасибо, может подробнее подскажешь, как мне потом этот кусок можно будет использовать? Как обращаться к чему-то внутри него, как изменить размер (увеличить, уменьшить), если это возможно?
А про всё, что ты сказал, я хорошо знаю и понимаю. Просто по-другому пока не додумался. Массив у меня не затрётся (мой частный случай), т.к. он вне всех процедур объявляется. Ошибку я свою нашёл и исправил, сейчас всё хорошо. Стыдно сказать, массив неправильно заполнял, поэтому по нескольку hWnd в одно место лепил.. Сейчас всё работает. По основной теме - спасибо за внимание!
Чтобы растянуть массив - нужно пересчитать его размер под новое количество элементов, выделить новый кусок памяти, скопировать в него старый массив, и затем старый удалить.
Можно ещё написать две небольшие служебные ф-ции типа RedimArray, в которой растягивать/уменьшать размер массива, и InitArray, в которую вынести VirtualAlloc и VirtualFree.
В довершение всего оформить эти 4 ф-ции в отдельный .inc - и у тебя полноценный массив с ф-циями инициализации, удаления, изменения размерности, чтения и записи в массив.
Все
Не в том дело, что не люблю по имени, просто функции коротенькие - в одной 5 инструкций - в другой -4, и на этом фоне если не предотвратить формирование стекового фрейма, то сразу добавятся бесполезные
push ebp
mov ebp,esp
leave
На фоне 4 инструкций - это очень много, особенно в плане скорости.
Так что тут все продумано
А синтаксис proc <parameters> использован чисто для визуального восприятия параметров.
HeapAlloc пару раз проглючил, уже не помню, что было - и я от него отказался. Опять же VirtualAlloc меньше кода
Лично у мня к хипам никаких нареканий нет... К локалам есть Однажды случился глюк, использовал strlen из masmlib, так там для ускорения процесса в регистр махом забиралось двойное слово, а потом уже искался нулевой байт... Так случилось что выделилялось памяти не кратное 4-м число, и конец этой памяти аккурат приходился на конец страницы В итоге при попытке забрать лишние 1-3 байта, вылетало нарушение доступа... Обидная обшибка была...
о StrLen: более грамотная реализация этого метода (подвордное чтение) сделана в си-шной strlen.
Там читается с адресов, кратных 4. Т.е. первые 0-3 байта читаются побайтно, а начиная с первого кратного 4 адреса - подвордно. И на граблю не наступишь, и скорость повышается за счет кратности читаемого адреса четырем.
Во какая интересная дискуссия получилась! Всё (почти) понятно, интересно, полезно.. sne, а твой примерчик можно с HeapAlloc? И чем всё-таки он хуже/лучше?
Дело вкуса, но я предпочитаю работать с Heap'ами, а не Virtal'aми...
Повторюсь, дело вкуса и привычки
Можно кста несколько хипов создать, не знаю где это может понадобиться, мне и одного процессового хватало Но тем-ни менее )
А что там с хипами пример-то, просто выделение памяти другой функцией, а так, весь выше приведенный код справедлив для любого способа и от способа выделения памяти ни коим место м не зависит ) лишь бы она была...
ЗЫ
Виртуалы выделяют память страницами, хеап-ы - сколько укажешь... с одной стороны как видит пользователь, хотя на самом деле резервируется страница