інця рядка. Якщо номер символу негативний, значить, такого рядка немає. Але можливо робиться спроба вставити після останнього рядка, так що запитаємо номер символу для попереднього рядка. Якщо і тепер номер негативний або довжина цього рядка нульова, припиняємо подальше виконання. При сприятливому результаті збільшуємо Selection.cpMin на довжину останнього рядка, таким чином, тепер вона вказує на останній символ в тексті (сюди і будемо вставляти). Наявність не нульовий довжини у останнього рядка говорить про те, що рядок не завершена. Щоб завершити її необхідно передати в текст спочатку, ознака кінця рядка, а потім саму додає рядок, з цього ознака кінця рядка включається в її початок. Далі встановлюємо кінець виділення на початок виділення (змінна Selection.cpMax) і переміщаємо туди курсор посилкою повідомлення EM_EXSETSEL. Форматуємо рядок і відправляємо повідомлення EM_REPLACESEL для розміщення вставляемой рядка. Після вдалої вставки нове положення курсору повинно рівнятися положенню перед вставкою плюс довжина вставляється рядки (Selection.cpMax + Length (Str)). Якщо ні, то викликається виняткова ситуація (raiseEOutOfResources.Create (sRichEditInsertError)). p align="justify"> Помилка виникає тому, що повідомлення EM_LINELENGTH використовує лише молодші 16 розрядів параметра. Цей параметр повинен містити номер будь-якого символу з рядка довжину, якої треба визначити. Якщо передається номер більше 65 535, ну, наприклад 65 536, то повідомлення повертає довжину рядка, що містить символ з номером 0. Таким чином, у методі Add при запиті функції GetCount може бути отримано значення на одиницю більше, якщо попадеться рядок не нульової довжини. І тоді процедурі Insert буде передано значення на одиницю більше, ніж номер останнього рядка. Це перша помилка. p align="justify"> Властивість Count, яка звертається до функції GetCount, може давати на один рядок більше при перевищенні розміру тексту в 65 535 байт. Помилка виникає тільки якщо рядок, що містить усічений номер символу, не порожня, тобто помилка буде мати плаваючий характер. p align="justify"> Повертаючись до методу Add, зауважу, що ця помилка не впливає на процедуру Insert. Тому що процедура Insert пробує не тільки зазначену рядок, а й, у разі не успіху, попередню, а це і буде якраз останнім рядком у тексті. Але тут-то і криється справжня помилка. Потрапивши в цю гілку if (тобто після else) процедура Insert запитує довжину рядка за допомогою повідомлення EM_LINELENGTH і знову отримує помилкове значення. Обставини наростають як сніжний ком, невідворотно. Тепер невірна довжина рядка використовується для визначення номера останнього символу в тексті. А адже довжина цієї останнього рядка можливо нульова і це значить, що ми вже маємо номер останнього символу в тексті після попереднього повідомлення EM_LINEINDEX. Після додавання до нього чужий довжини, ми отримуємо номер символу завідомо виходить за межі тексту. Через це і відбудеться виклик виняткової ситуації, але пізніше. По...