Сайту требуются администраторы и авторы статей. С предложениями пишите на rock-n-roll@tut.by.
26 января 2008

Delphi: ComboBox в ячейке StringGrid

 ComboBox в ячейке StringGrid

procedure TForm1.FormCreate(Sender: TObject);
begin
{Высоту combobox'а не изменишь, так что вместо combobox'а
будем изменять высоту строки grid'а !}

StringGrid1.DefaultRowHeight := ComboBox1.Height; {Спрятать combobox}
ComboBox1.Visible := False; ComboBox1.Items.Add('Delphi Kingdom');
ComboBox1.Items.Add('Королевство Дельфи');
end;

procedure TForm1.ComboBox1Change(Sender: TObject);
begin
{Перебросим выбранное в значение из ComboBox в grid}
StringGrid1.Cells[StringGrid1.Col,
StringGrid1.Row] := ComboBox1.Items[ComboBox1.ItemIndex];
ComboBox1.Visible := False; StringGrid1.SetFocus;
end;

procedure TForm1.ComboBox1Exit(Sender: TObject);
begin
{Перебросим выбранное в значение из ComboBox в grid}
StringGrid1.Cells[StringGrid1.Col,
StringGrid1.Row] := ComboBox1.Items[ComboBox1.ItemIndex];
ComboBox1.Visible := False; StringGrid1.SetFocus;
end;

procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol,
ARow: Integer; var CanSelect: Boolean);
var
R: TRect;
begin
if ((ACol = 3) and (ARow <> 0)) then
begin
{Ширина и положение ComboBox должно соответствовать ячейке StringGrid}
R := StringGrid1.CellRect(ACol, ARow); R.Left := R.Left + StringGrid1.Left;
R.Right := R.Right + StringGrid1.Left; R.Top := R.Top + StringGrid1.Top;
R.Bottom := R.Bottom + StringGrid1.Top; ComboBox1.Left := R.Left + 1;
ComboBox1.Top := R.Top + 1; ComboBox1.Width := (R.Right + 1) - R.Left;
ComboBox1.Height := (R.Bottom + 1) - R.Top; {Покажем combobox}
ComboBox1.Visible := True; ComboBox1.SetFocus;
end;
CanSelect := True;
end;

Категория Интерфейс, Delphi | 0 CommentsВерсия для печати Версия для печати

23 января 2008

Работа с ini файлами в Delphi

Вообще, ini-файлы – очень удобная вещь. В ini-файл можно записать практически всё, хотя создан он в основном для хранения настроек программы.

Структура ini-файла очень проста: весь файл поделён на секции. В секциях содержатся ключи и эти ключи хранят значения. Вот пример открытого в блокноте ini-файла:
[Form properties]
Width=450
Height=320
Left=10
Top=35
[Application properties]
Dir=C:\Мои документы\Musuc
Date=28.09.02

В этом ини-файле, как мы видим, 2 секции: Form properties и Application properties. В каждой из этих секций есть ключи, содержащие числа, строковые выражения, дату. Запись в файл осуществляется путём указания секции ини-файла, названия ключа и указания самого значения. Ниже я опишу способы использования ини-файла на Borland Delphi.

Для работы с ини-файлами в Delphi существует модуль IniFiles. В нём описан нужный нам класс TIniFile.

1. Включите Delphi и создайте новый проект.

2. Допишите в Uses новый модуль IniFiles.

3. Создайте глобальную переменную класса TIniFile.
var
Form1: TForm1;
IniFile: TIniFile;

4. При создании формы надо инициализировать переменную IniFile:
procedure TForm1.FormCreate(Sender: TObject);
begin
IniFile:=TIniFile.Create('C:\Program files\MyApplication\MyIni.ini');
end;

Инициализация проходит с участием дополнительного параметра типа string. Это имя файла. Если имя введено не полностью, а, например, так: 'MyIni.ini', то файл создастся при записи в папке Windows. Я же рекомендую создавать файл в папке с программой (её можно узнать так: ExtractFilePath(Application.ExeName)).

5. Как осуществить запись в файл? Для записи в ини-файл есть несколько процедур у класса TIniFile - смотря что надо записать.

Процедура записи строки:
WriteString(const Section, Ident, Value: string);

Процедура записи цифры:
WriteInteger(const Section, Ident: string; Value: Longint);

Процедура записи булевого выражения:
WriteBool(const Section, Ident: string; Value: Boolean);

Запись даты:
WriteDate(const Section, Name: string; Value: TDateTime);

