Введение
Delphi — это среда быстрой разработки, в которой в качестве языка программирования используется язык Delphi. Язык Delphi — строго типизированный объектно-ориентированный язык, в основе которого лежит хорошо знакомый программистам Object Pascal.
На сегодняшний день позволяет разрабатывать ПО для Microsoft Windows, Mac OS, iOS и Android и входит в состав Embarcadero RAD Studio.
- Подробности
- Категория: Введение
Автор: Алексей Федоров
Реестр - это центральное хранилище информации о параметрах системы и установленных программах. В версиях Windows до Windows 95 программисты сохраняли параметры программ либо в INI-файлах WIN.INI и SYSTEM.INI, либо в дополнительных INI-файлах. Хотя использование INI-файлов поддерживается и в Win32, Microsoft настоятельно рекомендует для хранения необходимых в работе программы параметров пользоваться реестром. Реестр представляет собой иерархическую базу данных, cостоящую из секций, подсекций и элементов. Каждая секция имеет свое назначение. Хранить данные о пользовательских программах Microsoft рекомендует в секции HKEY_CURRENT_USER и подсекции Software. В этой подсекции вы создаете подсекцию, идентифицирующую вашу программу или фирму, и уже внутри нее располагаете данные.
Модуль Registry
Для упрощения работы с регистратором в состав Delphi (начиная с версии 2.0) входит модуль REGISTRY, содержащий реализацию трех классов, - TRegistry, TRegistryIniFile и TRegIniFile.
Внимание! Чтобы использовать свойства и методы классов TRegistry, TRegistryIniFile и TRegIniFile, необходимо включить в список uses модуль Registry.
TRegIniFile
Собственно говоря, задача класса TRegIniFile - упростить перенос 16-битных программ в среду Windows 95. Методы этого класса эквивалентны методам класса TIniFile в 16-битной версии Delphi. Класс TRegIniFile позволяет обращаться к секции HKEY_CURRENT_USER, считывать и записывать строки (методы ReadString и WriteString), целочисленные значения (методы ReadInteger и WriteInteger), логические значения (методы ReadBool и WriteBool), секции (методы ReadSection, ReadSections и ReadSectionValues), удалять секции (метод EraseSection) и элементы (метод DeleteKey). Рассмотрим на примерах, как используются функции этого класса.
Microsoft рекомендует записывать данные, относящиеся к вашей программе, в подсекции секции HKEY_CURRENT_USER_Software. Предположим (не особенно фантазируя на эту тему), что ваша программа называется RegDemo, и данные для нее располагаются в секции Software\RegDemo. Ниже мы покажем, как поместить в регистратор строчные, целочисленные и логические данные, а затем считать их, - этих операций будет достаточно для того, чтобы сохранить в регистраторе параметры нашей программы, а затем считать их.
Прежде чем записать данные в определенную секцию, ее необходимо создать. Это происходит при вызове конструктора объекта TRegIniFile. В качестве параметра вы указываете название секции, и если таковой не существует, она создается:
RegFile := TRegIniFile.Create(SubKey);
После того как файл регистратора открыт (и создана определенная секция), мы можем записать данные. Поддерживаются три типа данных: целочисленные, логические и строчные данные. Для записи этих данных существуют методы WriteInteger, WriteBool и WriteString. В качестве параметров указываются:
· | название подсекции; |
· | название элемента; |
· | записываемые данные. |
Так, чтобы записать значение элемента MyIntVal в подсекции IntKey, следует выполнить код
RegFile.WriteInteger(IntKey, 'Int_Val', 32000);
а для того чтобы прочесть значение, необходимо вызвать метод ReadInteger (в качестве параметров указываются название подсекции, название элемента и значение по умолчанию):
RegFile.ReadInteger(IntKey, 'Int_Val', 0));
Для чтения логических и строчных данных используются соответственно методы ReadBool и ReadStr, а для их записи – методы WriteBool и WriteString.
Расссмотрим пример использования перечисленных выше методов класса TRegIniFile. Расположим в форме компонент Memo, две группы GroupBox и шесть кнопок – три в группе Write и три в группе Read. Нажатие каждой кнопки в группе Write приведет к записи соответствующего значения в реестр, нажатие каждой кнопки в группе Read – к чтению этого значения.
Ниже приведен исходный текст модуля, в котором содержатся обработчики нажатия кнопок, использующие методы класса TRegIniFile.
Code: |
unit RDUnit; interfaceuses Windows, Messages, SysUtils, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls, Registry; type TForm1 = class(TForm) Memo1: TMemo; GroupBox1: TGroupBox; GroupBox2: TGroupBox; Label1: TLabel; Button1: TButton; Button2: TButton; Button3: TButton; Button4: TButton; Button5: TButton; Button6: TButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); procedure Button5Click(Sender: TObject); procedure Button6Click(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation{$R *.DFM}var RegFile: TRegIniFile; const //Подсекция SubKey: string = 'Software\RegDemo'; // Элемент для хранения логических данных BoolKey: string = 'BoolKey'; // Элемент для хранения целочисленных данных IntKey: string = 'IntKey'; // Элемент для хранения строчных данных StrKey: string = 'StrKey';
procedure TForm1.FormCreate(Sender: TObject); begin // Создать экземпляр класса RegFile := TRegIniFile.Create(SubKey); end;
procedure TForm1.Button1Click(Sender: TObject); begin // Записать целочисленное значение RegFile.WriteInteger(IntKey, 'Value', 1998); end;
procedure TForm1.Button2Click(Sender: TObject); begin // Записать булево значение RegFile.WriteBool(BoolKey, 'Value', True); end;
procedure TForm1.Button3Click(Sender: TObject); begin // Записать строку RegFile.WriteString(StrKey, 'Value', 'Demo'); end;
procedure TForm1.Button4Click(Sender: TObject); begin // Считать целочисленное значение Memo1.Lines.Add('Int Value = ' + IntToStr(RegFile.ReadInteger(IntKey, 'Value', 0))); end;
procedure TForm1.Button5Click(Sender: TObject); begin // Считать булево значение if RegFile.ReadBool(BoolKey, 'Value', False) then Memo1.Lines.Add('Bool Value = True') else Memo1.Lines.Add('Bool Value = False'); end;
procedure TForm1.Button6Click(Sender: TObject); begin // Считать строку Memo1.Lines.Add(RegFile.ReadString(StrKey, 'Value', '')); end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin // Удалить секцию RegFile.EraseSection(SubKey); // Освободить память RegFile.Free; end; end. |
На приведенном ниже рисунке показано, как выглядит созданная нами подсекция в редакторе REGEDIT.
Отметим, что рассмотренных выше функций вполне достаточно для того чтобы обеспечить минимальную функциональность приложения. Если же вам требуется читать и записывать данные из других секций реестра, вы можете воспользоваться методами класса TRegistry или (что мене удобно) непосредственно функциями Win32 API.
Класс TRegistry
Прежде чем рассмотреть пример использования свойств и методов класса TRegistry, давайте кратко перечислим их.
В следующей таблице перечислены свойства класса TRegistry.
Свойство |
Описание |
CurrentKey |
Позволяет узнать текущую подсекцию, в которой проводятся операции по чтению и записи. Для изменения подсекции следует использовать методы OpenKey и OpenKeyReadOnly |
CurrentPath |
Позволяет узнать полное название текущей подсекции |
LazyWrite |
Задает способ обновления информации в реестре – непосредственно или после вызова метода CloseKey. |
RootKey |
Задает корневую секцию в реестре. По умолчанию установлено значение HKEY_CURRENT_USER |
В следующей таблице перечислены методы класса TRegistry.
Метод |
Описание |
CloseKey |
Записывает внесенные изменения и закрывает текущую подсекцию |
Create |
Создает экземпляр класса TRegistry и задает значение корневой секции - HKEY_CURRENT_USER |
CreateKey |
Создает подсекцию |
DeleteKey |
Удаляет подсекцию |
DeleteValue |
Удаляет значение элемента |
Destroy |
Уничтожает ранее созданный экземпляр класса TRegistry |
GetDataInfo |
Возвращает тип данных для указанного элемента |
GetDataSize |
Возвращает размер данных для указанного элемента |
GetDataType |
Возвращает тип данных для указанного элемента |
GetKeyInfo |
Возвращает информацию о текущем элементе |
GetKeyNames |
Возвращает имена подсекций для указанной секции |
GetValueNames |
Возвращает названия элементов для указанной подсекции |
HasSubKeys |
Позволяет узнать, имеются ли подсекции для указанной секции |
KeyExists |
Позволяет узнать, существует ли элемент |
LoadKey |
Создает новую подсекцию и загружает в нее информацию из указанного файла |
MoveKey |
Перемещает указанную подсекцию и все вложенные подсекции в заданное место |
OpenKey |
Открывает подсекцию |
OpenKeyReadOnly |
Открывает подсекцию только для чтения |
ReadBinaryData |
Считывает данные в бинарном формате |
ReadBool |
Считывает данные в булевом формате |
ReadCurrency |
Считывает данные в формате валюты |
ReadDate |
Считывает данные в формате даты |
ReadDateTime |
Считывает данные в формате “дата/время” |
ReadFloat |
Считывает данные в формате с плавающей точкой |
ReadInteger |
Считывает данные в целочисленном формате |
ReadString |
Считывает данные в строчном формате |
ReadTime |
Считывает данные в формате времени |
RegistryConnect |
Устанавливает соединение с реестром на другом компьютере |
RenameValue |
Переименовывает элемент |
ReplaceKey |
Замещает значение элемента значениями из файла |
RestoreKey |
Восстанавливает значение элемента из файла |
SaveKey |
Сохраняет значение элемента в файле |
UnLoadKey |
Удаляет подсекцию, загруженную методом LoadKey |
ValueExists |
Позволяет узнать, существует ли значение у элемента |
WriteBinaryData |
Записывает данные в бинарном формате |
WriteBool |
Записывает данные в булевом формате |
WriteCurrency |
Записывает данные в формате валюты |
WriteDate |
Записывает данные в формате даты |
WriteDateTime |
Записывает данные в формате “дата/время” |
WriteExpandString |
Записывает данные в формате "расширенно" строки |
WriteFloat |
Записывает данные в формате с плавающей точкой |
WriteInteger |
Записывает данные в целочисленном формате |
WriteString |
Записывает данные в строчном формате |
WriteTime |
Записывает данные в формате времени |
После того как мы кратко познакомились со свойствами и методами класса TRegistry, давайте рассмотрим несколько примеров их использования.
Инициализация
Перед использованием свойств и методов класса TRegistry, необходимо создать экземпляр этого класса. Например:
Code: |
var R: TRegistry; ...R := TRegistry.Create; |
Задание корневой секции
Если вы собираетесь работать с секцией, отличной от HKEY_CURRENT_USER (это значение задается по умолчанию), то после инициализации вы должны изменить значение свойства RootKey. Возможны следующие значения:
Code: |
HKEY_CLASSES_ROOT HKEY_CURRENT_USER HKEY_LOCAL_MACHINE HKEY_USERS HKEY_PERFORMANCE_DATA HKEY_CURRENT_CONFIG HKEY_DYN_DATA |
Например:
Code: |
with R do begin RootKey := HKEY_LOCAL_MACHINE; // // Продолжаем работу с реестром // end; |
- Подробности
- Категория: Введение
В Windows нет разделения каналов записи по источникам.
CD-ROM ----------|
| |--- Динамики
Микрофон --------| |
|-- Windows --|--- Записывающие программы
Линейный вход ---| |
| |--- Линейный выход
MIDI ------------|
Все поступающие в систему звуки смешиваются, и лишь после этого их получает программа.
Для получения звукового сигнала нужно воспользоваться WinAPI.
WaveInOpen открывает доступ к микрофону.
Одновременно только одна программа может работать с микрофоном.
Заодно Вы указываете, какая нужна частота, сколько бит на значение и размер буфера.
От последнего зависит, как часто и в каком объеме информация будет поступать в программу.
Далее нужно выделить память для буфера и вызвать функцию WaveInAddBuffer,
которая передаст Windows пустой буфер.
После вызова WaveInStart Windows начнет заполнять буфер,
и, после его заполнения, пошлет сообщение MM_WIM_DATA.
В нем нужно обработать полученную информацию и вновь вызвать WaveInAddBuffer,
тем самым указав, что буфер пуст.
Функции WaveInReset и WaveInClose прекратят поступление информации в программу и закроют доступ к микрофону.
Эта программа считывает сигнал с микрофона и выводит его на экран.
Частота сигнала - 22050 Гц. Количество бит определяется флажком, размер буфера TrackBar-ом.
Code: |
unit Unit1;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls, MMSystem;
type TData8 = array [0..127] of byte; PData8 = ^TData8; TData16 = array [0..127] of smallint; PData16 = ^TData16; TPointArr = array [0..127] of TPoint; PPointArr = ^TPointArr; TForm1 = class(TForm) Button1: TButton; Button2: TButton; PaintBox1: TPaintBox; TrackBar1: TTrackBar; CheckBox1: TCheckBox; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure CheckBox1Click(Sender: TObject); procedure FormCreate(Sender: TObject); private { Private declarations } public procedure OnWaveIn(var Msg: TMessage); message MM_WIM_DATA; end;
var Form1: TForm1;
implementation
{$R *.DFM}
var WaveIn: hWaveIn; hBuf: THandle; BufHead: TWaveHdr; bufsize: integer; Bits16: boolean; p: PPointArr; stop: boolean = false;
procedure TForm1.Button1Click(Sender: TObject); var header: TWaveFormatEx; BufLen: word; buf: pointer; begin BufSize := TrackBar1.Position * 500 + 100; { Размер буфера } Bits16 := CheckBox1.Checked; with header do begin wFormatTag := WAVE_FORMAT_PCM; nChannels := 1; { количество каналов } nSamplesPerSec := 22050; { частота } wBitsPerSample := integer(Bits16) * 8 + 8; { 8 / 16 бит } nBlockAlign := nChannels * (wBitsPerSample div 8); nAvgBytesPerSec := nSamplesPerSec * nBlockAlign; cbSize := 0; end; WaveInOpen(Addr(WaveIn), WAVE_MAPPER, addr(header), Form1.Handle, 0, CALLBACK_WINDOW); BufLen := header.nBlockAlign * BufSize; hBuf := GlobalAlloc(GMEM_MOVEABLE and GMEM_SHARE, BufLen); Buf := GlobalLock(hBuf); with BufHead do begin lpData := Buf; dwBufferLength := BufLen; dwFlags := WHDR_BEGINLOOP; end; WaveInPrepareHeader(WaveIn, Addr(BufHead), sizeof(BufHead)); WaveInAddBuffer(WaveIn, addr(BufHead), sizeof(BufHead)); GetMem(p, BufSize * sizeof(TPoint)); stop := true; WaveInStart(WaveIn); end;
procedure TForm1.Button2Click(Sender: TObject); begin if stop = false then Exit; stop := false; while not stop do Application.ProcessMessages; stop := false; WaveInReset(WaveIn); WaveInUnPrepareHeader(WaveIn, addr(BufHead), sizeof(BufHead)); WaveInClose(WaveIn); GlobalUnlock(hBuf); GlobalFree(hBuf); FreeMem(p, BufSize * sizeof(TPoint)); end;
procedure TForm1.OnWaveIn; var i: integer; data8: PData8; data16: PData16; h: integer; XScale, YScale: single; begin h := PaintBox1.Height; XScale := PaintBox1.Width / BufSize; if Bits16 then begin data16 := PData16(PWaveHdr(Msg.lParam)^.lpData); YScale := h / (1 shl 16); for i := 0 to BufSize - 1 do p^[i] := Point(round(i * XScale), round(h / 2 - data16^[i] * YScale)); end else begin Data8 := PData8(PWaveHdr(Msg.lParam)^.lpData); YScale := h / (1 shl 8); for i := 0 to BufSize - 1 do p^[i] := Point(round(i * XScale), round(h - data8^[i] * YScale)); end; with PaintBox1.Canvas do begin Brush.Color := clWhite; FillRect(ClipRect); Polyline(Slice(p^, BufSize)); end; if stop then WaveInAddBuffer(WaveIn, PWaveHdr(Msg.lParam), SizeOf(TWaveHdr)) else stop := true; end;
procedure TForm1.FormDestroy(Sender: TObject); begin Button2.Click; end;
procedure TForm1.CheckBox1Click(Sender: TObject); begin if stop then begin Button2.Click; Button1.Click; end; end;
procedure TForm1.FormCreate(Sender: TObject); begin TrackBar1.OnChange := CheckBox1Click; Button1.Caption := 'Start'; Button2.Caption := 'Stop'; CheckBox1.Caption := '16 / 8 bit'; end;
end. |
Даниил Карапетян.
- Подробности
- Категория: Введение
Все потомки TComponent могут посылать сообщения CM_MOUSEENTER и CM_MOUSELEAVE во время вхождения и покидания курсора мыши области компонента. Если вам необходимо, чтобы ваши компоненты обладали реакцией на эти события, необходио написать для них соответствующие обработчики.
Code: |
procedure CMMouseEnter(var msg:TMessage); message CM_MOUSEENTER; procedure CMMouseLeave(var msg: TMessage); message CM_MOUSELEAVE; .. .. .. procedure MyComponent.CMMouseEnter(var msg:TMessage); begin
inherited; {действия на вход мыши в область компонента} end;
procedure MyComponent.CMMouseLeave(var msg: TMessage); begin
inherited; {действия на покидание мыши области компонента} end; |
Дополнение
Часто приходится сталкиваться с ситуацией, когда необходимо обработать два важных события для визуальных компонентов:
MouseEnter - когда событие мыши входит в пределы визуального компонента;
MouseLeave - когда событие мыши оставляет его пределы.
Известно, что все Delphi объявляет эти сообщения в виде:
Cm_MouseEnter;
Cm_MouseLeave.
Т.е. все визуальные компоненты, которые порождены от TControl, могут отлавливать эти события. Следующий пример показывает как создать наследника от TLabel и добавить два необходимых события OnMouseLeave и OnMouseEnter.
Code: |
(*///////////////////////////////////////////////////////*) (*// Author: Briculski Serge (*// E-Mail: Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра. (*// Date: 26 Apr 2000 (*///////////////////////////////////////////////////////*)
unit BS_Label;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type TBS_Label = class(TLabel) private { Private declarations } FOnMouseLeave: TNotifyEvent; FOnMouseEnter: TNotifyEvent; procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER; procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE; protected { Protected declarations } public { Public declarations } published { Published declarations } property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave; property OnMouseEnter: TNotifyEvent read FOnMouseEnter write FOnMouseEnter; end;
procedure Register;
implementation
procedure Register; begin RegisterComponents('Custom', [TBS_Label]); end;
{ TBS_Label }
procedure TBS_Label.CMMouseEnter(var Message: TMessage); begin if Assigned(FOnMouseEnter) then FOnMouseEnter(Self); end;
procedure TBS_Label.CMMouseLeave(var Message: TMessage); begin if Assigned(FOnMouseLeave) then FOnMouseLeave(Self); end;
end. |
- Подробности
- Категория: Введение