Доброго времени! Изучаю masm32 по :"Уроки Iczelion'а" . В главе 12 - http://www.wasm.ru/article.php?article=1001012 - следуя совету leo : http://www.wasm.ru/comment.php?artcode=1001012 , который в комментариях написал, что пользоваться GlobalAlloc с флагом GMEM_MOVEABLE, как не правильно, так и расточительно с точки зрения выдиления памяти, я столкнулся с проблемой использования функции HeapAlloc. В примере заменил строки : invoke GlobalAlloc,GMEM_MOVEABLE or GMEM_ZEROINIT,MEMSIZE mov hMemory,eax invoke GlobalLock,hMemory mov pMemory,eax invoke ReadFile,hFile,pMemory,MEMSIZE-1,ADDR SizeReadWrite,NULL invoke SendMessage,hwndEdit,WM_SETTEXT,NULL,pMemory invoke CloseHandle,hFile invoke GlobalUnlock,pMemory invoke GlobalFree,hMemory ---------------------- на чтение ---------------------------------------------------------------- invoke GetProcessHeap mov hHeap,eax invoke HeapAlloc, hHeap,HEAP_ZERO_MEMORY,MEMSIZE mov pMemory,eax invoke ReadFile,hFile,pMemory,MEMSIZE-1,ADDR SizeReadWrite,NULL invoke SendMessage,hwndEdit,WM_SETTEXT,NULL,pMemory invoke HeapFree, hHeap, NULL, pMemory invoke CloseHandle,hFile ------------------ на сохранение ------------------------------------------- invoke HeapAlloc, hHeap,HEAP_ZERO_MEMORY,MEMSIZE mov pMemory,eax invoke SendMessage, hWndEdit, WM_GETTEXT, MEMSIZE-1, pMemory invoke WriteFile, hFile, pMemory, eax, addr RealSize, NULL invoke HeapFree, hHeap, NULL, pMemory invoke CloseHandle, hFile Теперь меню Save не работает, когда печатаешь в диалоговом окне и пытаешься сохранить в файл, т.е. при попытке сохранить текст программа вылетает в отладку. Работает, когда прочитаешь из файла в диалоговое окно, а после сохраняешь в файл. Кто знает , просветите в применении функции HeapAlloc Заранее спасибо! зы на всякий случай прилепил файлы с неправильно действующей HeapAlloc
Ес-но, т.к. hHeap не инициализирована. Или добавь вызов GetProcessHeap перед сохранением или лучше вынеси GetProcessHeap в общую часть кода до вызова WinMain
PS: Неправильно юзать GlobalAlloc c флагом GMEM_MOVEABLE там где это не нужно, а с флагом GMEM_FIXED или GPTR вполне можно, т.к. при этом никакой доп.памяти не расходуется, возвращается сразу указатель на блок памяти и соотв-но никакие Lock\Unlock тоже не нужны, единственный минус - GlobalAlloc работает несколько дольше чем HeapAlloc, но в данной задаче скорости и не нужны
leo - Спасибо, всё просто, исправил! А зачем тогда вообще использовать GlobalAlloc если она работает через HeapAlloc и, соответственно, медленнее ? Или существуют какие то специфические задачи, в которых GlobalAlloc нужнее HeapAlloc?
Plis GlobalAlloc оствлена для совместимости с win16, в частности буфер обмена требует как раз того самого нежелательного GMEM_MOVEABLE, чтобы можно было копипастить в/из старые (например для win3.1) программы. В современных программах однозначно правильно HeapAlloc, за исключением тех случаев (Clipboard, DDE) которые требуют обязательной совместимости с программами которых уже давно нет.
Y_Mur К сожалению дело не в самой совместимости, а еще и в корявости ее реализации, особенно для работы с клипбордом. Мало того, что само использование GMEM_MOVEABLE требует доп.резерва адресов и затрат физ памяти, но еще и при работе с клипбордом "скопированный" или "вставленный" кусок памяти не удаляется виндой из нашей кучи сразу после использования, а может сидеть в ней сколько угодно долго до следующего вызова OpenClipboard или ExitProcess А кого-то еще по наивности затраты памяти в проге волнуют, возможные утечки памяти беспокоят - мелкософтам же все эти мелочи пофиг, пока рак на горе не свистнет или гром не грянет, винда и не почешется удалять блок из нашей "приватной" "мусорной" кучи Кто скажет, что такое дурное поведение обусловлено совместимостью с Win16 ? Почему для Win32 нельзя было создать доп.функции для работы с кучей (типа Set\GetClipboardDataEx), которые бы только передавали\забирали данные в\из буфера пользователя, а не требовали бы обязательного выделения блока в куче с запретом его удаления самим юзером ?
leo Полностью согласен что клипборд реализован очень криво и нелепо - имхо гораздо лучше было в win32 сделать принипиально новый механизм работы, действующий параллельно со старым и откорректировать старые win 16 функции так чтобы они имели "окольный" доступ к данным из этого нового механизма. Пусть бы лучше старые функции стали от этого ещё кривее и тромознее - всё равно они только доживают свой век, чем портить новые программы такой "совместимостью". Но увы сделали совместимость "как сделали", остаётся только использовать как есть - сам же не перепишешь всё это безобразие из-за той же необходимости поддерживать совместимость с тем что есть теперь.