Программный поиск файлов
В этом уроке мы с вами ознакомимся с основными принципами программной организации поиска файлов. Для начала определимся, зачем нам это может быть нужно. Например, вам нужно при запуске программы на выполнение просканировать определенный каталог на присутствие DOC файлов, и при наличии таковых открыть их на редактирование или напечатать. А как вам такая идея: фоновый поиск EXE файла в сети, и при обнаружении новой версии, автоматическое обновление.
Многим известны программы, где можно искать файлы, правила поиска файла. Файлы можно искать как с файловых командирах (нортон, волков, дос навигатор, фар), так в любой операционной системе. В операционной системе windows диалоговое окно поиска файла вызывается «Пуск» — «Поиск» — «Файлы и папки». В открывшимся окне необходимо задать условие искомого файла (название, маска) и путь начального поиска (каталог). На других вкладках этого диалогового окна можно расширить возможности поиска по дате изменения, по содержащемуся тексту, по размеру.
Вспомним правила поиска файлов. Вы можете задать как имя искомого файла, так и его маску, если название неизвестно или необходимо найти несколько. Т.е. применяя специальный шаблон поиска, вы можете организовать условия выборки найденных файлов. Сразу оговорюсь, что поиск можно применять как к файлам, так и к каталогам. Будем их называть элементами файловой системы. В шаблон маски искомых элементов может входить:
- Буквы и цифры в названии и расширении.
- Символ * (звездочка, математический знак «умножить»), заменяющий любое количество всевозможных букв и цифр в названии или расширении.
- Символ ? (знак вопроса), заменяющий одну букву или цифру в названии или расширении искомого элемента.
Например, вы ищите все текстовые файлы с расширением TXT. В поле имени искомого файла вам нужно ввести «*.TXT» (пишется без кавычек) и система найдет все такие файлы в указанном диске или каталоге. Если вам надо найти все файлы с названием semen, то в поле поиска файла нужно ввести «semen.*». Если вам нужно найти элементы с третьей буквой k и с первой буквой t в расширении, то вводите «??k*.t*». Здесь знак вопроса указывает на любой символ, третьим символом по порядку идет буква k, далее название файла (каталога) может состоять из любого количества букв и цифр, указываем звездочку. В расширении первая буква t, дальше следует любое расширение.
Примечание: файлы и каталоги в операционной системе windows ищутся без учета регистра, т.е. строчние и прописные буквы не различаются.
Теперь рассмотрим программный поиск файлов с помощью языка программирования object pascal.
Вся организация цикла поиска, а именно это и есть цикл с продолжением поиска, сводится к:
- Задание условий поиска. Это каталог и маска искомого элемента или элементов, атрибуты элемента(ов). При задании условий поиска сразу происходит поиск первого подходящего под условие. Это функция FindFirst.
- Продолжение поиска следующего элемента по заданным в первом пункте условиям. Это функция FindNext и она может вызываться сколько угодно раз, пока все файлы и каталоги, удовлетворяющие условию, не будут найдены.
- Закрытие поиска и освобождение памяти, выделяемую системой под поиск. Команда FindClose.
где: Каталог для поиска и маска искомого элемента — строковая величина, имеющая тип String, может, например, содержать ‘c:\\*.*’ — все элементы в корне диска С. Обратите внимание, что указывается полный путь для поиска.
Атрибуты искомого элемента это пользовательские или системные атрибуты, которые может иметь файл (каталог, метка диска). Вот их перечень:
- faReadOnly — Файлы «только чтение». Такой атрибут устанавливается на файлы, которые не рекомендовано изменять, удалять. Такой атрибут имеют файлы, например, записанные на компакт-дисках.
- faHidden — Скрытые файлы. При обычных установках браузера и командира эти файлы невидимы.
- faSysFile — Системные файлы.
- faVolumeID — Файл метки диска. Такой элемент в своем имени имеет название диска (максимум 11 символов).
- faDirectory — Атрибут признака каталога.
- faArchive — Обычный файл. По умолчанию устанавливается на заново создаваемых файлах.
- faAnyFile — Если установить в качестве атрибута искомых элементов, то будет произведен поиск по всем вышесказанным атрибутам.
Эти вам нужно искать только элементы, имеющие атрибут «каталог» и «скрытый», то можно применить знак математического сложения, например faDirectory + faHidden.
Поисковая переменная имеет тип TSearchRec. В нее, при успешном результате поиска, будет занесены все необходимые данные о найденном файловом элементе.
Поскольку FindFirst является функцией, то она должна сама возвращать некоторое значение. Это значение имеет тип Integer и означает результат поиска файла (код ошибки поиска). Если файл найден, то принимает нулевое значение.
Эта функция продолжает поиск, заданный в функции FindNext. Возвращает значение результата поиска (нулевое в случае успешного поиска).
Закрывает поиск и освобождает память, выделенную системой под поиск.
Теперь рассмотрим пример. Допустим, нам надо найти все файлы и каталоги в каталоге DELPHI, находящийся на диске C:. В дальнейшем, вы можете самостоятельно, изменяя маску, менять условия поиска. Для формы с компонентом ListBox1 и кнопкой Button1 реакция на OnClick по кнопке:
Представленный пример кода, в принципе, является основой для организации более углубленного поиска, поиска файлов по времени создания, по содержащимся словам. Если вы запустите эту программу на выполнение, то при нажатии на кнопку Button1 вы увидите в списке в первой и второй строке элементы «.» и «..». Это элементы, имеющие атрибут «каталог». Первый содержит связь с корневым каталогом диска, второй содержит связь к каталогом верхнего уровня. Со вторым вы встречаетесь в дисковых командных оболочках, например нортон, когда выбираете каталог «..» и нажимаете на «ввод». Тем самым вы попадаете в каталог на уровень выше. Естественно, в нашей поисковой программе такие элементы не надо вносить в список, поэтому мы игнорируем их нахождение. Исправляем процедуру нажатия на кнопку Button1:
В этом случае, при нахождении каталога с именем «.» или с именем «..» программа продолжит обработку цикла поиска без вывода найденного имени элемента в компонент списка ListBox1.
Теперь рассмотрим тип TSearchRec. Он имеет в себе несколько полезных свойств:
- Name — название найденного каталога (файла);
- Size — размер файла в байтах;
- Attr — атрибуты каталога (файла);
- Time — упакованное значение времени и даты создания каталога (файла).
Все вышеперечисленные свойства мы уже рассмотрели или они понятны сразу, за исключением свойства Time. Оно имеет тип Integer и содержит в себе упакованное значение даты и времени создания файла. Распаковка производится с помощью функции FileDateToDateTime, которая в результате возвращает значение даты и времени.
Теперь добавим в нашу форму компонент DateTimePicher1 (страница Win32) и допишем несколько строк.
Как вы уже заметили, мы отбираем файлы и каталоги по дате создания, начиная с указанной в компоненте DateTimePicker1.
Теперь попробуем организовать поиск файлов во всех вложенных каталогах. Это не так просто, как может показаться на первый взгляд. Нам придется вручную организовывать весь цикл входа-выхода из каталога, перебор файлов. Немного сложноватый материал, но возможно те из вас, кто уже работал с языком программирования pascal или другим, знакомы с технологией многократности и многовложенности использования одного и того же программного кода. Коротко объясню алгоритм работы такой программы.
- Задание начальных условий поиска, поиск первого элемента.
- Если найден файл, то выводим его и соответственно обрабатываем (выводим в список, открываем, удаляем и т.п.).
- Если найден каталог, то начинаем новую процедуру поиска. Но программный код остается прежним. Мы просто заново вызываем и входим в эту же процедуру поиска.
- Обрабатываем таким же образом все вложенные в этот каталог файлы и каталоги (начинаем новый поиск в обнаруженном каталоге).
- Если элементов во вложенном каталоге больше нет, то обработка процедуры поиска в нем завершается, и мы выходим из нее. При этом мы оказываемся в том же месте, откуда и вызвали эту процедуру. Но она была вызвана из этой же процедуры. Поэтому программа продолжает свое выполнение дальше с момента возврата.
Таким образом, сколько витков программа наматывает на так называемый клубок, столько витков она и размотает. Программа на выполнении проходит все дерево вложенных каталогов, выполняя один и тот же кусок программного кода! И при этом данные условий поиска не перепутываются, и для каждой уникальной процедуры они сохраняются.
Рассмотрим пример. Создайте новый проект. Для создания отдельной процедуры поиска нам нужно объявить ее в соответствующем разделе (создаем ее вручную, поэтому и самостоятельно объявляем).
В разделе public пишем строку:
А в разделе кода программы, до слова «end.» вставляем пустой каркас процедуры
На форму вставляем компонент списка ListBox1, Button1, Edit1. Для компонента Edit1 свойство Text устанавливаем в «c:\\delphi\\». Обратите внимание на последний символ, знак «\\», присутствие которого в начальном пути поиска обязательно. Дальше процедура OnClick для кнопки Button1 выглядит следующим образом:
Созданная нами вручную процедура поиска:
Если вы в компоненте Edit1 в качестве начального условия поиска файлов зададите корневую папку диска, например «С:\\», то вы получите полный перечень всех файлов на данном диске. Обратите внимание на скорость поиска файлов и скорость работы вашей программы.
как пользоваться «FindWindow» в Делфи?
облазил все, но так ничего толком найти не могу. объясните мне как пользоваться функцией FindWindow, как и где ее прописывать и от куда берутся названия приложений(при помощи spy++)тогда и как ей пользоваться))) очень буду благодарен, начинающий ДеЛьФиСт)))
Добавлено через 1 минуту
пишите отвечу сразу, т.к. «горит». очень нужно разобраться.
BaT команды и «трюки» в делфи — как?
Так.. Допустим мне нужно запустить файл, два. BAT Set variant=Variant1 :: Set.
как в делфи сделать кнопку «печать»??
подскажите пожалуйста, если можно то с кодом.
В каждом слове текста замените «а» на букву «е», если «а» стоит на четном месте, и заменить букву «б» на сочетание «ак»,
В каждом слове текста замените «а» на букву «е», если «а» стоит на четном месте, и заменить букву.
Из слов «Работа», «крест», «тон» составить фразу «Кто не работает, тот не ест» и определить ее длину
Из слова «Работа»,»крест»,»тон» составить фразу:»Кто не работает, тот не ест» и определить ее длину.
Добавлено через 36 секунд
блакнот запускаю после приложения, и все равно
Добавлено через 9 минут
u1987200, потому что не прыгнет.
нужно фокус иметь.
как же я люблю «прогеров»**, которые пишут офигенные трейнеры для онлайн игр, аля прыжок.
** Хованский стайл active
ну вроде все так?
Добавлено через 45 секунд
мне бы научиться просто посылать одну команду а дальше я уже сам допетрю по шаблону)))
Добавлено через 4 минуты
и так пробовал
запускаю калькулятор потом прогу и нифига(
Добавлено через 1 минуту
как найти имя при помощи spy++? или он не нужен? как понять что «калькулятор» — калькулятор?
Тоже попробовал — нифига.
В заголовке написано: ‘Калькулятор’
млин, и че делать я уже третий раз тему поднимаю и что? где орда ответов
Добавлено через 1 минуту
объясните мне, ну не понимаю я, может мне начать с нуля, что-то гдето упустил. так предложите литературу какую почитать на данную тему
Нашел. Едит в разделе «Преобразование единиц». Спасибо.
А можно как-то выбрать нужный элемент, например, зная его Handle?
Добавлено через 8 минут
Точнее, выводит «4» во все Едиты, которые есть, просто главное окно Калькулятора не Едит, а Dialog.
да, кстати, зачем сложности spy дает хендл например 00010362 и как туда послать команду?
Добавлено через 2 часа 0 минут
Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь или здесь.
Тысячные числа исправлять к примеру с «1200» на «1 200», «12000» на «12 000» и т.д
Собственно числа исправлять к примеру с «1200» на «1 200», «12000» на «12 000», «120000» на.
Подсчёт очков для игры «Найди пару» на делфи
Нужно добавить код,чтобы за каждую правильно найденную пару,выводилось текст «Вы набрали 10 очков».
нужна программа на делфи 7 » Учет покупки и продажи валюты. «
Здравствуйте друзья! Надеюсь вы мне поможете ! Таблица продажи и покупки валюты: дата, фамилия.
How to find all text fields in a window?
I have a window with two text fields inside it.
How can I get the handles of both text fields using WinAPI calls?
Note: Both text boxes belong to a different application (I make the WinAPI calls in application A and the text boxes are located in application B).
Update 1:
I get Invalid window handle message when invoking GetClassName .
I suppose that something is wrong with my declaration of the callback function.
EnumChildWindows is invoked from one of the methods of TMyClass like this:
Here’s the code of the callback function.
1 Answer 1
- Use FindWindow or EnumWindows to find the top level window of the target application.
- Call EnumChildWindows to enumerate all children of the top level window.
- In the enumeration callback use GetClassName to check for the desired window class. It would be EDIT for a raw Win32 edit window, for example.
Use a tool like Spy++ to understand the structure of the target app, and find out the precise window class names that it uses.
Your questions in the comments about how to call GetClassName got me thinking. If you are using XE3, you could write a simple type record helper for HWND to make it syntactically cleaner to get hold of the class name:
And then you can write hwnd.ClassName to obtain the window class name. Of course, if you are not using XE3 you can do it like this:
Note that I am using a buffer length of 256 since window class name lengths are limited to be no longer than that.
Regarding the code in the update, you must not use an instance method for the callback. The callback must be declared like this:
This is made clear in the documentation. Unfortunately the declaration of EnumChildWindows in Windows.pas completely abandons type safety of the callback function. So you have to get it right without help from the compiler.
Note also that HWND and THandle are not the same thing. Don’t mix them up.