Часто возникает необходимость передать переменные в самой строке URL. Для этого нужно воспользоваться кодированием строки с переменными. А все спецсимволы типа пробела тоже должны учитываться.
Без применения кодирования:
Если испытать в работе первый код, то наш SQL запрос будет с некоторыми отсутствующими символами. А нам это не подходит, ведь теряется весь смысл многословного запроса.
Именно для решения этой проблемы программистамы было придумано кодировать строку перед подачей ее скрипту. Сама функция кодирования называется URLEncode и вся строка запроса кодируется в безопасном режиме (safe mode).
В статье описан процесс регистрации базы данных в BDE из программы.
Для доступа к BDE будем использовать компонент Session (вкладка BDE на панели компонент). Поместим его на форму, пусть это будет Session1. Положим на форму также компонеты Table, DataSource и DBGrid.
1. Простая регистация базы данных (алиаса)
Для добавления стандартного алиаса можно воспользоваться методом AddStandardAlias(Name, Path, DefaultDriver) объекта Session1, где Name - имя алиаса, Path - физический путь к базе данных, DefaultDriver - тип базы данных.
Для стандарного алиаса DefaultDriver может быть трех типов: Paradox, DBASE, ASCIIDRV. Перед запуском метода AddStandardAlias должно быть определено значение SessionName.
Пример:
Регистарция базы данных в BDE производится методом AddAlias(Name, Driver, List) объекта Session1, где Name - имя алиаса, Driver - используемый драйвер БД, List - список параметров.
Вот пример кода, выполняющего действия, аналогичные описанным в пункте 1.
.
.
.
.
.
.
.
.
.
.
.
.
. 3. Удаление базы данных (алиаса) из BDE
Здесь все просто, запускаем метод Alias с указанием имени алиаса.
Проверить, существует ли интересующий нас алиас можно с помощью методa IsAlias.
Данная проблема решается как минимум двумя путями, о чем и будет рассказано ниже.
Решение 1
Действительно, любой компонент можно создать и без (вне) формы или любого другого дочернего компонента. Для этого я использую параметр nil:
Решение 2
Я привожу некоторый код, касающийся описываемой проблемы: он работал, когда я использовал его в большом приложении. Я не знаю специфического метода создания компонента TTable вне родителей, поэтому я пошел путем создания своего класса от TTable во время инициализации модуля. Удобство такого подхода объясняется наличием под рукой всегда готового к работе экземпляра класса, стоит всего-лишь добавить модуль к вашему приложению.
Конечно, новый класс не должен иметь одиноко выглядящую процедуру со странной технологией фильтрации данных :=))), да и не помешала бы публикация нескольких событий, но этот пример призван все-го лишь продемонстрировать иной подход к решаемой задаче.
У меня есть форма с расположенными на ней компонентами TreeView и Memo. Значение свойства align обоих компонентов позволяет им занимать всю форму. Я хотел бы расположить между ними движок типа Splitter, пропорционально меняющий их размеры (один шире, другой меньше и наоборот). Какой компонент мог бы симитировать поведение Splitter и как это реализовать?
Предположим, Ваш TreeView расположен в левой, а Memo в правой части формы. Вам нужно сделать следующее:
* Установите свойство Align компонента TreeView на alLeft.
* Вырежьте (Ctrl-X) компонент TMemo из вашей формы.
* Добавьте компонент Panel и присвойте его свойству Align значение alClient.
* Внутри панели разместите другой компонент Panel.
* Установите его ширину, равной 8 пикселам, свойству Align присвойте значение alLeft.
* Скопируйте вырезанный компонент TMemo в панель Panel1 и присвойте свойству Align значение alClient.
Код может быть модифицирован для получения горизонтального движка - идея, надеюсь, будет вам понятна.
Panel2 - движок: теперь вам необходимо добавить процедуры, приведенные ниже. Ваш код будет выглядеть приблизительно так:
Иконка компонента является инкапсулированным объектом, требующим для хранения изображения некоторый участок памяти. Следовательно, при замене иконки, память, связанная с первоначальной иконкой, должна возвратиться в кучу, а для новой иконки требуется новое распределение памяти.
По правилам Delphi, этим должен заниматься метод "Assign". Ниже приведен код всей процедуры замены иконки.
Как через конфигурацию IDAPI получить физический каталог расположения базы данных, зная ее псевдоним? Обратите внимание на метод GetAliasParams класса TSession. Возвращенная строка будет содержать искомый путь.
Здесь я привожу примеры программ, которые я использую для копирования и удаления таблиц. Необходимые для работы модули: DB, DBTables, DbiProcs,DbiErrs, и DbiTypes.
Вам всего лишь необходимо указать каталог расположения, исходное имя таблицы, каталог назначения и имя таблицы, куда будет скопирована исходная таблица и BDE скопирует таблицу целиком со всеми индексами. Процедура удаления в качестве входных параметров использует каталог расположения и имя таблицы, при этом BDE удаляет как саму таблицу, так и все файлы, связанные с ней (индексы и т.п.).
Для тестирования данные процедуры были помещены в новое приложение и мне пришлось их немного отредактировать, чтобы удалить некоторые зависимости, которые были связаны с главной формой приложения. Теперь процедуры являются полностью автономными и могут быть помещены в отдельный модуль. (Не забудьте включить его в список используемых модулей).
Событие OncalcFields генерится ОЧЕНЬ часто и может быть необязательным и занимать большое количество времени, например, у вас есть таблица с неким вычисляемым полем, и при каждом редактировании таблицы вызывается следующий код:
Теперь, если Вы решили пройти последовательно каждую запись огромной таблицы, вы можете представить, какое количество таких событий будет сгенерировано! Они будут необязательны в случае, если вы сделаете обработку полей в отдельной процедуре.
Мой совет следующий: выключите генерацию события OnCalcFields, обработайте все поля и снова включите генерацию данного события, к примеру так:
.
.
.
.
.
.
.
.
.
.
.
Поля не вычисляются в течение времени обработки, которое может быть достаточно велико, но при наличие громоздких вычислений специфического поля (или даже нескольких полей), все вычисляется за один проход!
Данный метод позволяет исключить необязательный код и может быть использован повсюду, где применяются большие таблицы или сложный алгоритм калькуляции поля. Разница в скорости обработки таблицы довольно ощутима.
Вот несколько функций для операций с двухмерными массивами. Самый простой путь для создания собственной библиотеки. Процедуры SetV и GetV позволяют читать и сохранять элементы массива VArray (его Вы можете объявить как угодно).
Например:
Самый простой путь - создать массив динамически
сделайте функцию fetch_num типа
и затем вместо myarray[2,3] напишите
Вот способ создания одно- и двухмерных динамических массивов:
Прежде чем работать с графикой, необходимо понять, как именно в Windows реализован принцип перерисовки изображений. Не инструменты рисования являются предметом этого материала, а общий механизм перерисовки окон.
Данный материал посвящен системному сообщению WM_PAINT.
Основной принцип перерисовки: Save and Paint - сохраняй и прорисовывай.
Windows не хранит в памяти нарисованное изображение в виде растрового рисунка. Система перерисовывает ту часть окна , которая в какждый конкретный момент в этом нуждается.
Когда Windows ( или другое приложение) посылает запрос на перерисовку окна или его части, этому окну посылается сообщение WM_PAINT.
Посылка сообщения WM_PAINT окну может быть вызвана как явным обращением к методам Window или RedrawWindow, так и полученим запроса на перерисовку от системы, которое поступает при перемещении окна, изменении его размеров и так далее. Windows посылает это сообщение, когда не имеется никаких других сообщений в очереди сообщений приложения.
Сообщение WM_PAINT относится к сообщениям с низким приоритетом, поэтому оно будет обработано в самую последнюю очередь.
Если будут посланы подряд несколько сообщений WM_PAINT, то обработано будет только одно, так как система не регистрирует следующие сообщения WM_PAINT. Таким образом достигается минимизация затрат на исполнение очень длительной операции - перерисовки окна.
В соответствии с общим подходом, принятым в Windows, перерисовываться будет не все окно, а только та часть, которая в этом нуждается. Так называемая область модификации - Region. К области модификации добавляется только некорректно отображаемая часть - Invalid Area , именна та часть окна, которая нуждается в перерисовке.
Область окна установливается как некорректная (Invalid area) методами Invalidate, InvalidateRect, или InvalidateRgn, а так же после того, как окно передвигают, изменяют его размеры или выполняют любою другою операцию, которая воздействует на клиентскую область окна.
Метод Invalidate объявляет некорректной всю клиентскую область окна.
Метод InvalidateRect ( и InvalidateRgn ) объявляет некорректной клиентскую область внутри данного прямоугольника, добавляя этот прямоугольник к текущей области модификации ( Region).
Удалить некоторую область из Region можно методами ValidateRect или ValidateRgn.
Таким образом, некорректные области накапливаются в Region, пока эта область не будет обработана при следующем сообщении WM_PAINT , или пока она не будет объявлена корректной принудительно, методом ValidateRect или ValidateRgn.
Как уже отмечалось выше, установка непустой области модификации Region не заставляет приложение немедленно перерисоваться. Вместо этого, приложение продолжает получать сообщения из очереди, пока все сообщения не будут обработаны. Затем Windows проверяет область модификации, и если область не пустая, посылает сообщение WM_PAINT окну. При проверке области модификации могут быть посланы так же сообщения WM_NCPAINT и WM_ERASEBKGND, если требуется перерисовать рамку ( неклиентскую часть) окна или необходимо очистить окно.
Например, при увеличении размера окна будут посланы все три сообщения : WM_NCPAINT , WM_ERASEBKGND и WM_PAINT. При уменьшении размеров, окну придет только два сообщения из этой группы, сообщение WM_NCPAINT и WM_ERASEBKGND. По смыслу ситуации это резонно - при уменьшении окна клиентская часть его только урезается, следовательно стереть ее надо, а рисовать, вообще говоря, нечего...
[pagebreak]
Метод Window требует немедленной перерисовки клиентской области в обход общей очереди. Предварительно проверяется состояние области модификации: если область модификации не пустая, окну будет послано сообщение WM_PAINT. Если область модификации пуста сообщение WM_PAINT, наоборот, не будет послано.
Если эта область была помечена для стирания, то окну предварительно будет послано сообщение WM_ERASEBKGND.
Для получения более подробной информации смотрите Help WinAPI по темам:
Все вышеперечисленные методы являются методами класса CWnd, доступного через WinAPI.
Для перерисовки окон в Delphi применяются два метода :
Метод RePaint заключается в объявлении всей области окна как некорректной и немедленного запроса на перерисовавание окна. Достаточно привести реализацию этого метода из модуля Controls.pas, чтобы это увидеть:
Метод Refresh является модификацией метода RePaint. Для класса TWinControl метод Refresh повторяет вызов RePaint.
Таким образом, если Вам необходимо немедленно обновить окно, воспользуйтесь методом RePaint, если в этом нет необходимости и перерисовку нужно запросить, но в порядке общей очереди, лучше использовать метод Invalidate;
Для получения более подробной информации смотрите реализацию методов:
* TWinControl.Invalidate
* TWinControl.
* метод Refresh для разных компонент, наследников от TWinControl.
В этой статье будут рассмотрены некоторые функции для работы с окнами.
Функция 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 в противном случае.