Запись время:
WriteTime(const Section, Name: string; Value: TDateTime);

Запись даты и время вместе:
WriteDateTime(const Section, Name: string; Value: TDateTime);

Запись не целого численного значения:
WriteFloat(const Section, Name: string; Value: Double);

Запись потока:
WriteBinaryStream(const Section, Name: string;Value: TStream);

Во всех этих функциях обязательно указывать секцию (Section), имя ключа (Name) и записываемое значение.

Для наглядности вы можете поместить на форму кнопку и по её нажатию можете прописать следующее:
procedure TForm1.Button2Click(Sender: TObject);
begin
IniFile.WriteString('Form info','Form caption',Caption);
IniFile.WriteInteger('Form info','Left',Left);
IniFile.WriteInteger('Form info','Top',Top);
IniFile.WriteInteger('Form info','Width',Width);
IniFile.WriteInteger('Form info','Height',Height);
IniFile.WriteTime('Other','Write time',Time);
end;

По выполнению этого кода программа создаст (если ещё не создан) файл в указанном при процедуре Create месте и запишет в него примерно следующее:
[Form info]
Form caption=Form1
Left=192
Top=107
Width=544
Height=375
[Other]
Write time=23:13:55

6. Процедура чтения из ини-файла осуществляется похожим способом. Для чтения существуют функции:
ReadString(const Section, Ident, Default: string): string;
ReadInteger(const Section, Ident: string; Default: Longint): Longint;
ReadBool(const Section, Ident: string; Default: Boolean): Boolean;
ReadBinaryStream(const Section, Name: string; Value: TStream): Integer;
ReadDate(const Section, Name: string; Default: TDateTime): TDateTime;
ReadDateTime(const Section, Name: string; Default: TDateTime): TDateTime;
ReadFloat(const Section, Name: string; Default: Double): Double;
ReadTime(const Section, Name: string; Default: TDateTime): TDateTime;

Каждая функция возвращает прочтённое из файла значение. Если по каким-либо причинам прочтение не удалось, то функция возвращает значение, указанное в параметре самой функции как Default.

Например, для прочтения из нашего ини-файла значения Form caption надо написать следующее:
Edit1.Text:=IniFile.ReadString('Form info',
'Form caption','Ошибка при чтении!');

В этом примере тексту помещённого на форму Edit-а присваивается прочтённое из файла значение. В нашем случае тексту Edit-а будет присвоено значение «Form1». Если чтение не удастся, то тексту Edit-а будет присвоено значение «Ошибка при чтении».

Другие процедуры и функции для работы с ини-файлами:

Проверка, существует ли секция:
function SectionExists(const Section: string): Boolean;

Прочтение всей секции:
procedure ReadSection(const Section: string; Strings: TStrings);

Прочтение всего файла (все секции записываются в Strings):
procedure ReadSections(Strings: TStrings);

Прочтение всех значений в заданной секции:
procedure ReadSectionValues(const Section: string; Strings: TStrings);

Удалить заданную секцию со всеми её значениями:
procedure EraseSection(const Section: string);

Удаление определённого ключа (и его значения) в секции:
procedure DeleteKey(const Section, Ident: String);

Проверка, существует ли заданный ключ в указанной секции:
function ValueExists(const Section, Ident: string): Boolean;

Категория Файловая система, Интерфейс, Delphi | 0 CommentsВерсия для печати Версия для печати

18 января 2008

Delphi: Округление дробных чисел

Вещественные числа, в отличие от целых чисел, хранят лишь приблизительное значение, и за рубежом используются в основном для хранения научных данных. Для хранения денежных величин обычно используются целочисленные типы данных. Однако integer как правило не хватает для хранения наших денег (особенно остро стоит эта проблема в турции, где зарплату получают миллионами турецких лир). Поэтому для денег приходится использовать вещественные числа (начиная с InterBase 6.0 и в последующих версиях InterBase/Firebird/Yaffil есть поддержка int64 или bigint в третьем диалекте).

Далее »

Категория Арифметика, Алгоритмы, Delphi | 0 CommentsВерсия для печати Версия для печати

12 января 2008

Функция SetWindowPos

Функция SetWindowPos изменяет размер, позицию и Z-последовательность дочернего, выскакивающего или верхнего уровня окна. Дочерние, выскакивающие и верхнего уровня окна размещаются по порядку согласно их появлению на экране. Самое верхнее окно принимает самый высокий ранг и становится первым окном в Z-последовательности.

