Вопрос пользователя связан с использованием компонента TWebBrowser из пакета RadPHP 3 для редактирования HTML. При загрузке некоторых HTML-файлов, включая, например, страницу StackOverflow, программа вызывает ошибку доступа к памяти (access violation). Это происходит при попытке установить атрибут contentEditable для элемента body в документе, который загружается в TWebBrowser. Ошибка возникает на строке, где выполняется операция Doc.Body.SetAttribute('contentEditable', 'true', 0).
Пример кода, вызывающего ошибку:
procedure THTMLEdit.EditText(const text: string);
var
Doc: IHTMLDocument2;
sl: TStringList;
f: string;
begin
sl := TStringList.Create;
try
sl.Text := text;
f := GetTempFile('.html');
sl.SaveToFile(f);
wbBrowser.Navigate(f);
Doc := GetDocument;
if Doc <> nil then
Doc.Body.SetAttribute('contentEditable', 'true', 0); // Crash HERE
DeleteFile(f);
finally
FreeAndNil(sl);
end;
end;
Описание проблемы:
Метод THTMLEdit.EditText предназначен для загрузки HTML-кода в TWebBrowser. Однако, при попытке установить атрибут contentEditable для элемента body документа, программа терпит сбой. Это происходит из-за того, что операция wbBrowser.Navigate(f) является асинхронной, и в момент вызова Doc.Body.SetAttribute объект Doc или его элемент Body могут быть не полностью инициализированы.
Подтвержденный ответ:
Чтобы избежать ошибки, необходимо дождаться полной загрузки страницы в TWebBrowser. Это можно сделать, используя событие OnDocumentComplete, которое срабатывает, когда документ полностью загружен. В этом событии уже можно безопасно обращаться к DOM.
Пример корректного использования TWebBrowser.OnDocumentComplete:
procedure TForm1.WebBrowser1DocumentComplete(Sender: TObject; const pDisp: IDispatch; var url: OleVariant);
var
Doc: IHTMLDocument2;
begin
Doc := pDisp as IHTMLDocument2;
if Assigned(Doc) then
Doc.Body.SetAttribute('contentEditable', 'true', 0);
end;
При нажатии на кнопку, которая вызывает редактирование HTML, необходимо подключить обработчик события OnDocumentComplete для TWebBrowser и установить необходимые атрибуты уже после полной загрузки документа.
Альтернативный ответ:
Также, для переключения в режим редактирования можно использовать метод Doc.DesignMode := 'On', но это следует делать после полной загрузки документа.
Заключение:
Использование TWebBrowser для редактирования HTML в RadPHP 3 может быть нестабильным, особенно при работе с атрибутами DOM. Важно помнить о необходимости ожидания полной загрузки страницы перед выполнением операций с DOM. Использование событий OnDocumentComplete является предпочтительным способом для работы с TWebBrowser в таких случаях.
Обратите внимание, что в коде, предоставленном пользователем, использование временного файла для загрузки HTML может быть неоптимальным. В будущих версиях кода стоит рассмотреть возможность исключения этого шага, если это возможно.
Примечание: В данном ответе не приводится полный код программы, так как он не требуется для понимания сути проблемы и решения. Пользователю рекомендуется интегрировать предоставленные советы в свой проект и адаптировать их под свои нужды.
Вопрос связан с устранением ошибки доступа к памяти при редактировании HTML в компоненте `TWebBrowser` из RadPHP 3, вызванной попыткой изменить атрибут `contentEditable` для элемента `body` в асинхронной загрузке страницы.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.