Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Вопросы по Delphi (до версии 2009) - часть 6

Автор: Gnom3
Дата сообщения: 02.11.2012 10:03

Цитата:
Это переполнение или особенности хранения строчек StringList?


Цитата:
Думаю, что просто не предполагается, что в строке вообще могут быть символы #0.

символ #0 в каждой строке быть обязан, я давно уже вбил себе это в голову - это символ окончания строки для любого строкового параметра, в том числе и для каждого элемента массива типа tStrings. Совсем другое дело, когда пачка таких символов в одной строке. можно порекомендовать читать файл вручную, и парсить каждую строку, если больше одного #0 находим, то все предидущие в этой строке заменяем на, например, #32 (вроде под этим символом пробел идет).

Есть вопрос - скорей всего ничего сложного, но все-же - как заполнить ImagеList системными иконками из Shell.dll? (вроде там они лежат...)
Автор: krapotkin
Дата сообщения: 02.11.2012 11:32
Gnom3
Строго говоря, #0 не является частью строки. Это терминатор, что располагается после нее.
Еще раз предлагаю обратиться к файлу, что создается по TStringList.SaveToFile
там строки разделяются #13#10 и все.
следовательно, появление #0 для StringList - сюрприз

p.s. предЫдущие
p.p.s #0 при разборе вообще игнорировать и пропускать
Автор: Ichigo2
Дата сообщения: 02.11.2012 12:02
Оказывается уже после этой строчки ничего нет.

Попробую через TFileStram
Автор: Gnom3
Дата сообщения: 02.11.2012 12:05

Цитата:
p.p.s #0 при разборе вообще игнорировать и пропускать

все зависит от файла, и будет-ли он сохраняться в прочитанном виде обратно. Хотя не могу не согласиться что такой вид - наиболее вероятно, что ошибка при предидущей записи.
Цитата:
Строго говоря, #0 не является частью строки.

Эмм. Этот знак всегда присутствует в конце строки. strlen('mama') возвращает 5, просто "нечтение" этого символа заложено во всех функциях работы со строками. Хотя, это всего-лишь мой взгляд, а в работе со строками у меня часто бывают проблемы, может как раз из-за того, что неправильно понимаю принцип построения строки..
Автор: salexn1
Дата сообщения: 02.11.2012 12:24
Ichigo2
Выложите сам файл и часть кода
Если код а-ля
for i := 0 to f.count do
...
то конечно будет падать, после того, как i = count...


Автор: ant0ni02004
Дата сообщения: 02.11.2012 20:25
Ichigo2
а попробуйте "по честному" - открыть файл и в цикле while not eof через readln строки вытягивать
Автор: krapotkin
Дата сообщения: 02.11.2012 23:20
Gnom3
>>strlen('mama')

http://www.cplusplus.com/reference/clibrary/cstring/strlen/
:: number of characters between the beginning of the string and the terminating null character (without including the terminating null character itself)
http://delphi.scps.ru/string/str5223.htm
:: количество символов строки без учета символа конца строки.

strlen('mama') = 4 !

