Здравствуйте. Имею проблему,которая мне не понятна. Код: proc DialProc,hDial,uMsg,wParam,lParam local ps PAINTSTRUCT local hDCWORD local aWORD local bWORD local hEditPWORD local hEditDWORD push edi esi ebx mov eax,[uMsg] cmp eax,WM_COMMAND je Command cmp eax,WM_INITDIALOG je Init cmp eax,WM_PAINT je paint cmp eax,WM_CLOSE je jCLOSE xor eax,eax jmp finish Init: invoke GetDlgItem,[hDial],105 mov [hEditP],eax invoke SetFocus,[hEditP] invoke GetDlgItem,[hDial],104 mov [hEditD],eax jmp finish paint: invoke BeginPaint,[hDial],addr ps mov [hDC],eax invoke EndPaint,[hDial],addr ps jmp finish Command: mov eax,[wParam] cmp ax,123 je Create jmp finish Create: invoke GetDlgCtrlID,[hEditP] mov [a],eax invoke GetDlgCtrlID,[hEditD] mov ,eax invoke GetDlgItemText,[hDial],[a],Buf,5 invoke SetDlgItemText,[hDial],,Buf invoke SetWindowText,[hDial],Buf jmp finish jCLOSE: invoke EndDialog,[hDial],0 mov eax,1 finish: pop ebx esi edi ret endp Эта процедура (а точнее ее часть "Create") начинает правильно работать только после того переменные hEditP и hEditD сделать не локальными, а определить в секции DATA( hEditP dd ? hEditD dd ? ). Скажите пожалуста ,почему локализация этих переменных ошибочна?
локальные переменные - в стеке и стираются после выхода из процедуры, а ведь то что в ней создаёшь должно обновляться виндой , а цикл обновления - разве он использует эту процедуру? вроде не должен вроде так помню у меня в какой-то програме invoke BeginPaint не работала с локальной переменной, компилятор ошибки не выдавал, всё окей, вот только окно - йок
Тоесть вы хотите сказать что мои переменные вычисляются только один раз при получении WM_INITDIALOG, а макрос local резервирует место в стеке каждий раз при обращении к DialProc и каждый раз разные адреса. Понял.Спасибо за подсказку.
Sashok Даже если адреса и одинаковые, то любая запись в стек после выхода из DialProc будет затирать её локальные переменные. Правило здесь одно: стековые (bzw. локальные) переменные живут не дольше, чем длится одноразовая отработка использующей их процедуры. Новый вызов процедуры — новые локальные переменные. В этом смысл реентерабельного кода.
"В этом смысл реентерабельного кода." - это вы сильно сказали. Но всеравно спасибо .Хоть информация и проста (для кого то),для меня это важно. Незная такой простой информации делаеш глупые ошибкиб из за которых тратиш уйму времени.
Локальные переменные могут быть глобальными, если расположены выше максимального уровня стека, на который поднимается процедура(в сторону дна). Стек ниже текущего Esp свободен и будет освобождён при возврате. Простые локальные переменные находятся в нём.
И ещё обращение к локальным переменным осуществляется через ebp. Это надо учитывать если вы изменяете этот регистр.