Раздел "Кодинг". Содержание:
Статьи:
10 вещей, которые должен знать дельфер
Как поместить иконку в трей средствами Delphi?
Рисуем график функции в Delphi
Как отомстить врагу. Delphi. Добавляем приложение в Автозагрузку
Собираем консольный калькулятор на Delphi
Раздел "Кодинг". Статьи:
 | 10 вещей, которые должен знать дельфер |
|
1
Используйте в приложениях Runtime Packages - пакеты времени выполнения. Выберите Project>Options, перейдите в появившемся окне на страницу Options и установите флажок Build with Runtime Packages. Размер исполняемого файла вашего проекта сократится в 5-10 раз, поскольку с ним не будут соединяться динамические библиотеки Delphi. Однако программа будет исполнятся только в том случае, если обнаружит на компьютере коллекции Borland - *.bpl (то есть, говоря проще, если на винте есть Delphi :)).
2
Одним из недостатков среды Delphi является медленная загрузка, особенно на старых компьютерах. Чтобы исправить это, уменьшите количество пакетов разработки (Design time Packages). Вкладки Indy, COM, ActiveX, WebSnap и т.д. почти наверняка не понадобятся вам, если только вы не профессиональный разработчик. Откройте страницу Packages в опциях проекта и удалите ненужные пакеты, а чтобы не ошибиться, просматривайте компоненты, содержащиеся в них, с помощью кнопки Components. Delphi будет загружаться и работать значительно быстрее.
3
Забыли, на какой вкладке компонент? Найдите его с помощью View>Components List, а потом выберите Component>Configure Palette и отредактируйте вкладки по своему вкусу. В списке будет содержаться много пустых страниц, без всяких компонентов. Удалите их.
4
Поставьте курсор в какую-нибудь строку исходного кода и нажмите F5. Строка подсветится красным. Затем нажмите F9 и запустите проект. Когда код, содержащийся в помеченной строке, будет исполнятся, Delphi укажет на это. Очень полезно, если у вас есть подозрение, что некоторые строки кода не исполняются при работе приложения.
5
Пользуйтесь "короткими" переменными: ShortString вместо String, Smallint вместо Integer. Иногда (особенно в консольном приложении) это может уменьшить размер EXE на несколько килобайт.
6
Следите за секцией Uses. Там постоянно "оседают" модули, которыми, может, вы уже не пользуетесь. К примеру, если вы осчастливили свою форму компонентом TBitBtn, поставили на него какой-то код, а потом отказались и удалили, то модуль Buttons.pas останется в Uses, засоряя исполняемый файл. Избавляйтесь от модулей вместе с компонентами и не бойтесь удалить что-нибудь нужное: при компиляции Delphi автоматически добавляет в Uses модули присутствующих объектов. Изредка (если вы работаете с нестандартными компонентами) такого рода чистка может дать эффект в сотни(!) килобайт.
7
Пользуйтесь компрессорами исполняемых файлов. AsPack, UPX и другие в 3-4 раза уменьшают размер EXE, и запакованное ими приложение нельзя просмотреть шпионом ресурсов.
8
Достаньте себе шпион ресурсов. (Как найти софт в Сети - не мне вам рассказывать ;)). Restorator, ResHacker и т.д. позволяют вскрывать и редактировать EXE-файлы, если только они не запакованы (см. выше). Дело в том, что Delphi по собственному почину добавляет к приложению курсоры, рисунки (галочки/палочки/крестики), которые содержатся в BitButton'ах, даже если BitButton'ов в вашем проекте нет. С помощью шпиона ресурсов можно удалить этот мусор. Далее, шпионы почти всегда могут показать форму вашего приложения, как она записана в файле *.DFM (т.е. не в графическом, а в текстовом виде) и строковые ресурсы (различные сообщения, обычно на английском), которые можно (и нужно) редактировать.
9
Русифицируйте свои консольные приложения. Если в команде Writeln вы укажите какой-нибудь текст на русском, консоль выдаст всякую тарабарщину. Значит, нужно перекодировать текст Win в Dos. Существует уйма перекодировщиков, лучший из которых - Блокнот. Введите нужный вам текст и поставьте шрифт Terminal. Результат отобразиться в
OEM/DOS.
10
10 программ, которые вы должны собрать за свою сознательную жизнь, не используя нестандартных компонентов:
- Текстовый редактор. С этого начинают все. Отработка приемов работы с текстом и первичные навыки сохранения документов.
- Калькулятор. Навыки дельфийских математических операций.
- Графический редактор. Работа с канвой и уяснение разницы между компонентом Image и
PaintBox.
- Информация о системе. ОС, ОЗУ, винчестер, процессор, имя пользователя
etc.
- Будильник. Работа с датой и временем.
- Программа, Сворачивающаяся В Трей.
- Чистильщик реестра. Удаление "мертвых" ключей из секции Uninstall и т.п. Навыки работы с реестром.
- Чистильщик диска. Удаляет *.tmp, *.gid и прочий мусор. Поиск файлов и работа с ними.
- Медиаплейер.
- Клавиатурный шпион.
З.Ы.
Если вы знали все эти советы еще до их прочтения и в состоянии собрать перечисленные программы не глядя в хелп и не вставая со стула, значит, в Delphi вы кое-чего добились :).
 | Как поместить иконку в трей средствами Delphi? |