Автор: gosnami
Дата сообщения: 02.11.2012 23:29
Gnom3
strlen - длина БЕЗ учета символа конца строки.
StrEnd    Возвращает указатель на символ окончания длинной строки.
Автор: salexn1
Дата сообщения: 02.11.2012 23:59
krapotkin
Что-то я не понял вашего изумления...
круче было бы, если бы результат был бы НЕ 4?????
Автор: Varenik
Дата сообщения: 03.11.2012 15:50
salexn1
Цитата:
Что-то я не понял вашего изумления...
А почитать выше - слабо?
Цитата:
strlen('mama') возвращает 5
All
И вообще, по-моему здесь тема по Delphi а не CBuilder…
Автор: alex1334
Дата сообщения: 04.11.2012 19:55
Gnom3
Не все строки в дельфи содержат конечный ноль. Есть тип данных shortstring в дельфи он интерпритируется как массив [1..255] элемент с индексом 0 содержит длинну массива. Когда вы указываете тип string то в зависимости от опции компилятора он может восприниматься и как shortstring. Однако есть и строки с нуль символом в конце. Строки типа PChar точно имеют завершающий нуль. A вот как хранятся данные в строках longstring и wideString я не знаю. Не удивлюсь если они тоже не имеют завершающего нуля.
Класс Tstring имеет свойство capacity определяющее сколько строк мах может содержать объект. Сами строки хранятся в формате string а это значит что очень даже может строка НЕ содержать завершающего нуля
Автор: Gnom3
Дата сообщения: 05.11.2012 09:22
alex1334
я просто сталкивался с заполнением массива строк, и получал неожиданные значения размера массива, когда нужно было включать chr(0) в составе некоторых строк. поэтому и увидел проблему именно в этом. Утверждать не буду, просто проблема товарища Ichigo2, перекликается с моей тогдашней засадой.
Автор: gosnami
Дата сообщения: 05.11.2012 16:11
Господа, есть форма... на ней много Edit'ов... хочу в зависимости от значения менять цвет... причем для всех едитов одинаково - если 0 - то серый, если >0 - красный...
Как лучше организовать?.. приложение мультипользовательское....
по таймеру вызывать функцию, обновляющую значения для всех полей?
И как правильнее написать функцию? Можно ли написать 1 функцию...которая будет подходить для всех полей... и вызывать функцию, передавая в качестве аргумента эти самые эдиты... или это нереально?
Автор: XPerformer
Дата сообщения: 05.11.2012 16:26
gosnami
Думаю, в данном случае удобнее всего вызывать по таймеру - в случае, если значение может быть изменено извне другим пользователем.
В функции перебирать все контролы на форме. Если Components[i] is TEdit и условие выполнилось, то перекрашивать в нужный цвет
Автор: salexn1
Дата сообщения: 05.11.2012 17:16
gosnami
Правильно ли я понимаю:
есть 2 пользователя, они видят одни и те же данные.
Пользователь 1 меняет значение одного edit и тут же у другого изменяется цвет?

как и где хранятся данные?
Автор: A_V
Дата сообщения: 05.11.2012 17:40
gosnami
напишите наследник над TEdit, к-й будет в зависимости от значения менять цвет (думаю достаточно перекрыть метод Change). если все это в рамках одной формы, то его даже можно не регистрировать в IDE, а просто написать в том-же юните как TEdit = class(StdCtrls.TEdit)
не совсем правда понятно каким боком тут "мультипользовательность"..
Автор: alex1334
Дата сообщения: 05.11.2012 17:56
Gnom3
строки типа ansistring допускают символы #0 однако некоторые функции работы со строками из модуля SysUtil с такими строками работают некоректно, что же касается winAPI то мне встречались только функции которые требовали завершающего нуля. Многие функции delphi не явным образом вызывают функцию API и также требуют типа PChar. Однако сомневаюсь что строка ansistring и имеющая символы #0 будет корректно преобразована в тип PChar. Думаю что компилятор просто добавит пару команд вставляющих в конец строки символ #0. А вот win API в силу тупости операционной системы получив такую строку не корректно обработает символ #0. Выход тут только один никогда не передавать в winAPI указатель на строки, которые содержат символы #0.
Автор: salexn1
Дата сообщения: 05.11.2012 17:57
A_V
Так изменение на одной форме можно и без нового компонента сделать, хотя правильнее все таки создать свой контрол и переопределить нужные методы.
Но вот как быть с "мультипользовательностью"?
Делать по таймеру, если это база, не есть тру, т.к. можно положить базу при частых запросах...

Автор: A_V
Дата сообщения: 05.11.2012 18:04
salexn1
Ну пусть автор сначала внятно скажет, что там у него с пользователями происходит.. если действительно нужно среагировать на данные, измененные другим пользователям, то это лучше решать средствами субд, рассылая уведомления.. но это смотря какая субд..
Автор: gosnami
Дата сообщения: 05.11.2012 18:34

Цитата:
напишите наследник над TEdit, к-й будет в зависимости от значения менять цвет (думаю достаточно перекрыть метод Change). если все это в рамках одной формы, то его даже можно не регистрировать в IDE, а просто написать в том-же юните как TEdit = class(StdCtrls.TEdit)
не совсем правда понятно каким боком тут "мультипользовательность"..

можете пример показать?..
мультипользовательность ... если 1 человек изменил заказ и заказ улетел в другую графу... необходимо чтобы на всех компах значения обновились..
Автор: A_V
Дата сообщения: 05.11.2012 18:47
gosnami
>можете пример показать
ну какой пример.. в юните с формой описывешь контрол с тем-же именем:
TEdit = class(StdCtrls.TEdit)
protected
proceudre Change; override;
end;
в нем перекрываешь Change, в котором ставишь цвет.
при создании формы контролы создадутся не как системные TEdit'ы, а как описываемый, т.к у них имя класса то-же..