Синтаксис

BOOL SetWindowPos
(
HWND hWnd,            // дескриптор окна
HWND hWndInsertAfter,        // дескриптор порядка размещения
int X,                // позиция по горизонтали
int Y,                // позиция по вертикали
int cx,                // ширина
int cy,                // высота
UINT uFlags             // флажки позиционирования окна
);

Параметры

hWnd
Идентифицирует окно.
hWndInsertAfter
Идентифицирует окно, которое предшествует установленному окну в Z-последовательности. Этот параметр должен быть дескриптор окна или одно из следующих значений:

  • HWND_BOTTOM - Помещает окно внизу Z-последовательности. Если параметр hWnd идентифицирует самое верхнее окно, окно теряет своё самое верхнее состояние и помещается внизу всех других окон.
  • HWND_NOTOPMOST - Помещает окно перед всеми не в самыми верхними окнами (то есть позади всех самых верхних окон). Этот флажок не имеет никакого влияния, если окно - уже не самое верхнее окно.
  • HWND_TOP - Помещает окно наверху Z-последовательности.
  • HWND_TOPMOST - Помещает окно перед не самыми верхними окнами. Окно сохраняет свою самую верхнюю позицию даже тогда, когда оно неактивное.

Для получения дополнительной информации о том, как использовать этот параметр, см. следующий раздел Замечания.
X
Устанавливает новую позицию с левой стороны окна.
Y
Устанавливает новую позицию верхней части окна.
cx
Устанавливает новую ширину окна, в пикселях.
cy
Устанавливает новую высоту окна, в пикселях.
uFlags
Определяет флажки, устанавливающие размеры и позиционирование окна. Этот параметр может быть комбинацией следующих значений:

  • SWP_DRAWFRAME - Выводит рамку (определенную в описании класса окна) вокруг окна.
  • SWP_FRAMECHANGED - Посылает сообщение WM_NCCALCSIZE окну, даже тогда, когда размер окна не изменяется. Если этот флажок не установлен, WM_NCCALCSIZE посылается только тогда, когда размер окна изменяется.
  • SWP_HIDEWINDOW - Скрывает окно.
  • SWP_NOACTIVATE - Не активизирует окно. Если этот флажок не установлен, окно активизируется и перемещается в верхнюю часть или самой верхней, или не самой верхней группы (в зависимости от установки параметра hWndInsertAfter).
  • SWP_NOCOPYBITS - Сбрасывает все содержание рабочей области. Если этот флажок не установлен, допустимое содержание рабочей области сохраняется и копируется обратно в рабочую область после того, как окно установлено по размеру или переустановлено.
  • SWP_NOMOVE - Сохраняет текущую позицию (игнорирует X и Y параметры).
  • SWP_NOOWNERZORDER - Не изменяет позицию окна владельца в Z-последовательности.
  • SWP_NOREDRAW - Не перерисовывает изменения. Если этот флажок установлен, то не происходит никакой перерисовки любого вида. Это применяется к рабочей области, нерабочей области (включая строку заголовка и линейки прокрутки) и любую часть родительского окна, раскрытого в результате перемещения окна. Когда этот флажок установлен, прикладная программа должна явно лишить законной силы или перерисовывать любые части окна и родительского окна, которые требуют перерисовки.
  • SWP_NOREPOSITION - То же самое, что и флажок SWP_NOOWNERZORDER.
  • SWP_NOSENDCHANGING - Предохраняет окно от приема сообщения WM_WINDOWPOSCHANGING.
  • SWP_NOSIZE - Сохраняет текущий размер (игнорирует cx и cy параметры).
  • SWP_NOZORDER - Сохраняет текущую Z-последовательность (игнорирует параметр hWndInsertAfter).
  • SWP_SHOWWINDOW - Отображает окно.

Возвращаемые значения
Если функция завершилась успешно, возвращается значение отличное от нуля. Если функция потерпела неудачу, возвращаемое значение - ноль. Чтобы получить расширенную информацию об ошибке, вызовите GetLastError.