|
Здесь я привожу ответ на интересующий
многих вопрос: а как же поместить иконку в
трей? Надо сказать, что это довольно распространенный
пример, и авторство его мне точно не
известно, но помочь он Вам должен.
Обязательно включите в список
подключаемых модулей, модуль ShellApi, иначе
ничего работать не будет.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ShellApi; //!!
const
WM_NOTIFYTRAYICON = WM_USER + 1;
type
TForm1 = class(TForm)
procedure FormDestroy(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
procedure WMTRAYICONNOTIFY(var Msg: TMessage);
message WM_NOTIFYTRAYICON;
public
{ Public declarations }
end;
var
Form1: TForm1;
tray: TNotifyIconData;
TrayIcon: TIcon;
implementation
{$R *.dfm}
procedure TForm1.WMTRAYICONNOTIFY(var Msg: TMessage);
begin
{обрабатываем события на иконке в трее}
case Msg.LParam of
WM_LBUTTONDOWN: Form1.Visible:=true;
WM_LBUTTONDBLCLK: {ваш код обработки события
двойного нажатия на левую кнопку мыши}
WM_LBUTTONUP: {ваш код обработки события
отпускания левой кнопки мыши}
WM_RBUTTONDOWN: {ваш код}
WM_RBUTTONDBLCLK: {ваш код}
WM_RBUTTONUP: {ваш код}
WM_MOUSEMOVE: {ваш код}
end;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
try
with tray do begin
cbSize := SizeOf(TNotifyIconData);
Wnd := Form1.Handle;
uID := 1;
end;
Shell_NotifyIcon(NIM_DELETE, Addr(tray));
finally
Application.Terminate;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
TrayIcon := Application.Icon;
with tray do begin
cbSize := SizeOf(TNotifyIconData);
Wnd := Form1.Handle;
uID := 1;
uFlags := NIF_ICON or NIF_MESSAGE or NIF_TIP;
uCallBackMessage := WM_NOTIFYTRAYICON;
hIcon := TrayIcon.Handle;
szTip := ('Это мое приложение в трее');
end;
Shell_NotifyIcon(NIM_ADD, Addr(tray));
end;
procedure TForm1.GoToTrayButtonClick(Sender: TObject);
begin
//сворачиваемся в Трей
Form1.Visible:=false;
end;
end.
 | Рисуем график функции в Delphi |
|
В этой статье мы рассмотрим
несколько способов нарисовать график какой-нибудь
функции. Рисовать график мы будем на канве
компонента Image.
Рисование по пикселам
Рисовать на канве можно разными
способами. Первый вариант - рисовать по
пикселям. Для этого используется свойство
канвы Pixels. Это свойство представляет
собой двумерный массив, который отвечает за
цвета канвы. Например Canvas.Pixels[10,20] -
соответствует цвету пикселя с координатами
(10,20). С массивом пикселей можно обращаться,
как с любым свойством: изменять цвет,
задавая пикселю новое значение, или
определять его цвет, по хранящемуся в нем
значению. На примере ниже мы зададим черный
цвет пикселю с координатами (10,20):
Canvas.Pixels[10,20]:=clBlack;
Теперь мы попробуем нарисовать
график функции F(x), если известен диапазон
ее изменений Ymax и Ymin, и диапазон
изменения аргумента Xmax и Xmin. Для
этого мы напишем пользовательскую функцию,
которая будет вычислять значение функции F
в точке x, а также будет возвращать максимум
и минимум функции и ее аргумента.
function Tform1.F(x:real; var Xmax,Xmin,Ymax,Ymin:real):real;
Begin
F:=Sin(x);
Xmax:=4*pi;
Xmin:=0;
Ymax:=1;
Ymin:=-1;
End;
Не забудьте также указать
заголовок этой функциии в разделе Public:
public
{ Public declarations }
function F(x:real; var Xmax,Xmin,Ymax,Ymin:real):real;
Здесь для ясности мы просто
указали диапазон изменения функции Sin(x) и ее
аргумента, ниже эта функция будет описана
целиком. Параметры Xmax, Xmin, Ymax, Ymin - описаны со
словом Var потому что они являются
входными-выходными, т.е. через них функция
будет возвращать значения вычислений этих
данных в основную программу. Поэтому надо
объявить Xmax, Xmin, Ymax, Ymin как глобальные
переменные в разделе Implementation:
implementation
var Xmax,Xmin,Ymax,Ymin:real;
Теперь поставим на форму кнопку и в
ее обработчике события OnClick напишем
следующий код:
procedure TForm1.Button1Click(Sender: TObject);
var x,y:real;
PX,PY:longInt;
begin
for PX:=0 to Image1.Width do
begin
x:=Xmin+PX*(Xmax-Xmin)/Image1.Width;
y:=F(x,Xmax,Xmin,Ymax,Ymin);
PY:=trunc(Image1.Height-(y-Ymin)*Image1.height/(Ymax-Ymin));
image1.Canvas.Pixels[PX,PY]:=clBlack;
end;
end;
В этом коде вводятся переменные x
и y, являющиеся значениями аргумента
и функции, а также переменные PX и PY, являющиеся
координатами пикселей, соответствующих x
и y. Сама процедура состоит из цикла по
всем значениям горизонтальной координаты
пикселей PX компонента Image1. Сначала
выбранное значение PX пересчитывается в соответствующее
значение x. Затем производится вызов
функции F(x) и определяется ее значение Y. Это
значение пересчитывается в вертикальную
координату пикселя PY
Рисование с помощью пера Pen
У канвы имеется свойство Pen - перо.
Это объект в свою очередь имеющий ряд
свойств. Одно из них свойство Color - цвет,
которым наносится рисунок. Второе свойство Width
- ширина линии, задается в пикселах (по
умолчанию 1).
Свойство Style определяет вид
линии и может принимать следующие значения:
psSolid |
Сплошная линия |
psDash |
Штриховая линия |
psDot |
Пунктирная линия |
psDashDot |
Штрих пунктирная линия |
psDashDotDot |
Линия, чередующая штрих и два
пунктира |
psClear |
Отсутствие линии |
psInsideFrame |
Сплошная линия, но при Width > 1
допускающая цвета, отличные от палитры
Windows |
Все стили со штрихами и пунктирами
доступны только при толщине линий равной 1.
Иначе эти линии рисуются как сплошные.
У канвы имеется свойство PenPos, типа TPoint.
Это свойство определяет в координатах
канвы текущую позицию пера. Перемещение
пера без прорисовки осуществляется методом
MoveTo(x,y). После вызова этого метода канвы
точка с координатами (x,y) становится
исходной, от которой методом LineTo(x,y)
можно провести линию, в любую точку с
координатами (x,y).
Давайте теперь попробуем нарисовать
график синуса пером. Для этого добавим
перед циклом оператор:
Image1.Canvas.MoveTo(0,Image1.height div 2);
А перед заключительным end цикла добавьте
следующий оператор:
Image1.Canvas.LineTo(PX,PY);
Таким образом у Вас должен получиться
такой код:
procedure TForm1.Button1Click(Sender: TObject);
var x,y:real;
PX,PY:longInt;
begin
Image1.Canvas.MoveTo(0,Image1.height div 2);
for PX:=0 to Image1.Width do
begin
x:=Xmin+PX*(Xmax-Xmin)/Image1.Width;
y:=F(x,Xmax,Xmin,Ymax,Ymin);
PY:=trunc(Image1.Height-(y-Ymin)*Image1.height/(Ymax-Ymin));
image1.Canvas.Pixels[PX,PY]:=clBlack;
Image1.Canvas.LineTo(PX,PY);
end;
end;
Как Вы уже успели заметить, если запустили
программу, качество рисования графика
пером, намного лучше, чем рисования по
пикселям.
Как обещал сейчас напишу пример программы
которая находит максимум и минимум функции.
Я маленько изменил структуру процедур и
функций, чтобы было яснее. Вот готовый код
программы:
...
type
TForm1 = class(TForm)
Button1: TButton;
Image1: TImage;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
function F(x:real):real;
Procedure Extrem1(Xmax,Xmin:real; Var Ymin:real);
Procedure Extrem2(Xmax,Xmin:real; Var Ymax:real);
{ Public declarations }
end;
var
Form1: TForm1;
implementation
Const e=1e-4;//точность одна тысячная
var Xmax,Xmin,Ymax,Ymin:real;
{$R *.DFM}
function Tform1.F(x:real):real;
Begin
F:=Sin(x);
End;
//поиск минимума функции
Procedure TForm1.Extrem1(Xmax,Xmin:real; Var Ymin:real);
Var x,h:real; j,n:integer;
Begin
n:=10;
Repeat
x:=Xmin;
n:=n*2;
h:=(Xmax-Xmin)/n;
Ymin:=F(Xmin);
For j:=1 to n do begin
if f(x)<Ymin then Ymin:=f(x);
x:=x+h;
end;
Until abs(f(Ymin)-f(Ymin+h))<e;
End;
//поиск максимума функции
Procedure TForm1.Extrem2(Xmax,Xmin:real; Var Ymax:real);
Var x,h:real; j,n:integer;
Begin
n:=10;
Repeat
x:=Xmin;
n:=n*2;
h:=(Xmax-Xmin)/n;
Ymax:=F(Xmin);
For j:=1 to n do begin
if f(x)>=Ymax then Ymax:=f(x);
x:=x+h;
end;
Until abs(f(Ymax)-f(Ymax+h))<e;
End;
procedure TForm1.Button1Click(Sender: TObject);
var x,y:real;
PX,PY:longInt;
begin
//здесь необходимо указать диапазон изменения x
Xmax:=8*pi;
Xmin:=0;
//вычисляем экстремумы функции
Extrem1(Xmax,Xmin,Ymin);
Extrem2(Xmax,Xmin,Ymax);
//рисуем график функции
Image1.Canvas.MoveTo(0,Image1.height div 2);
for PX:=0 to Image1.Width do
begin
x:=Xmin+PX*(Xmax-Xmin)/Image1.Width;
y:=F(x);
PY:=trunc(Image1.Height-(y-Ymin)*Image1.height/(Ymax-Ymin));
image1.Canvas.Pixels[PX,PY]:=clBlack;
Image1.Canvas.LineTo(PX,PY);
end;
end;
end.
Ну вот и все, надеюсь эта статья оказалась Вам интересна!
 | Как отомстить врагу. Delphi. Добавляем приложение в Автозагрузку |
|
Я уже давно обещал рассказать нашим читателям, как добавить приложение в StartUp. Так что читайте и впитывайте. Сейчас мы разберем несколько вариантов алгоритма. Можно просто скопировать исполняемый файл в папку "Автозагрузка", узнав ее местонахождение с помощью функций модуля ShlObj.pas.
program StartUp;
{$APPTYPE CONSOLE}
uses
ShlObj, //!!
SysUtils,
Windows;
var
Folder: Pchar; //путь к StartUp
List: PitemidList; //список "специальных" папок
begin
//ищем папку
SHGetSpecialFolderLocation(0,CSIDL_STARTUP,List);
new(folder);
SHGetPathFromIDList(List,folder);
//Нашли? Переходим в директорию StartUp
ChDir(folder);
//копируем файл
CopyFile(PChar(ExtractFilePath(paramStr(0)) + 'StartUp.exe'), 'StartUp.exe', true); //укажите имя своего EXE файла
end.
Теперь загляните в папку "Автозагрузка". Если вы указали в функции имя СВОЕГО файла, он должен быть уже там :).
Обратите внимание на три выделенных строки. С их помощью можно найти путь к любой системной папке, указав в функции SHGetSpecialFolderLocation соответствующую константу: CSIDL_DESKTOP для рабочего стола, CSIDL_FONTS для шрифтов и т.д.
А теперь более простой способ - запись ключа в секцию Run реестра. Ниже в одной процедуре совмещено и его создание, и удаление.
Uses Registry;
//............
procedure ChangeReg(StrName: ShortString; delete: boolean);
var
reg: TRegistry;
begin
Reg := nil;
try
reg := TRegistry.Create;
reg.RootKey := HKEY_LOCAL_MACHINE;
reg.LazyWrite := false;
reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\Run',false);
if not delete then reg.WriteString(StrName, Application.ExeName)
else reg.DeleteValue(StrName);
reg.CloseKey;
reg.free;
except
if Assigned(Reg) then Reg.Free;
end;
end;
procedure TForm1.AddBtnClick(Sender: TObject);
begin
ChangeReg('My App',false); //добавляем в Автозагрузку
end;
procedure TForm1.RemoveBtnClick(Sender: TObject);
begin
ChangeReg('My App',true); //удаляем из Автозагрузки
end;
Вот и всё. Если что не удалось - пишите, мы вам поможем.
 | Собираем консольный калькулятор на Delphi |
