Сайту требуются администраторы и авторы статей. С предложениями пишите на 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Версия для печати Версия для печати

4 декабря 2007

PHP: Перекодирование UTF-8 в Windows-1251

Обычно для перекодирования строк из одной кодировки в другую используют функцию iconv.

$out=iconv("UTF-8", "WINDOWS-1251", $in);

Однако бывает так, что на некоторых хостингах (обычно бесплатных) данная функция отсутствует.

В таком случае можно использовать функцию работающую на массивах:

function utf_to_win($str)
{
$str=strtr($str,array("Р°"=>"а","Р±"=>"б","РІ"=>"в","Рі"=>"г","Рґ"=>"д","Рµ"=>"е","С‘"=>"ё",
"Р¶"=>"ж","Р·"=>"з",
"Рё"=>"и","Р№"=>"й","Рє"=>"к","Р»"=>"л","Рј"=>"м","РЅ"=>"н","Рѕ"=>"о","Рї"=>"п",
"СЂ"=>"р","СЃ"=>"с","С‚"=>"т","Сѓ"=>"у","С„"=>"ф","С…"=>"х","С†"=>"ц",
"С‡"=>"ч","С€"=>"ш","С‰"=>"щ","СЉ"=>"ъ","С‹"=>"ы","СЊ"=>"ь",
"СЌ"=>"э","СЋ"=>"ю","СЏ"=>"я",
"Рђ"=>"А","Р‘"=>"Б","Р’"=>"В","Р“"=>"Г","Р”"=>"Д",
"Р•"=>"Е","РЃ"=>"Ё","Р–"=>"Ж","Р—"=>"З","Р˜"=>"И","Р™"=>"Й","Рљ"=>"К","Р›"=>"Л",
"Рњ"=>"М","Рќ"=>"Н","Рћ"=>"О","Рџ"=>"П","Р "=>"Р",
"РЎ"=>"С","Рў"=>"Т","РЈ"=>"У","Р¤"=>"Ф","РҐ"=>"Х",
"Р¦"=>"Ц","Р§"=>"Ч","РЁ"=>"Ш","Р©"=>"Щ","РЄ"=>"Ъ","Р«"=>"Ы",
"Р¬"=>"Ь","Р­"=>"Э","Р®"=>"Ю","РЇ"=>"Я"));
return $str;
}

Категория Кодировки, PHP | 6 CommentsВерсия для печати Версия для печати

5 ноября 2007

Начало работы с CakePHP по-русски

Скоро товарищей, пишущих по старинке веб-страницы на голом php, можно будет показывать в зоопарках :-)
Наступает эра Фреймворков. И это хорошо, потому что программист избавлен от множества рутинных задач,
и может сосредоточиться на создании логики приложения.
В CakePHP используется подход MCV (Model - View - Controller). Теперь вместо одного файла *.php на одну
страничку их будет целых три минимум %) - один для модели (описывает связь формы с базой данных, имеет
расширение php), thtml файл будет описывать внешний вид страницы (view), третий (контроллер страницы с
расширением php будет реализовывать логику формы и будет содержать методы, дополняющие функциональность
родительского класса AppController.
Что ж, начнем печь приложения как пирожки )) Но для этого придется преступить через себя и принять новый подход к программированию. Оно того стоит ^_^

Далее »

Категория CakePHP, Фреймворки, PHP | 1 CommentВерсия для печати Версия для печати

26 сентября 2007

Хранение настроек программы без INI-файлов и реестра

При хранении настроек программы в INI-файле или реестре довольно трудоемким является считывание этих данных и инициализация внутренних структур/классов, хранящих настройки. Не лучше ли хранить сами эти классы, а еще лучше - форму, которая содержит интерфейс управления настройками программы.

Далее »

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

18 сентября 2007

Delphi: Работа с ресурсами

Windows поддерживает такие виды ресурсов:

  • RT_ACCELERATOR Accelerator table
  • RT_ANICURSOR Animated cursor
  • RT_ANIICON Animated icon
  • RT_BITMAP Bitmap resource
  • RT_CURSOR Hardware-dependent cursor resource
  • RT_DIALOG Dialog box
  • RT_FONT Font resource
  • RT_FONTDIR Font directory resource
  • RT_GROUP_CURSOR Hardware-independent cursor resource
  • RT_GROUP_ICON Hardware-independent icon resource
  • RT_ICON Hardware-dependent icon resource
  • RT_MENU Menu resource
  • RT_MESSAGETABLE Message-table entry
  • RT_RCDATA Application-defined resource (raw data)
  • RT_STRING String-table entry
  • RT_VERSION Version resource

Самый простой из них это RT_STRING - то есть строковый. Для работы с ним предусмотрено специальное зарезервированное слово - resourcestring.

Далее »

Категория Работа с ресурсами, Delphi | 0 CommentsВерсия для печати Версия для печати

13 сентября 2007

Delphi: перетаскивание элементов ListBox

Если вы хотите принимать перетаскиваемый объект, только если он представляет собой собственный элемент, то в обработчике OnDragOver вставьте строчку "Accept := Source=Sender;". Ниже приведен код, позволяющий сортировать элементы с помощью перетаскивания их мышкой внутри списка компонента. Вам также понадобится таймер для обеспечения функции автопрокручивания. Это означает, что при перетаскивании элемента в верхнюю часть списка, он при необходимости прокручивается вниз, дабы стали видны невидимые в верхней части списка элементы. Если вам не нужно такое поведение компонента, исключите из кода все строчки, имеющие отношение к таймеру, включая вторую строчку в обработчике события OnDragOver.

//...
private
{ Private declarations }
GoingUp: Boolean;

procedure TForm1.ListBox1DragOver(Sender, Source: TObject;
X, Y: Integer; State: TDragState; var Accept: Boolean);
begin
Accept := (Sender = Source) and
(TListBox(Sender).ItemAtPos(Point(X, Y), False) >= 0);
{устанавливаем таймер для автопрокрутки}
if Accept then
with Sender as TListBox do
if Y > Height - ItemHeight then
begin
GoingUp := False;
Timer1.Enabled := True;
end
else if Y > ItemHeight then
begin
GoingUp := True;
Timer1.Enabled := True;
end
else
Timer1.Enabled := False;
end;

procedure TForm1.ListBox1DragDrop(Sender, Source: TObject;
X, Y: Integer);
var
NuPos: Integer;
begin
with Sender as TListBox do
begin
NuPos := ItemAtPos(Point(X, Y), False);
if NuPos >= Items.Count then
Dec(NuPos);
Label1.Caption := Format('Перемещено из %d в %d',
[ItemIndex, NuPos]);
Items.Move(ItemIndex, NuPos);
{выделяем перемещенный элемент}
ItemIndex := NuPos;
end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
with ListBox1 do
if GoingUp then
if TopIndex > 0 then
TopIndex := TopIndex - 1
else
Timer1.Enabled := False
else if TopIndex < Items.Count - 1 then
TopIndex := TopIndex + 1
else
Timer1.Enabled := False;
end;

procedure TForm1.ListBox1EndDrag(Sender, Target: TObject;
X, Y: Integer);
begin
Timer1.Enabled := False;
end;

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

Друзья

  • Рубрики

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