Замечания
Если установлены флажки SWP_SHOWWINDOW или SWP_HIDEWINDOW, окно не может быть перемещено или изменен его размер. Все координаты для дочерних окон - рабочие координаты (относительно левого верхнего угла рабочей области родительского окна). Окно может быть сделано самым верхним окном или, путем установки параметра hWndInsertAfter в HWND_TOPMOST с гарантией того, что флажок SWP_NOZORDER не установлен, или, путем установки позиции окна в Z-последовательности так, чтобы оно было выше любого существующего самого верхнего окна. Когда не самое верхнее окно делается самым верхним, находящиеся в его собственности окна также делаются самыми верхними. Его владельцы, однако, не изменяются. Если ни флажок SWP_NOACTIVATE, ни флажок SWP_NOZORDER не установлен (то есть, когда прикладная программа потребовала, чтобы окно было одновременно, и активизировано, и чтобы его позиция изменилась в Z-последовательности), значение, заданное в hWndInsertAfter, используются только в следующих обстоятельствах:

  • Ни флажок HWND_TOPMOST ни флажок HWND_NOTOPMOST не установлен в hWndInser-tAfter.
  • Окно, идентифицированное hWnd - не активное окно.

Прикладная программа не может активизировать неактивное окно без такого же обеспечения ему в верхней части Z-последовательности. Прикладные программы могут изменять позицию активизированного окна в Z-последовательности без ограничений, или они могут активизировать окно, а затем переместить его в верхнюю часть самых верхних или не самых верхних окон. Если самое верхнее окно переустановлено в нижней части (HWND_BOTTOM) Z-последовательности или после любого не самого верхнего окна, оно больше не самое верхнее. Когда самое верхнее окно сделано не самым верхним, его владельцы и находящиеся в его собственности окна также делаются не самыми верхними окнами. Не самое верхнее окно может владеть самым верхним окном, а наоборот не может происходить. Любое окно (например, диалоговое окно) принадлежащее самому верхнему окну самостоятельно делается самым верхним окном, гарантируя, что все окна находящиеся во владении находятся выше их владельца. Если прикладная программа не в активном режиме, а должна быть в активном режиме, она должна вызвать функцию SetForegroundWindow.

Смотри также
MoveWindow, SetActiveWindow, SetForegroundWindow

Размещение и совместимость SetWindowPos

  • Windows NT            Да
  • Win95                Да
  • Win32s                Да
  • Импортируемая библиотека        user32.lib
  • Заголовочный файл            winuser.h
  • Unicode                Нет
  • Замечания по платформе        Не имеется

Категория Окна, WinAPI, Windows | 0 CommentsВерсия для печати Версия для печати

12 января 2008

Как обрабатывать сообщения в Delphi

Обработка сообщений означает, что приложение будет тем или иным образом реагировать на полученные от операционной системы сообщения. В стандартном приложении Windows обработка сообщений сосредотачивается в процедурах окна. Delphi, частично обрабатывая сообщения, упрощает работу программиста, позволяя вместо одной процедуры для обработки всех типов сообщений создавать независимые процедуры для обработки сообщений различных типов.

Все процедуры обработки сообщений должны отвечать следующим требованиям:

  • Процедура должна быть методом объекта
  • Процедуре должен передаваться один передаваемый по ссылке параметр, т.е. с помощью описания var. Тип параметра должен быть TMessage или другой, зависящий от типа специализированного сообщения
  • Описание процедуры должно включать ключевое слово message, за которым должна следовать константа, задающая тип обрабатываемого сообщения

Вот пример объявления процедуры, обрабатывающей сообщение WM_Paint

procedure WMPaint(var Msg: TWMPaint); message wm_Paint;

соглашение по присвоению имён требует присваивать обработчику сообщения то же имя, что и имя обрабатываемого сообщения, но без символа подчёркивания и указанием первым знаков имени прописными буквами]

В качестве примера напишем процедуру обработки сообщения WM_Paint, которая вместо перерисовки будет выдавать звуковой сигнал:

Для этого сначала нужно объявить процедуру в частных объявлениях (в области Private объекта TForm1):

procedure WMPaint(var Msg: TWMPaint); message wm_Paint

Теперь в разделе implementation модуля добавляем определение процедуры (в этом случае указание ключевого слова message не требуется):

procedure TForm1.WMPaint(var Msg: TWMPaint);
begin
beep;
inherited;
end;

Обратите внимание на ключевое слово inherited, которое позволяет передать сообщение обработчику этого сообщения, принадлежащему классу-предку, т.е. если бы мы в нашем случае не указали бы это слово, перерисовка окна не осуществлялась бы, а выполнялось бы только только то, что было описано в области реализации нашего приложения, т.е. только бы подавался звуковой сигнал.

Категория Окна, Окна, WinAPI, Windows, Delphi | 0 CommentsВерсия для печати Версия для печати

Друзья

  • Рубрики

  • Разное
  • Прочее