Вопрос пользователя касается создания пользоваского окна в Delphi, используя собственный класс TMainWindow, без применения VCL. Приведенный код частично работает, но программа крашится после создания окна или при использовании функции Dispatch в методе HandleMessage. Проблема заключается в неправильной передаче указателя на объект в функцию CreateWindow.
Объяснение проблемы
В методе Create класса TMainWindow используется выражение @Self, которое является указателем на локальную переменную, а не на сам объект. Это приводит к ошибке доступа, так как указатель на локальную переменную не валиден после выхода из метода Create.
Подтвержденный ответ
Чтобы исправить проблему, необходимо убрать оператор @ при передаче указателя на объект в функцию CreateWindow. Вместо @Self следует использовать Self напрямую.
constructor TMainWindow.Create;
begin
// ...
if CreateWindow(
'Scratch', // Class Name
'Scratch', // Title
WS_OVERLAPPEDWINDOW, // Style
Integer(CW_USEDEFAULT),
Integer(CW_USEDEFAULT), // Position
Integer(CW_USEDEFAULT),
Integer(CW_USEDEFAULT), // Size
0, // Parent
0, // No menu
HInstance, // Instance
Self // No special parameters
) = 0 then begin
raise Exception.Create('CreateWindow failed: ' + SysErrorMessage(GetLastError));
end;
end;
Альтернативные способы решения
Использование TDictionary
Для более безопасного хранения ассоциаций между окнами и объектами можно использовать TDictionary, что избавит от необходимости работы со строками.
Использование SetWindowLongPtr и GetWindowLongPtr
Можно напрямую связать объект с окном, используя SetWindowLongPtr для установки указателя на объект в дополнительные байты окна и GetWindowLongPtr для его получения.
Использование свойств окна
Свойства окна (window properties) позволяют хранить данные, связанные с окном, используя функции SetProp и RemoveProp.
Создание нового процедуры окна
Подход, используемый VCL, заключается в создании нового процедуры окна для каждого объекта, что позволяет сохранить ссылку на объект в памяти, выделенной для процедуры.
Заключение
Исправление кода, убравание @ из выражения @Self, должно устранить проблему с утечкой указателей. Однако, стоит рассмотреть альтернативные подходы для улучшения безопасности и производительности приложения.
Создание пользоваского окна в Delphi с использованием собственного класса `TMainWindow` без VCL приводит к ошибке при передаче указателя на объект в функцию `CreateWindow` из-за неправильного использования указателя на локальную переменную.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.