Delphi. Существует ли файл и доступен ли он для чтения?

Простая проверка возможности прочитать файл. //True – файл открыт для чтения. Иначе – False.

 

Delphi. Как отсортировать TStringList и сохранить соответствие с несколькими другими TStringList?

Данный пост является развитием предыдущего. Будем сортировать один TStringList -другие же приводить в соответствие с переставленными элементами.

Исходные данные у меня точно такие же. Не буду переписывать часть поста сюда.Изменился только алгоритм сортировки, так как теперь в соответствие нужно привести не один, а несколько списков. Continue reading

Delphi. Сортировка TStringList с приведением в соответствие другого TStringList

Что делаем?

Есть у нас некоторый TStringList, скажем SLToSort:TStringlist. Нужно его отсортировать – задача элементарная, пишем компараторы для наших данных, включаем CustomSort и всё готово. А что делать, если кроме SLToSort есть просто SomeSL:TStringlist и после сортировки SLToSort – нужно привести его элементы в соответствие с SLToSort, ну то есть так….

Где это может понадобиться?

Случай редкий, но всё же. Я делаю небольшой FTP клиент, который собирает данные о файлах на сервере. В принципе – вся информация уже есть и её хранит ОС, я к тому, что в данном случае вопрос использования БД – это действительно вопрос. Я подумал, что логично, просто собирать эти данные и использовать в FTP клиенте, но возникли нюансы, в частности с сортировкой списков. В SQL одна простая инструкция SortBy, а здесь приходится изобретать, но плюс в том, что программа становится независимой от БД.

Мне казалось, что я вроде сделал это, пока не наткнулся на глюк того, что если элементы одинаковые, то алгоритм работает некорректно. Немного последив за тем, как работает встроенный алгоритм CustomSort, на котором я строил свой алгоритм, я понял, что он меняет местами элементы, даже если они одинаковые. В основе CustomSort лежит QuickSort, если немного раскопать внутренности метода. Но суть не в этом.  Continue reading

Delphi. Как узнать адрес в памяти строковой переменной?

Всегда считал, что адрес любой переменной можно взять как-то вот так…

А оказывается для строк, и не только, это неправильно, потому что s в данном случае уже указатель. То есть, насколько я понимаю для integer и др. не ссылочных типов это сойдет, а для ссылочных – как-то строки – не прокатитит.  А правильно для строк вот как… – адрес то уже содержится, нам известен, на него указывает s, нам остается только сделать приведение типов

Also Transition to hex

 

Delphi. Делаем простой инкрементальный поиск

Пусть на ListView выведены данные. Сделаем простой инкрементальный поиск…

45

46

Данные будем брать из ListView. Алгоритм поиска самый простой – перебор, при желании и обилия большого числа данных его легко можно заменить, скажем на бинарный поиск. Сначала результаты поиска сохраним в отдельном списке, и далее будем проматывать по мере нажатия кнопки далее, показывая результаты.  Continue reading

Delphi. GDI+ vs StretchDraw. Как уменьшить много картинок в потоке и сохранить их на диске?

Встала задача – создать thumbnails для полноформатных изображений. В сети уйма информации, не знал за что хвататься, решил пробовать по очереди. В сущности, попробовал 2 способа более менее подробно, а остальные по верхам. Остановился на стандартном StretchDraw из Delphi, из за того, что GDI+ почему-то в дополнительном потоке рисовала белые прямоугольники. Я не стал это глубоко раскапывать, так как нужно было решать задачу.

snimok

В результате получим кучу уменьшенный фотографий практически из любых форматов. Я тестил с Jpg, PNG, Tiff, с другими думаю тоже будет работать, так как для загрузки используется twicimage.

41

Коды приведенные ниже иллюстрируют уменьшение большого числа изображений. Как это работает?

Выбираем директорию

Запускается отдельный поток, в котором в цикле уменьшается большое число изображений

Всё складывается в папочку \thumbnaiPics

Я использовал формат twicimage, который позволяет загружать большое число форматов, ну и в программе уже в ручную ставил фильтр на сами форматы.

Как уменьшить одно изображение с помощью библиотеки GDI+?

Continue reading

Delphi. TListView. Сортировка в обычном и virtual режимах

Понадобилось сделать сортировки в обычном и virtual режимах для компонента TListView. В обычном мы сами заполняем и сразу весь список так сказать. Для небольших списков это Ок, а если записей под 100 000 – это удовольствие будет тормозить, чтобы этого избежать, в TListView есть, как известно virtual режим, который подгружает данные в событии onData. Но об этом позже.

