Валентин Озеров - Советы по Delphi. Версия 1.4.3 от 1.1.2001
- Название:Советы по Delphi. Версия 1.4.3 от 1.1.2001
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Валентин Озеров - Советы по Delphi. Версия 1.4.3 от 1.1.2001 краткое содержание
…начиная с 1001. Смотрите другие файлы…
Советы по Delphi. Версия 1.4.3 от 1.1.2001 - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
procedureAssignStr( varP: PString; constS: string);
Можно отметить, что явно задать использование long strings можно декларацией
var
sMyLongString: AnsiString; // long dinamically allocated string
sMyWideString: WideString; // wide string (UNICODE)
sMyShortString1: ShortString; // old-style string
sMyShortString2: String[255]; // old-style string, no more than 255 chars
Хотелось бы также предупредить наиболее частные ошибки при использовании длинных строк:
• Если Вы передаёте указатель PChar на буфер, взятый от длинной строки, в функцию, которая может изменить содержание буфера, то убедитесь, что на этот буфер указывает только одна строка. Это верно в случаях сложения строк, вызова UniqueString или SetLength и некоторых других;
• Если Вы используете длинные строки как аргументы или результаты для функций, располагающихся в DLL, то в DLL надо использовать модуль ShareMem;
• Не используйте длинные строки как члены структур типа record. Используйте там короткие строки или array[0..n] of char. Также нельзя использовать в структурах типа record динамические массивы. Данные ограничения отсутствуют для классов.
Различия TMEMOFIELD
Delphi 1
Во-первых, если аргумент size у GetMem равен нулю, GetMem устанавливает указатель в nil (не отбрасывайте такой способ, но разумней самому установить его в nil). Также в отладчике вы могли бы проверять значение DataSize (или getTextLen) перед самим вызовом.
(Проигнорируйте следующий параграф, если Table1Notes не Memo.)
Во-вторых, если Table1Notes — Memo-поле, вы, вероятно, захотите использовать Table1Notes.getTextLen, не DataSize, поскольку DataSize возвращает размер сегмента буфера записи (0-254), тогда как getTextLen возвратит вам реальный размер Memo. (Для строкового поля DataSize работать будет, но очень странно, поскольку возвращает ноль.) Также вы можете воспользоваться getTextBuf вместо getData, не знаю точно почему, но мои многочисленные экспериметны показали, что getTextBuf работает правильно и устойчиво, а getData нет.
Поскольку "wordwrapping" (перенос слов) доступен в вашем приложении, вы можете заменить символы #10 (перевод строки) и #13 (возврат каретки) на пробелы, например так:
cursor: pchar;
cursor := ваш буфер;
whilecursor^ <> #0 do if (cursor^ = #13) or(cursor^ = #10) thencursor^ := ' ';
Данный способ прост, поскольку нам нет нужды перемещать текст из переменной в переменную, хотя и не без недостатка, поскольку в конце каждой строки мы получаем два пробела, что может неправильно интерпретироваться при переносе строк. В качестве альтернативы, вместо пробела вы можете применить другой служебный символ, который ваш текстовый процессор воспримет в качестве прерывания строки, или проигнорирует его (например, символ #8). Если вам нужно просто избавиться от символов перевода строки, воспользуйтесь двумя курсорами как показано ниже (извините, не тестировал):
out, in: pchar;
out := ваш буфер;
in := out;
whilein^ <> #0 do begin
if (in^ <> #10) and(in^ <> #13) then begin
out^ := in^;
inc(out);
end;
inc(in);
end;
out^ := #0;
Если вместо этого вы хотите заменить каждую пару CR-LF или отдельный CR или LF единичным пробелом, попробуйте это:
out, inn: PChar;
out := ваш буфер;
inn := out;
whilein^ <> #0 do begin
if (in^ = #10) then begin
end
else if (in^ = #13) then begin
if (in+1)^
Если вместо этого вы хотите заменить каждую пару CR-LF или отдельный CR или LF единичным пробелом, попробуйте это:
out, inn: PChar;
out := buf;
inn := out;
whileinn^ <> #0 do begin
if (inn^ = #10) or((inn^ = #13) and((inn+1)^ <> #10)) then begin
out^ := ' ';
Inc(out);
end
else if (inn^ = #13) then
{ только CR, игнорируем }
else begin
out^ := inn^;
Inc(out);
end;
Inc(inn);
end;
out^ := #0;
{ буфер теперь закрыт }
Непроверенное: эффект уменьшения размера (путем установки терминатора #0) этого PChar позволит уменьшить время компиляции массивов и буферов GetMem, что же будет при использовании StrAlloc/StrDispose?
Вот конечный код после учета всех мелочей! Например, нам, в конечном счете, нужно сообщить указателю о необходимости возвратиться к началу своей новой строки.
procedureTForm1.RemoveSpaces( varInBuf: PChar; Size: Word);
var
Input, OutPut, Orig: PChar;
begin
GetMem(Output, Size);
input := Inbuf;
Orig := Output;
whileinput^ <> #0 do begin
if(input^ <> #10) and(input^ <> #13) then begin
output^ := input^;
inc(output);
end;
inc(input);
end;
Output^ := #0;
Output := Orig;
InBuf := Output;
end;
Я все еще немало удивлен тому как работает GetData! Я все еще не хочу использовать TMemo! Если кто-то может решить эту проблему, я буду очень рад! Пока же я готовлю для вас материал, включающий новые процедуры печати! Наведем порядок в беспорядке! Я уже имею реализацию вывода текста с любым шрифтом и в любой позиции, выраженной в дюймах, и это только начало! Но что я думаю действительно классно вышло, так это диманическая сетка! Вы можете создавать сетку с любым количеством строк и колонок. Назначьте текст и ячейку, установите горизонтальное и вертикальное выравнивание, выберите стиль границы для каждой ячейки и изучите множество других способов манипулирования и печати сетки!
Функция, возвращающая тип
Delphi 1
Вы можете сделать это в C++. В ObjectPascal это также можно сделать, смотрите пример:
// функция Chameleon, возвращающая тип сгенерированного исключения
unitUnit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,StdCtrls;
type
MyBoolean = class
public
Value : boolean;
end;
MyInteger = class
public
Value : integer;
end;
MyClass = class
public
Value : TStrings;
end;
TForm1 = class(TForm)
Button1: TButton;
procedureButton1Click(Sender: TObject);
private{ Private declarations }
public{ Public declarations }
procedureMyProc;
functionChameleon : boolean;
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
functionTForm1.Chameleon : boolean;
var
b : MyBoolean;
i : MyInteger;
c : MyClass;
r : integer;
begin
Интервал:
Закладка: