Отправляет email-рассылки с помощью сервиса Sendsay

Программирование на Delphi

  Все выпуски  

Программирование на DELPHI в вопросах и ответах #5


Информационный Канал Subscribe.Ru

Программирование на Delphi в вопросах и ответах.


Здравствуйте, уважаемые читатели! Перед вами выпуск №5 от 27.11.04.

Текущий (пятый) выпуск рассылки вышел несколько "не в срок". Хотя объявленная периодичность рассылки - один раз в неделю, выходить она, может быть, будет гораздо чаще. Всё зависит от вашей активности, господа! Вот со вчерашнего дня пришло много писем с ответами на вопросами, пожеланиями, а также ответами на предложенное голосование. Видимо, ещё не все читатели получили 4-ый выпуск, поэтому голосование продолжается. Оценив присланные ответы, стало ясно, что требуются ещё некоторые варианты. В связи с этим добавились новые ответы.

Программы какого направления вы создаёте?

>>> Для работы с текстом
>>> Мультимедийные приложения
>>> Приложения, основанные на WinAPI (интегрирующиеся с операционной системой)
>>> Системные утилиты
>>> Программы другого типа (пожалуйста, укажите, какие именно в тексте письма)
>>> Программы для работы с графикой
>>> БД (Базы Данных)
>>> Сетевые приложения

Также вы можете выбрать несколько вариантов ответа, но выбирайте те, что действительно "преобладают" над другими.

Очень прошу проголосовать всех читателей рассылки.

Правила нашей рассылки:
1. Не присылайте ответов на вопросы вроде "да я не знаю" или "да/нет". Такие ответы не публикуются.
2. Вопросы, не касающиеся Delphi, не принимаются (для этого существуют другие рассылки).
3. Запрещено присылать вложенные файлы! Автор вопроса сам свяжется с вами!
4. Письма с "неправильной" темой не публикуются!


Статья по Delphi.

Работа с реестром в Delphi.

Реестр

Добавление элементов в контекстное меню "Создать"
1. Создать новый документ, поместить его в папку Windows/ShellNew
2. В редакторе реестра найти расширение этого файла, добавить новый подключ, добавить туда строку: FileName в качестве значения которой указать имя созданного файла.

Путь к файлу который открывает не зарегистрированные файлы
1. Найти ключ HKEY_CLASSES_ROOT\Unknown\Shell
2. Добавить новый ключ Open
3. Под этим ключом еще ключ с именем command в котором изменить значение (По умолчанию) на имя запускаемого файла, к имени нужно добавить %1. (Windows заменит этот символ на имя запускаемого файла)

В проводнике контекстное меню "Открыть в новом окне"
1. Найти ключ HKEY_CLASSES_ROOT\Directory\Shell
2. Создать подключ: opennew в котором изменить значение (По умолчанию) на: "Открыть в новом окне"
3. Под этим ключом создать еще подключ command (По умолчанию) = explorer %1

Использование средней кнопки мыши Logitech в качестве двойного щелчка
Подключ HKEY_LOCAL_MACHINE\SoftWare\Logitech и там найти параметр DoubleClick заменить 000 на 001

Новые звуковые события
Например создает звуки на запуск и закрытие WinWord
HKEY_CURRENT_USER\AppEvents\Shemes\Apps добавить подключ WinWord и к нему подключи Open и Close.
Теперь в настройках звуков видны новые события

Путь в реестре для деинсталяции программ:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall

Работа с реестром в Delphi

В Delphi есть объект TRegistry при помощи которого очень просто работать с реестром.
Реестр предназначен для хранения системных переменных и позволяет зарегистрировать файлы программы, что обеспечивает их показ в проводнике с соответствующей иконкой, вызов программы при щелчке на этом файле, добавление ряда команд в меню, вызываемое при нажатии правой кнопки мыши над файлом. Кроме того, в реестр можно внести некую свою информацию (переменные, константы, данные о инсталлированной программы ...). Программу можно добавить в список деинсталляции, что позволит удалить ее из менеджера "Установка/Удаление программ" панели управления.
Для работы с реестром применяется ряд функций API :

RegCreateKey (Key: HKey; SubKey: PChar; var Result: HKey): Longint;
Создать подраздел в реестре. Key указывает на "корневой" раздел реестра, в SubKey - имя раздела - строится по принципу пути к файлу в DOS (пример subkey1\subkey2\ ...). Если такой раздел уже существует, то он открывается (в любом случае при успешном вызове Result содержит Handle на раздел). Об успешности вызова судят по возвращаемому значению, если ERROR_SUCCESS, то успешно, если иное - ошибка.

RegOpenKey(Key: HKey; SubKey: PChar; var Result: HKey): Longint;
Открыть подраздел Key\SubKey и возвращает Handle на него в переменной Result. Если раздела с таким именем нет, то он не создается. Возврат - код ошибки или ERROR_SUCCESS, если успешно.

RegCloseKey(Key: HKey): Longint;
Закрывает раздел, на который ссылается Key. Возврат - код ошибки или ERROR_SUCCESS, если успешно.
RegDeleteKey(Key: HKey; SubKey: PChar): Longint;
Удалить подраздел Key\SubKey. Возврат - код ошибки или ERROR_SUCCESS, если нет ошибок.

RegEnumKey(Key: HKey; index: Longint; Buffer: PChar;cb: Longint): Longint;
Получить имена всех подразделов раздела Key, где Key - Handle на открытый или созданный раздел (см. RegCreateKey и RegOpenKey), Buffer - указатель на буфер, cb - размер буфера, index - индекс, должен быть равен 0 при первом вызове RegEnumKey. Типичное использование - в цикле While, где index увеличивается до тех пор, пока очередной вызов RegEnumKey не завершится ошибкой (см. пример).

RegQueryValue(Key: HKey; SubKey: PChar; Value: PChar; var cb: Longint): Longint;
Возвращает текстовую строку, связанную с ключом Key\SubKey.Value - буфер для строки; cb- размер, на входе - размер буфера, на выходе - длина возвращаемой строки. Возврат - код ошибки.

RegSetValue(Key: HKey; SubKey: PChar; ValType: Longint; Value: PChar; cb: Longint): Longint;
Задать новое значение ключу Key\SubKey, ValType - тип задаваемой переменной, Value - буфер для переменной, cb - размер буфера. В Windows 3.1 допустимо только Value=REG_SZ. Возврат - код ошибки или ERROR_SUCCESS, если нет ошибок.

Примеры :

{ Создаем список всех подразделов указанного раздела }

procedure TForm1.Button1Click(Sender: TObject);

var

MyKey: HKey;{ Handle для работы с разделом }

Buffer: array[0..1000] of char; { Буфер }

Err, { Код ошибки }

index: longint; { Индекс подраздела }

begin

Err:=RegOpenKey(HKEY_CLASSES_ROOT,'DelphiUnit',MyKey); { Открыли раздел }

if Err<> ERROR_SUCCESS then

begin

MessageDlg('Нет такого раздела !!',mtError,[mbOk],0);

exit;

end;

index:=0;

{Определили имя первого подраздела }

Err:=RegEnumKey(MyKey,index,Buffer,Sizeof(Buffer));

while err=ERROR_SUCCESS do { Цикл, пока есть подразделы }

begin

memo1.lines.add(StrPas(Buffer)); { Добавим имя подраздела в список }

inc(index); { Увеличим номер подраздела }

Err:=RegEnumKey(MyKey,index,Buffer,Sizeof(Buffer)); { Запрос }

end;

RegCloseKey(MyKey); { Закрыли подраздел }

end;

Объект INIFILES - работа с INI файлами.

Почему иногда лучше использовать INI-файлы, а не реестр?
1. INI-файлы можно просмотреть и отредактировать в обычном блокноте.
2. Если INI-файл хранить в папке с программой, то при переносе папки на другой компьютер настройки сохраняются. (Я еще не написал ни одной программы, которая бы не поместилась на одну дискету :)
3. Новичку в реестре можно запросто запутаться или (боже упаси), чего-нибудь не то изменить.
Поэтому для хранения параметров настройки программы удобно использовать стандартные INI файлы Windows. Работа с INI файлами ведется при помощи объекта TIniFiles модуля IniFiles. Краткое описание методов объекта TIniFiles дано ниже.

Constructor Create('d:\test.INI');
Создать экземпляр объекта и связать его с файлом. Если такого файла нет, то он создается, но только тогда, когда произведете в него запись информации.

WriteBool(const Section, Ident: string; Value: Boolean);
Присвоить элементу с именем Ident раздела Section значение типа boolean

WriteInteger(const Section, Ident: string; Value: Longint);
Присвоить элементу с именем Ident раздела Section значение типа Longint

WriteString(const Section, Ident, Value: string);
Присвоить элементу с именем Ident раздела Section значение типа String

ReadSection (const Section: string; Strings: TStrings);
Прочитать имена всех корректно описанных переменных раздела Section (некорректно описанные опускаются)

ReadSectionValues(const Section: string; Strings: TStrings);
Прочитать имена и значения всех корректно описанных переменных раздела Section. Формат :
имя_переменной = значение

EraseSection(const Section: string);
Удалить раздел Section со всем содержимым

ReadBool(const Section, Ident: string; Default: Boolean): Boolean;
Прочитать значение переменной типа Boolean раздела Section с именем Ident, и если его нет, то вместо него подставить значение Default.

ReadInteger(const Section, Ident: string; Default: Longint): Longint;
Прочитать значение переменной типа Longint раздела Section с именем Ident, и если его нет, то вместо него подставить значение Default.

ReadString(const Section, Ident, Default: string): string;
Прочитать значение переменной типа String раздела Section с именем Ident, и если его нет, то вместо него подставить значение Default.

Free;
Закрыть и освободить ресурс. Необходимо вызвать при завершении работы с INI файлом

Property Values[const Name: string]: string;
Доступ к существующему параметру по имени Name

Пример :

Procedure TForm1.FormClose(Sender: TObject);

var

IniFile:TIniFile;

begin

IniFile := TIniFile.Create('d:\test.INI'); { Создали экземпляр объекта }

IniFile.WriteBool('Options', 'Sound', True); { Секция Options: Sound:=true }

IniFile.WriteInteger('Options', 'Level', 3); { Секция Options: Level:=3 }

IniFile.WriteString('Options' , 'Secret password', Pass);

{ Секция Options: в Secret password записать значение переменной Pass }

IniFile.ReadSection('Options ', memo1.lines); { Читаем имена переменных}

IniFile.ReadSectionValues('Options ', memo2.lines); { Читаем имена и значения }

IniFile.Free; { Закрыли файл, уничтожили объект и освободили память }

end;


Новые вопросы:

Поступили ответы абсолютно на все вопросы. Новых вопросов пока что нет. Задавайте их.


Поступившие ответы:

2. (Выделение отдельных строк ListView разным цветом). [Отвечает: Eugene the Monster]. 1. Смотри события OnCustomDraw, OnCustomDrawItem и сам рисуй клетку как хочешь, хоть картинки туда суй. 2. Смотри компоненты 3-х фирм, например JEDI - возможностей >>> чем у простого VCL.

4. (Изменение и восстановление параметров экрана). [Отвечает: Садовников Владимир]. Воспользуйся DirectDraw - самое простое, на мой взгляд.

5. (Создание XP-стиля в программах Delphi). [Отвечает: Садовников Владимир]. Есть довольно много всяких компонент для Delphi в стиле XP: типа XPComPack, XPControls и т.д., которые умные люди написали сразу же после выхода ХП. Остаётся только поискать в Интернете такие компоненты и установить себе на Delphi. Делается это легко, и обычно описано в архиве с исходниками.

6. ("Case key of" и массивы). [Отвечает: Садовников Владимир]. На самом деле, всё элементарно. Если используешь OnKeyPress, то параметр Key содержит в себе обычные и управляющие символы ASCII. Вот некоторые из них:
#9 - Tab
#8 - Backspace
#13 - Enter
#27 - Escape и т.д. Экспериментируй, и всё получится.
После того, как клавиша была отловлена, переменную Key не следует изменять, если предполагается дальнейшая реакция системы, или обнулить, если эта клавиша ловится только нашим обработчиком. Короткий пример:

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
case Key of
#9: Key:=#0; //Запрещаем какую-либо реакцию на клавишу Tab
#27: Close; //Выходим по клавише Escape из программы
end;
end;

Если требуется отловить нажатие клавиш Alt, Shift и Ctrl, то тут уже надо воспользоваться событием OnKeyDown/OnKeyUp. Тогда клавиши определяются константами типа VK_LEFT, VK_RIGHT, VK_UP, VK_DOWN и т.д., а клавиши Alt, Shift и Ctrl содержатся в отдельной переменной Shift.

Пример: выводим сообщение по нажатию клавиш Ctrl+Alt+F1:

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if (Key=VK_F1) and (ssAlt in Shift) and (ssCtrl in shift) then
MessageBox(Handle,'Ctrl+Alt+F1 pressed!','',MB_OK);
end;

Массивы - простая вещь тоже.

var
I:array [0..10,0..20] of Integer; - так описывается двумерный массив 11x21, каждый элемент которого имеет тип Integer.

Динамические массивы объявляются без индекса.

var
I:array of Integer;

begin
SetLength(I,20); //делаем массив длиной в 20 элементов (нумерация от 0 до 19).
I[5]:=0; //записываем в пятый (нумерация с нуля) элемент массива число 0.
I:=nil; //освобождаем память, выделенную под массив.
end.

И на закуску: создание треугольного массива.

var
A:array of array of Integer;
I:Integer;
begin
SetLength(A,10); //10 столбцов
for I:=0 to 9 do
SetLength(A[I],I+1); //в каждом столбце количество строчек равно номеру столбца плюс один
...
end.

Вы также можете ответить на предыдущие вопросы. Поскольку на них уже ответили как минимум раз, они больше не публикуются в рассылке. Но если вы можете что-то добавить к ответам других, пожалуйста, отвечайте - ответы будут опубликованы. Найти предыдущие вопросы вы можете в архиве рассылки: http://subscribe.ru/archive/comp.soft.prog.delphifaq/, либо на сайте рассылки (http://www.delphi-faq.fatal.ru). Примечание: на текущий момент на сайте ещё нет всех поступивших ответов, но они там появятся в ближайшее время.


Друзья:

Здесь представлены ссылки на дружественные сайты нашего портала. Если вы тоже хотите стать нашим другом, разместите баннер на главной странице своего сайта и напишите нам об этом. После этого ссылка на ваш сайт появится в данном разделе вместе с тем описанием, которое вы пришлёте. О вашем портале узнают все читатели!

http://infomania2004.webhost.ru/ - Этот сайт создан для того, чтобы вы могли получить интересующую вас информацию с минимальными затратами сил и времени. Если вы не нашли здесь нужной информации, вы можете оставить заявку на ее поиск. Как только информация будет найдена, она появится на сайте, а вам сообщат об этом.
http://www.nod33.narod.ru/ - Программы, приколы, песни и т. д. - сайт для всех!
http://www.basic.webhost.ru/ - Программирование на языках Basic и Visual Basic.

Код баннера:

<A HREF="http://www.delphi-faq.fatal.ru/" TARGET="_blank">
<IMG SRC="http://www.delphi-faq.fatal.ru/images/delphi.gif" ALT="Программирование на DELPHI в вопросах и ответах" WIDTH=100 HEIGHT=40 BORDER=0></A>


Юмор:

- А что такое Linux LiveCD?
- Это компакт, который вылазит по ночам из cd-rom-а, и ползает по округе, находя компакты с виндой, душит и грызет их. Утром, заметая следы взлома, возвращается обратно.

Сисадмин пытается познакомиться с девушкой:
- Привет! Что ты делаешь сегодня вечером? Может сходим в кино? Или в бар, пропустим по кружечке?
На что получает отрицательный ответ. Вздохнув:
- Стандартные драйвера не подошли.

Программист на ночь себе ставит два стакана возле кровати. Один с водой - на случай, если захочет пить, другой без воды - на случай, если не захочет.

Первое правило сисадмина: 'Лежаший на столе винчестер с данными выглядит точно так же, как и винчестер без данных'.

- Я у вас компьютеp купил. Так он сдох.
- Гаpантия какая?
- Пожизненная.
- Раз сдох - гаpантия кончилась.

Присылайте свои "компьютерные" анекдоты по этой ссылке: delphi-faq@list.ru и они обязательно будут опубликованы!


Товарищи программисты! Проявляйте свою активность. Давайте помогать друг другу!
Если вы не нашли ответа на свой вопрос, не отчаивайтесь! Ведь количество подписчиков постоянно растёт и, наверняка, найдётся тот человек, который поможет вам!
На сегодня всё. До встречи через неделю!

Сайт рассылки: http://www.delphi-faq.fatal.ru E-mail: Delphi-FAQ@list.ru


http://subscribe.ru/
http://subscribe.ru/feedback/
Подписан адрес:
Код этой рассылки: comp.soft.prog.delphifaq
Отписаться

В избранное