39

Сортировка TListView  в обычном режиме

Традиционная сортировка в сети достаточно известна, как я понял, вот например на блоге geekelectronics довольно хорошая статья. Сложного ничего нет.

Обработаем событие OnCompare

Сам вызов сортировки происходит таким образом

Направление сортировки можно заменить переменой порядка Item1.Caption и Item2.Caption на Item2.Caption и Item1.Caption в компараторе.

SortType определяет, как я понял – что мы будем сортировать – строки или цифры, как известно – они по разному сортируются. Как сортировать строки и цифры – более менее понятно. Как сортировать, скажем даты… Далее мы увидим как это можно сделать, сделав специальный компоратор для даты. В принципе, ничего сложного!!! Но вот как в стандартном режиме переключаться на разные типы данных внутри одного компоратора в событии OnCompare – не совсем понятно.

Вообще, прямо очень хорошее описание сортировки в обычном (невиртуальном) режиме TlistView находится на официальном сайте Embarcadero. Там есть ещё свои тонкости и нюансы, но я затеял данный пост скорее для описания сортировки в виртуальном режиме TListView.

Сортировка TListView в виртуальном режиме

Внимание, следующая часть статьи не совсем корректна, если данные одинаковые то алгоритм работает не совсем корректно. Чуть позже это поправлю.

Вот этой информации, я нигде не нашёл. Пришлось думать самому. Результат оправдал.

Что такое виртуальный режим TListView? Скажем, нам нужно отобразить, ну оч. много данных. Для этого и создан виртуальный режим. Включить его можно так…

Соответственно данные для отображения в TListView нужно передавать в событии OnData, ну скажем, так…

FrandomList и FrandomList2 это заранее созданные списки. При каждом обновлении списков – обновить данные в TListView можно так… Continue reading

Delphi. TStringList.CustomSort – сортировка строк, integer, tdatetime в ascending и descending порядках

Часто использую TStringList, а вот сортировку в нём не часто. Понадобилась, разобрался, ниже основные моменты по сортировке разных типов, тем или иным путем попавшим в TStringList.

Сортировка строк

Ascending

Вариант 1 (самый популярный, поэтому самый краткий)

Все остальные функции – через так называемые функции компараторы – они позволяют задать тип данных, с которым мы работаем, а также направление сортировки – по возрастанию или по убыванию.

Вариант 2

Descending

Сортировка integer

Continue reading

Delphi. Indy. FTP. Как получить дату создания, изменения и последнего доступа на сервере от idFTP ?

Этот вопрос можно преобразовать в “как преобразовать 20160911195120 в 11.09.2016 19:51:20 и перевести в LocalTime?”

Я также поднял этот вопрос на 2 форумах

Русский форум

Английский форум

Также мне показалась интересной ссылка на TTimeZone  – класса, который появился, начиная с Delphi XE и избавил нас, в какой-то степени от зависимости от WinAPI

Ссылка на обзор на блоге про TTimeZone 

В сущности, получить даты создания, изменения и последнего доступа в Indy несложно, сделать это можно вот так…

Мы получим примерно вот такой результат

36

Как вытащить его оттуда? Да с помощью регулярок. Я чуть позже, в данном посте покажу как я это сделал. Мы получим число в формате 20160911195120. Но если распарсить его, то оно не локализовано, оно в GMT 0;

Как преобразовать 20160911195120 в 11.09.2016 19:51:20 и перевести в LocalTime?

Continue reading

Delphi. Indy. FTP. Как правильно удалить директорию с FTP сервера?

Столкнулся с тем, что если удалять директорию с помощью стандартной функции RemoveDir библиотеки Indy, то непустые директории не удаляются. Немного поискав, наткнулся на почти готовое решение на форуме. Суть в том, что удалять директории нужно рекурсивно, и начиная с конца списка.

Применив этот код в своем примере напрямую, я столкнулся с ошибкой – “Already Connected”. И действительно, при рекурсии, если подключаться в самой процедуре, Connect к FTP серверу  получается несколько раз. Когда я вынес подключение вовне, а рекурсия работала с одним подключением – всё встало на свои места. Вот код, который у меня получился и работал корректно на тестах.

Сам вызов будет следующим

Всего получилось 3 процедуры

Для начала рассмотрим так сказать ядро удаления… Continue reading