|
Сейчас мы создадим программу, которая будет вычислять значения синуса, косинуса, тангенса и котангенса и, естественно, выводить результаты. Но не это главное. Наше приложение будет весить 42 КБ!
Итак, пользователь введет какую-нибудь строку вида F(x), где F - sin, cos, tg или ctg; x - определяемый угол в градусах, и после этого только остается узнать, какой именно функцией он это нагрузил нас! К счастью, Delphi предоставляет большие возможности для работы с текстом - смотрите ниже и убедитесь.
program CoolCalc; //Выберите File>New>Other>Console Application,
//чтобы создать консольное приложение
{$APPTYPE CONSOLE}
uses
SysUtils,
Math; //!!
const
Symbols: Array[0..5] of PChar = ('sin', 'cos', 'ctg', 'tg', '(', ')');
var
Func,
//строка, введенная юзером
Num: ShortString;
//вид тригонометрической функции
function GetValue(SubStr: PChar; s: ShortString): String;
var
i: smallint;
begin
repeat
//Есть ли в строке искомые функции?
i:=pos(SubStr,s);
//Если есть - удаляем...
delete(s,i,StrLen(SubStr));
//...и запоминаем
if (i>0) and (SubStr<Symbols[4]) then Num:=SubStr;
until i<=0;
Result:=s;
end;
procedure GetResult;
var
n: smallint;
begin
//Ищем в строке функции
for n:=0 to 5 do Func:=GetValue(Symbols[n],Func);
//Решаем
if Num = 'cos' then Writeln('Result: ' + FloatToStr(cos(DegToRad(StrToFloat(Func)))) + #10);
if Num = 'sin' then Writeln('Result: ' + FloatToStr(sin(DegToRad(StrToFloat(Func)))) + #10);
if Num = 'tg' then Writeln('Result: ' + FloatToStr(tan(DegToRad(StrToFloat(Func)))) + #10);
if Num = 'ctg' then Writeln('Result: ' + FloatToStr(cotan(DegToRad(StrToFloat(Func)))) + #10);
end;
begin
while true do begin //Запускам вечный цикл
Writeln('Enter function' + #10);
Readln(Func);
GetResult;
end;
end.
По совести говоря, нужно еще, чтобы прога решала уравнения 42-й степени, находила производную и вела лог, но я надеюсь, что вам не составит труда реализовать это, тем самым способствуя тригонометрии и софтостроению :).
|