В приведенном ниже примере описано как можно получить список логических дисков, установленных в системе, а также определить их тип. Для этих целей используются функции winAPI GetLogicalDrives и GetDriveType.
Для работы примера на форму проекта поместите объекты Button1 и Memo1. В обработчике событий для Button1 нужно ввести указанный код.
Возможно ли создание массива компонентов? Для показа статуса я использую набор LED-компонентов и хотел бы иметь к ним доступ, используя массив.
Прежде всего необходимо объявить массив:
.
.
При необходимости динамического создания LED-компонентов организуйте цикл, пример которого мы приводим ниже:
.
.
.
.
.
.
.
.
Если компоненты уже присутствуют на форме (в режиме проектирования), сделайте их элементами массива, например так:
.
.
.
.
.
.
.
.
.
.
Тем не менее у нас получился массив со случайным расположением LED-компонентов. Я предлагаю назначить свойству Tag каждого LED-компонента порядковый номер его расположения в массиве, а затем заполнить массив, используя это свойство:
.
.
.
.
.
.
.
.
Если вам нужен двухмерный массив, то для формирования индекса понадобится другая хитрость, например, хранение в свойстве Hint информации о времени создания компонентов.
Мне необходимо найти индекс компонента в родительском списке дочерних элементов управления. Я попытался модифицировать prjexp.dll, но без успеха. У кого-нибудь есть идеи?
Есть такая функция. Ищет родителя заданного компонента, перебирает список и возвращает индекс искомого компонента. Функция прошла многочисленные тесты и вполне работоспособна.
Данная проблема решается как минимум двумя путями, о чем и будет рассказано ниже.
Решение 1
Действительно, любой компонент можно создать и без (вне) формы или любого другого дочернего компонента. Для этого я использую параметр nil:
Решение 2
Я привожу некоторый код, касающийся описываемой проблемы: он работал, когда я использовал его в большом приложении. Я не знаю специфического метода создания компонента TTable вне родителей, поэтому я пошел путем создания своего класса от TTable во время инициализации модуля. Удобство такого подхода объясняется наличием под рукой всегда готового к работе экземпляра класса, стоит всего-лишь добавить модуль к вашему приложению.
Конечно, новый класс не должен иметь одиноко выглядящую процедуру со странной технологией фильтрации данных :=))), да и не помешала бы публикация нескольких событий, но этот пример призван все-го лишь продемонстрировать иной подход к решаемой задаче.
Событие OncalcFields генерится ОЧЕНЬ часто и может быть необязательным и занимать большое количество времени, например, у вас есть таблица с неким вычисляемым полем, и при каждом редактировании таблицы вызывается следующий код:
Теперь, если Вы решили пройти последовательно каждую запись огромной таблицы, вы можете представить, какое количество таких событий будет сгенерировано! Они будут необязательны в случае, если вы сделаете обработку полей в отдельной процедуре.
Мой совет следующий: выключите генерацию события OnCalcFields, обработайте все поля и снова включите генерацию данного события, к примеру так:
.
.
.
.
.
.
.
.
.
.
.
Поля не вычисляются в течение времени обработки, которое может быть достаточно велико, но при наличие громоздких вычислений специфического поля (или даже нескольких полей), все вычисляется за один проход!
Данный метод позволяет исключить необязательный код и может быть использован повсюду, где применяются большие таблицы или сложный алгоритм калькуляции поля. Разница в скорости обработки таблицы довольно ощутима.
Я представляю на Ваш суд утилиту быстрого поиска по базе данных. Данная технология производит поиск по полям, преобразуя их значения в строки (все значения преобразуются в верхний регистр, включая действительные числа).
Данное решение может быть не самым быстрым, однако на поверку оно оказывается быстрее остальных, обнаруженных мною в Интернете (может вам повезет больше). Более того, представьте, что действительное значение какого-либо поля равно 4.509375354, а значение поиска равно 7, в этом случае утилита засчитает "попадание". Утилита удобна также тем, что она за один проход производит поиск более, чем в одном поле.
Это удобно, если у Вас имеются, к примеру, два поля с адресами. Это моя первая "серьезная" разработка, так как первое, с чем я столкнулся, изучая Delphi, стала необходимость включения процедуры поиска в любое приложение, работающее с базой данных. А так как поиск - вещь тоже сугубо специфическая, как и любое приложение, то мне пришлось побороть свой страх перед "крутым программированием" и попробовать написать свой поисковый механизм, удовлетворивший меня (и, надеюсь, других) своей скоростью и возможностью "мульти"-поиска по нескольким полям.
Я надеюсь, что он поможет тем программистам, кто часто сталкивается с подобными задачами. Технология довольно легка для понимания, но если у Вас возникли какие-либо вопросы, пошлите мне письмо электронной почтой, я буду рад Вам помочь. Посмотрев код, можно легко узнать поддерживаемые типы полей (добавить новые не составит проблем).
В этой статье будут рассмотрены некоторые функции для работы с окнами.
Функция FindWindow
Синтаксис function FindWindow(className,WindowName : PChar) : HWND;
Функция возвращает дескриптор окна, удовлетворяющий запросу (0 - если такого окна не найдено).
ClassName - Имя класса, по которому призводится поиск среди ВСЕХ окон системы.
WindowName - Заголовок окна
Один из параметров может быть равен nil, тогда поиск ведется по другому параметру.
Функция GetWindow
Синтаксис function GetWindow(Wnd : HWND; Param) : HWND
Функция возвращает дескриптор окна удовлетворяющий запросу.
Wnd - Дескриптор какого-либо начального окна
Param - Принимает одно из следующих значений-констант:
gw_Owner - Возвращается дескриптор окна-предка (0 - если нет предка).
gwHWNDFirst - Возвращает дескриптор первого окна (относительно Wnd).
gw_HWNDNext - Возвращает дескриптор следующего окна (окна перебираются без повторений, т.е. если вы не меняли параметр Wnd функции, повторно дескрипторы не возвращаются)
gw_Child - Возвращает дескриптор первого дочернего окна.
Функция GetWindowText
Синтаксис function GetWindowText(hWnd: HWND; lpString: PChar; nMaxCount: Integer): Integer;
Функция возвращает текст окна. Для формы это будет заголовок, для кнопки - надпись на кнопке.
hWnd - Дескриптор того окна, текст которого нужно получить.
lpString - Переменная, в которую будет помещен результат
nMaxCount - Максимальная длина текста, если текст длиннее, то он обрезается.
Функция SetWindowText
Синтаксис function SetWindowText(hWnd: HWND; lpString: PChar): BOOL;
Устанавливает текст окна.
hWnd - дескриптор того окна, текст которого нужно установить
X, Y, nWidth, nHeight - Соответственно: новые координаты X,Y; новая ширина, высота.
bRepaint - Булево значение, показывающее будет ли окно перерисовано заново.
Функция IsWindowVisible
Синтаксис function IsWindowVisible(hWnd: HWND): BOOL;
Возвращает True если данное окно видимо.
hWnd - дескриптор окна.
Функция EnableWindow
Синтаксис function EnableWindow(hWnd: HWND; bEnable: BOOL): BOOL;
Устанавливает доступность окна(окно недоступно, если оно не отвечает на события мыши, клавиатуры и т.д.). Аналог в Delphi свойство Enabled компонентов. EnableWindow возвращает True, если всё прошло успешно и False в противном случае.