>если 1 человек изменил заказ и заказ улетел в другую графу... необходимо чтобы на всех >компах значения обновились..
какая СУБД?
Автор: gosnami
Дата сообщения: 05.11.2012 19:08

Цитата:
при создании формы контролы создадутся не как системные TEdit'ы, а как описываемый, т.к у них имя класса то-же..

понял, буду пробовать.. эдиты используются devExpress-овские. но думаю из-за этого проблем быть не должно... а почему как protected? разве не public?

Цитата:
какая СУБД?

Firebird
Автор: A_V
Дата сообщения: 05.11.2012 19:17
gosnami
с FireBird не работал, но там вроде есть возможность рассылки уведомлений с сервера
погугли по 'firebird events'
вот например
http://www.firebirdsql.org/file/documentation/papers_presentations/Power_Firebird_events.pdf

если не получится - то завсети поле с датой (timestamp), при изменениях ее обновлять, по таймеру считывать, если не та, что при загрузке формы - обновлять значения контролов


Цитата:
а почему как protected? разве не public?

ну Change - внутренний protected метод

Добавлено:
для DevExpress объявляй так:

TcxTextEdit = class(cxTextEdit.TcxTextEdit)
protected
procedure DoTextChanged; override;
end;

Внутри проверяй Text и ставь Color
Автор: salexn1
Дата сообщения: 05.11.2012 22:34
A_V
Уже много было копий сломано насчет автообновлений...
Тут ОЧЕНЬ много вопросов и как бы не навредить с такими обновлениями...

А если в этот момент сотрудник изменяет данные? А как часто опрашивать (запускать таймер)? А если часто, то не положит ли такое обновление базу данных и сетку (при наличии определенного количества пользователей)?

В общем - думать,думать и еще раз думать...

Автор: A_V
Дата сообщения: 05.11.2012 23:08
salexn1
думать надо, не спорю, но это вопрос автору.. я, если честно, сомневаюсь, что подобное вообще имеет смысл. в крайнем случае, можно выводить хинт, типа данные были изменены, но вообще лучше не давать что-то одновременно править. решать все равно автору, какой вопрос, такой ответ
Автор: salexn1
Дата сообщения: 06.11.2012 08:28
A_V
Судя по статусу gosnami забанен... Не скоро узнаем, что он хотел в итоге
Автор: SevereK20
Дата сообщения: 06.11.2012 09:15


Цитата:
А если в этот момент сотрудник изменяет данные? А как часто опрашивать (запускать таймер)? А если часто, то не положит ли такое обновление базу данных и сетку (при наличии определенного количества пользователей)?

Собственно говоря в главном окне будут поля - Обработанные, необработанные заявки и т.д.
У каждой группы будет свой критерий отбора, по которым они будут делиться на эти группы...
Допустим обработался 1 заявка... соответственно счетчики должны поменяться...
Если 2 человека начнут одновременно обрабатывать заявку... пытаясь внести в нее изменения.... тут ничего страшного не будет - холостым апдейтом всегда проверяется...

Цитата:
procedure DoTextChanged; override;

Это процедура класса cxTextEdit ? В документации DevExpress искал... ни одного метода минимально похожего на TextChanged.... однако в делфе все работает...подскажите неучу...где ищуться эти самые стандартные процедуры, которые можно переопределять?
Автор: salexn1
Дата сообщения: 06.11.2012 09:28
SevereK20

Цитата:
где ищуться эти самые стандартные процедуры, которые можно переопределять?


как правило в исходниках ищут.
Автор: SevereK20
Дата сообщения: 06.11.2012 09:41

Цитата:
как правило в исходниках ищут.

точно.. нашел в cxTextEdit.pas ... но удивительно что не гуглится вообще... сочетание "cxTextEdit DoTextChanged" дает только 5 результатов... ито не то, что надо.
Всем спасибо.
Автор: A_V
Дата сообщения: 06.11.2012 09:55
SevereK20
искать - в исходниках по похожему названию (лучше с плагином, к-й показывает список процедур напр. Ctrl+G в Gexperts). Именования обычно в нормальных компонентах человеческие, по этому по фильтру по слову Changed все сразу находится. если так не нашлось, вешаешь событие (в данном случае по изменению), ставишь туда брейкпойнт, затем по call-stack смотришь, из какого метода произошел его вызов

Страницы: 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374

Предыдущая тема: MPO File


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.